Path: blob/master/libs/tomcrypt/src/pk/dsa/dsa_decrypt_key.c
4396 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file dsa_decrypt_key.c12DSA Crypto, Tom St Denis13*/1415#ifdef LTC_MDSA1617/**18Decrypt an DSA encrypted key19@param in The ciphertext20@param inlen The length of the ciphertext (octets)21@param out [out] The plaintext22@param outlen [in/out] The max size and resulting size of the plaintext23@param key The corresponding private DSA key24@return CRYPT_OK if successful25*/26int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,27unsigned char *out, unsigned long *outlen,28dsa_key *key)29{30unsigned char *skey, *expt;31void *g_pub;32unsigned long x, y;33unsigned long hashOID[32] = { 0 };34int hash, err;35ltc_asn1_list decode[3];3637LTC_ARGCHK(in != NULL);38LTC_ARGCHK(out != NULL);39LTC_ARGCHK(outlen != NULL);40LTC_ARGCHK(key != NULL);4142/* right key type? */43if (key->type != PK_PRIVATE) {44return CRYPT_PK_NOT_PRIVATE;45}4647/* decode to find out hash */48LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));49err = der_decode_sequence(in, inlen, decode, 1);50if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {51return err;52}5354hash = find_hash_oid(hashOID, decode[0].size);55if (hash_is_valid(hash) != CRYPT_OK) {56return CRYPT_INVALID_PACKET;57}5859/* we now have the hash! */6061if ((err = mp_init(&g_pub)) != CRYPT_OK) {62return err;63}6465/* allocate memory */66expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);67skey = XMALLOC(MAXBLOCKSIZE);68if (expt == NULL || skey == NULL) {69if (expt != NULL) {70XFREE(expt);71}72if (skey != NULL) {73XFREE(skey);74}75mp_clear(g_pub);76return CRYPT_MEM;77}7879LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL);80LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);8182/* read the structure in now */83if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {84goto LBL_ERR;85}8687/* make shared key */88x = mp_unsigned_bin_size(key->p) + 1;89if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {90goto LBL_ERR;91}9293y = mp_unsigned_bin_size(key->p) + 1;94y = MIN(y, MAXBLOCKSIZE);95if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {96goto LBL_ERR;97}9899/* ensure the hash of the shared secret is at least as big as the encrypt itself */100if (decode[2].size > y) {101err = CRYPT_INVALID_PACKET;102goto LBL_ERR;103}104105/* avoid buffer overflow */106if (*outlen < decode[2].size) {107*outlen = decode[2].size;108err = CRYPT_BUFFER_OVERFLOW;109goto LBL_ERR;110}111112/* Decrypt the key */113for (x = 0; x < decode[2].size; x++) {114out[x] = expt[x] ^ skey[x];115}116*outlen = x;117118err = CRYPT_OK;119LBL_ERR:120#ifdef LTC_CLEAN_STACK121zeromem(expt, mp_unsigned_bin_size(key->p) + 1);122zeromem(skey, MAXBLOCKSIZE);123#endif124125XFREE(expt);126XFREE(skey);127128mp_clear(g_pub);129130return err;131}132133#endif134135136