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 */