Path: blob/master/libs/tomcrypt/src/pk/ecc/ecc_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*/89/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b10*11* All curves taken from NIST recommendation paper of July 199912* Available at http://csrc.nist.gov/cryptval/dss.htm13*/14#include "tomcrypt.h"1516/**17@file ecc_decrypt_key.c18ECC Crypto, Tom St Denis19*/2021#ifdef LTC_MECC2223/**24Decrypt an ECC encrypted key25@param in The ciphertext26@param inlen The length of the ciphertext (octets)27@param out [out] The plaintext28@param outlen [in/out] The max size and resulting size of the plaintext29@param key The corresponding private ECC key30@return CRYPT_OK if successful31*/32int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,33unsigned char *out, unsigned long *outlen,34ecc_key *key)35{36unsigned char *ecc_shared, *skey, *pub_expt;37unsigned long x, y;38unsigned long hashOID[32] = { 0 };39int hash, err;40ecc_key pubkey;41ltc_asn1_list decode[3];4243LTC_ARGCHK(in != NULL);44LTC_ARGCHK(out != NULL);45LTC_ARGCHK(outlen != NULL);46LTC_ARGCHK(key != NULL);4748/* right key type? */49if (key->type != PK_PRIVATE) {50return CRYPT_PK_NOT_PRIVATE;51}5253/* decode to find out hash */54LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));55err = der_decode_sequence(in, inlen, decode, 1);56if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {57return err;58}5960hash = find_hash_oid(hashOID, decode[0].size);61if (hash_is_valid(hash) != CRYPT_OK) {62return CRYPT_INVALID_PACKET;63}6465/* we now have the hash! */6667/* allocate memory */68pub_expt = XMALLOC(ECC_BUF_SIZE);69ecc_shared = XMALLOC(ECC_BUF_SIZE);70skey = XMALLOC(MAXBLOCKSIZE);71if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {72if (pub_expt != NULL) {73XFREE(pub_expt);74}75if (ecc_shared != NULL) {76XFREE(ecc_shared);77}78if (skey != NULL) {79XFREE(skey);80}81return CRYPT_MEM;82}83LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);84LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);8586/* read the structure in now */87if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {88goto LBL_ERR;89}9091/* import ECC key from packet */92if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {93goto LBL_ERR;94}9596/* make shared key */97x = ECC_BUF_SIZE;98if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {99ecc_free(&pubkey);100goto LBL_ERR;101}102ecc_free(&pubkey);103104y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE);105if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {106goto LBL_ERR;107}108109/* ensure the hash of the shared secret is at least as big as the encrypt itself */110if (decode[2].size > y) {111err = CRYPT_INVALID_PACKET;112goto LBL_ERR;113}114115/* avoid buffer overflow */116if (*outlen < decode[2].size) {117*outlen = decode[2].size;118err = CRYPT_BUFFER_OVERFLOW;119goto LBL_ERR;120}121122/* Decrypt the key */123for (x = 0; x < decode[2].size; x++) {124out[x] = skey[x] ^ ecc_shared[x];125}126*outlen = x;127128err = CRYPT_OK;129LBL_ERR:130#ifdef LTC_CLEAN_STACK131zeromem(pub_expt, ECC_BUF_SIZE);132zeromem(ecc_shared, ECC_BUF_SIZE);133zeromem(skey, MAXBLOCKSIZE);134#endif135136XFREE(pub_expt);137XFREE(ecc_shared);138XFREE(skey);139140return err;141}142143#endif144145146