]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/ecc/ecc_decrypt_key.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / ecc / ecc_decrypt_key.c
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
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11  *
12  * All curves taken from NIST recommendation paper of July 1999
13  * Available at http://csrc.nist.gov/cryptval/dss.htm
14  */
15 #include "tomcrypt.h"
16
17 /**
18   @file ecc_decrypt_key.c
19   ECC Crypto, Tom St Denis
20 */
21
22 #ifdef LTC_MECC
23
24 /**
25   Decrypt an ECC encrypted key
26   @param in       The ciphertext
27   @param inlen    The length of the ciphertext (octets)
28   @param out      [out] The plaintext
29   @param outlen   [in/out] The max size and resulting size of the plaintext
30   @param key      The corresponding private ECC key
31   @return CRYPT_OK if successful
32 */
33 int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
34                           unsigned char *out, unsigned long *outlen,
35                           ecc_key *key)
36 {
37    unsigned char *ecc_shared, *skey, *pub_expt;
38    unsigned long  x, y;
39    unsigned long  hashOID[32] = { 0 };
40    int            hash, err;
41    ecc_key        pubkey;
42    ltc_asn1_list  decode[3];
43
44    LTC_ARGCHK(in     != NULL);
45    LTC_ARGCHK(out    != NULL);
46    LTC_ARGCHK(outlen != NULL);
47    LTC_ARGCHK(key    != NULL);
48
49    /* right key type? */
50    if (key->type != PK_PRIVATE) {
51       return CRYPT_PK_NOT_PRIVATE;
52    }
53
54    /* decode to find out hash */
55    LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
56    err = der_decode_sequence(in, inlen, decode, 1);
57    if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
58       return err;
59    }
60
61    hash = find_hash_oid(hashOID, decode[0].size);
62    if (hash_is_valid(hash) != CRYPT_OK) {
63       return CRYPT_INVALID_PACKET;
64    }
65
66    /* we now have the hash! */
67
68    /* allocate memory */
69    pub_expt   = XMALLOC(ECC_BUF_SIZE);
70    ecc_shared = XMALLOC(ECC_BUF_SIZE);
71    skey       = XMALLOC(MAXBLOCKSIZE);
72    if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
73       if (pub_expt != NULL) {
74          XFREE(pub_expt);
75       }
76       if (ecc_shared != NULL) {
77          XFREE(ecc_shared);
78       }
79       if (skey != NULL) {
80          XFREE(skey);
81       }
82       return CRYPT_MEM;
83    }
84    LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING,      pub_expt,  ECC_BUF_SIZE);
85    LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE);
86
87    /* read the structure in now */
88    if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
89       goto LBL_ERR;
90    }
91
92    /* import ECC key from packet */
93    if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
94       goto LBL_ERR;
95    }
96
97    /* make shared key */
98    x = ECC_BUF_SIZE;
99    if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
100       ecc_free(&pubkey);
101       goto LBL_ERR;
102    }
103    ecc_free(&pubkey);
104
105    y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE);
106    if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
107       goto LBL_ERR;
108    }
109
110    /* ensure the hash of the shared secret is at least as big as the encrypt itself */
111    if (decode[2].size > y) {
112       err = CRYPT_INVALID_PACKET;
113       goto LBL_ERR;
114    }
115
116    /* avoid buffer overflow */
117    if (*outlen < decode[2].size) {
118       *outlen = decode[2].size;
119       err = CRYPT_BUFFER_OVERFLOW;
120       goto LBL_ERR;
121    }
122
123    /* Decrypt the key */
124    for (x = 0; x < decode[2].size; x++) {
125      out[x] = skey[x] ^ ecc_shared[x];
126    }
127    *outlen = x;
128
129    err = CRYPT_OK;
130 LBL_ERR:
131 #ifdef LTC_CLEAN_STACK
132    zeromem(pub_expt,   ECC_BUF_SIZE);
133    zeromem(ecc_shared, ECC_BUF_SIZE);
134    zeromem(skey,       MAXBLOCKSIZE);
135 #endif
136
137    XFREE(pub_expt);
138    XFREE(ecc_shared);
139    XFREE(skey);
140
141    return err;
142 }
143
144 #endif
145
146 /* ref:         $Format:%D$ */
147 /* git commit:  $Format:%H$ */
148 /* commit time: $Format:%ai$ */
149