Mercurial > dropbear
comparison pkcs_1_oaep_decode.c @ 0:d7da3b1e1540 libtomcrypt
put back the 0.95 makefile which was inadvertently merged over
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:21:40 +0000 |
parents | |
children | 6362d3854bb4 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d7da3b1e1540 |
---|---|
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, [email protected], http://libtomcrypt.org | |
10 */ | |
11 #include "mycrypt.h" | |
12 | |
13 /* OAEP Padding for PKCS #1 -- Tom St Denis */ | |
14 | |
15 #ifdef PKCS_1 | |
16 | |
17 int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, | |
18 const unsigned char *lparam, unsigned long lparamlen, | |
19 unsigned long modulus_bitlen, int hash_idx, | |
20 unsigned char *out, unsigned long *outlen) | |
21 { | |
22 unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)]; | |
23 unsigned long hLen, x, y, modulus_len; | |
24 int err; | |
25 | |
26 _ARGCHK(msg != NULL); | |
27 _ARGCHK(out != NULL); | |
28 _ARGCHK(outlen != NULL); | |
29 | |
30 /* test valid hash */ | |
31 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
32 return err; | |
33 } | |
34 hLen = hash_descriptor[hash_idx].hashsize; | |
35 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); | |
36 | |
37 /* test message size */ | |
38 if (modulus_len >= sizeof(DB) || msglen != modulus_len) { | |
39 return CRYPT_PK_INVALID_SIZE; | |
40 } | |
41 | |
42 /* ok so it's now in the form | |
43 | |
44 0x00 || maskedseed || maskedDB | |
45 | |
46 1 || hLen || modulus_len - hLen - 1 | |
47 | |
48 */ | |
49 | |
50 /* must have leading 0x00 byte */ | |
51 if (msg[0] != 0x00) { | |
52 return CRYPT_INVALID_PACKET; | |
53 } | |
54 | |
55 /* now read the masked seed */ | |
56 for (x = 1, y = 0; y < hLen; y++) { | |
57 seed[y] = msg[x++]; | |
58 } | |
59 | |
60 /* now read the masked DB */ | |
61 for (y = 0; y < modulus_len - hLen - 1; y++) { | |
62 DB[y] = msg[x++]; | |
63 } | |
64 | |
65 /* compute MGF1 of maskedDB (hLen) */ | |
66 if ((err = pkcs_1_mgf1(DB, modulus_len - hLen - 1, hash_idx, mask, hLen)) != CRYPT_OK) { | |
67 return err; | |
68 } | |
69 | |
70 /* XOR against seed */ | |
71 for (y = 0; y < hLen; y++) { | |
72 seed[y] ^= mask[y]; | |
73 } | |
74 | |
75 /* compute MGF1 of seed (k - hlen - 1) */ | |
76 if ((err = pkcs_1_mgf1(seed, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { | |
77 return err; | |
78 } | |
79 | |
80 /* xor against DB */ | |
81 for (y = 0; y < (modulus_len - hLen - 1); y++) { | |
82 DB[y] ^= mask[y]; | |
83 } | |
84 | |
85 /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ | |
86 | |
87 /* compute lhash and store it in seed [reuse temps!] */ | |
88 x = sizeof(seed); | |
89 if (lparam != NULL) { | |
90 if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { | |
91 return err; | |
92 } | |
93 } else { | |
94 /* can't pass hash_memory a NULL so use DB with zero length */ | |
95 if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { | |
96 return err; | |
97 } | |
98 } | |
99 | |
100 /* compare the lhash'es */ | |
101 if (memcmp(seed, DB, hLen) != 0) { | |
102 return CRYPT_INVALID_PACKET; | |
103 } | |
104 | |
105 /* now zeroes before a 0x01 */ | |
106 for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { | |
107 /* step... */ | |
108 } | |
109 | |
110 /* error out if wasn't 0x01 */ | |
111 if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { | |
112 return CRYPT_INVALID_PACKET; | |
113 } | |
114 | |
115 /* rest is the message (and skip 0x01) */ | |
116 if (msglen - ++x > *outlen) { | |
117 return CRYPT_BUFFER_OVERFLOW; | |
118 } | |
119 | |
120 /* copy message */ | |
121 *outlen = (modulus_len - hLen - 1) - x; | |
122 for (y = 0; x != (modulus_len - hLen - 1); ) { | |
123 out[y++] = DB[x++]; | |
124 } | |
125 | |
126 #ifdef CLEAN_STACK | |
127 zeromem(DB, sizeof(DB)); | |
128 zeromem(seed, sizeof(seed)); | |
129 zeromem(mask, sizeof(mask)); | |
130 #endif | |
131 | |
132 return CRYPT_OK; | |
133 } | |
134 | |
135 #endif /* PKCS_1 */ |