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_encrypt_key.c 15 DSA Crypto, Tom St Denis 16 */ 17 18 #ifdef MDSA 19 20 /** 21 Encrypt a symmetric key with DSA 22 @param in The symmetric key you want to encrypt 23 @param inlen The length of the key to encrypt (octets) 24 @param out [out] The destination for the ciphertext 25 @param outlen [in/out] The max size and resulting size of the ciphertext 26 @param prng An active PRNG state 27 @param wprng The index of the PRNG you wish to use 28 @param hash The index of the hash you want to use 29 @param key The DSA key you want to encrypt to 30 @return CRYPT_OK if successful 31 */ 32 int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, 33 unsigned char *out, unsigned long *outlen, 34 prng_state *prng, int wprng, int hash, 35 dsa_key *key) 36 { 37 unsigned char *expt, *skey; 38 void *g_pub, *g_priv; 39 unsigned long x, y; 40 int err; 41 42 LTC_ARGCHK(in != NULL); 43 LTC_ARGCHK(out != NULL); 44 LTC_ARGCHK(outlen != NULL); 45 LTC_ARGCHK(key != NULL); 46 47 /* check that wprng/cipher/hash are not invalid */ 48 if ((err = prng_is_valid(wprng)) != CRYPT_OK) { 49 return err; 50 } 51 52 if ((err = hash_is_valid(hash)) != CRYPT_OK) { 53 return err; 54 } 55 56 if (inlen > hash_descriptor[hash].hashsize) { 57 return CRYPT_INVALID_HASH; 58 } 59 60 /* make a random key and export the public copy */ 61 if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { 62 return err; 63 } 64 65 expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); 66 skey = XMALLOC(MAXBLOCKSIZE); 67 if (expt == NULL || skey == NULL) { 68 if (expt != NULL) { 69 XFREE(expt); 70 } 71 if (skey != NULL) { 72 XFREE(skey); 73 } 74 mp_clear_multi(g_pub, g_priv, NULL); 75 return CRYPT_MEM; 76 } 77 78 /* make a random x, g^x pair */ 79 x = mp_unsigned_bin_size(key->q); 80 if (prng_descriptor[wprng].read(expt, x, prng) != x) { 81 err = CRYPT_ERROR_READPRNG; 82 goto LBL_ERR; 83 } 84 85 /* load x */ 86 if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) { 87 goto LBL_ERR; 88 } 89 90 /* compute y */ 91 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { 92 goto LBL_ERR; 93 } 94 95 /* make random key */ 96 x = mp_unsigned_bin_size(key->p) + 1; 97 if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { 98 goto LBL_ERR; 99 } 100 101 y = MAXBLOCKSIZE; 102 if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { 103 goto LBL_ERR; 104 } 105 106 /* Encrypt key */ 107 for (x = 0; x < inlen; x++) { 108 skey[x] ^= in[x]; 109 } 110 111 err = der_encode_sequence_multi(out, outlen, 112 LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, 113 LTC_ASN1_INTEGER, 1UL, g_pub, 114 LTC_ASN1_OCTET_STRING, inlen, skey, 115 LTC_ASN1_EOL, 0UL, NULL); 116 117 LBL_ERR: 118 #ifdef LTC_CLEAN_STACK 119 /* clean up */ 120 zeromem(expt, mp_unsigned_bin_size(key->p) + 1); 121 zeromem(skey, MAXBLOCKSIZE); 122 #endif 123 124 XFREE(skey); 125 XFREE(expt); 126 127 mp_clear_multi(g_pub, g_priv, NULL); 128 return err; 129 } 130 131 #endif 132 /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c,v $ */ 133 /* $Revision: 1.7 $ */ 134 /* $Date: 2006/12/04 03:18:43 $ */ 135 136