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