1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis 2 * 3 * LibTomCrypt is a library that provides various cryptographic 4 * algorithms in a highly modular and flexible manner. 5 * 6 * The library is free for all purposes without any express 7 * guarantee it works. 8 * 9 * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com 10 */ 11 #include "tomcrypt.h" 12 13 /** 14 @file dsa_decrypt_key.c 15 DSA Crypto, Tom St Denis 16 */ 17 18 #ifdef MDSA 19 20 /** 21 Decrypt an DSA encrypted key 22 @param in The ciphertext 23 @param inlen The length of the ciphertext (octets) 24 @param out [out] The plaintext 25 @param outlen [in/out] The max size and resulting size of the plaintext 26 @param key The corresponding private DSA key 27 @return CRYPT_OK if successful 28 */ 29 int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, 30 unsigned char *out, unsigned long *outlen, 31 dsa_key *key) 32 { 33 unsigned char *skey, *expt; 34 void *g_pub; 35 unsigned long x, y, hashOID[32]; 36 int hash, err; 37 ltc_asn1_list decode[3]; 38 39 LTC_ARGCHK(in != NULL); 40 LTC_ARGCHK(out != NULL); 41 LTC_ARGCHK(outlen != NULL); 42 LTC_ARGCHK(key != NULL); 43 44 /* right key type? */ 45 if (key->type != PK_PRIVATE) { 46 return CRYPT_PK_NOT_PRIVATE; 47 } 48 49 /* decode to find out hash */ 50 LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); 51 52 if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { 53 return err; 54 } 55 56 hash = find_hash_oid(hashOID, decode[0].size); 57 if (hash_is_valid(hash) != CRYPT_OK) { 58 return CRYPT_INVALID_PACKET; 59 } 60 61 /* we now have the hash! */ 62 63 if ((err = mp_init(&g_pub)) != CRYPT_OK) { 64 return err; 65 } 66 67 /* allocate memory */ 68 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); 69 skey = XMALLOC(MAXBLOCKSIZE); 70 if (expt == NULL || skey == NULL) { 71 if (expt != NULL) { 72 XFREE(expt); 73 } 74 if (skey != NULL) { 75 XFREE(skey); 76 } 77 mp_clear(g_pub); 78 return CRYPT_MEM; 79 } 80 81 LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL); 82 LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); 83 84 /* read the structure in now */ 85 if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { 86 goto LBL_ERR; 87 } 88 89 /* make shared key */ 90 x = mp_unsigned_bin_size(key->p) + 1; 91 if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) { 92 goto LBL_ERR; 93 } 94 95 y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE); 96 if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) { 97 goto LBL_ERR; 98 } 99 100 /* ensure the hash of the shared secret is at least as big as the encrypt itself */ 101 if (decode[2].size > y) { 102 err = CRYPT_INVALID_PACKET; 103 goto LBL_ERR; 104 } 105 106 /* avoid buffer overflow */ 107 if (*outlen < decode[2].size) { 108 *outlen = decode[2].size; 109 err = CRYPT_BUFFER_OVERFLOW; 110 goto LBL_ERR; 111 } 112 113 /* Decrypt the key */ 114 for (x = 0; x < decode[2].size; x++) { 115 out[x] = expt[x] ^ skey[x]; 116 } 117 *outlen = x; 118 119 err = CRYPT_OK; 120 LBL_ERR: 121 #ifdef LTC_CLEAN_STACK 122 zeromem(expt, mp_unsigned_bin_size(key->p) + 1); 123 zeromem(skey, MAXBLOCKSIZE); 124 #endif 125 126 XFREE(expt); 127 XFREE(skey); 128 129 mp_clear(g_pub); 130 131 return err; 132 } 133 134 #endif 135 136 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c,v $ */ 137 /* $Revision: 1.9 $ */ 138 /* $Date: 2006/12/04 03:18:43 $ */ 139 140