Home | History | Annotate | Download | only in dsa
      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