Mercurial > dropbear
comparison pkcs_1_pss_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 /* PKCS #1 PSS Signature Padding -- Tom St Denis */ | |
14 | |
15 #ifdef PKCS_1 | |
16 | |
17 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, | |
18 const unsigned char *sig, unsigned long siglen, | |
19 unsigned long saltlen, int hash_idx, | |
20 unsigned long modulus_bitlen, int *res) | |
21 { | |
22 unsigned char DB[1024], mask[sizeof(DB)], salt[sizeof(DB)], hash[sizeof(DB)]; | |
23 unsigned long x, y, hLen, modulus_len; | |
24 int err; | |
25 hash_state md; | |
26 | |
27 _ARGCHK(msghash != NULL); | |
28 _ARGCHK(res != NULL); | |
29 | |
30 /* default to invalid */ | |
31 *res = 0; | |
32 | |
33 /* ensure hash is valid */ | |
34 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
35 return err; | |
36 } | |
37 | |
38 hLen = hash_descriptor[hash_idx].hashsize; | |
39 modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); | |
40 | |
41 /* check sizes */ | |
42 if ((saltlen > sizeof(salt)) || (modulus_len > sizeof(DB)) || | |
43 (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { | |
44 return CRYPT_INVALID_ARG; | |
45 } | |
46 | |
47 /* ensure the 0xBC byte */ | |
48 if (sig[siglen-1] != 0xBC) { | |
49 return CRYPT_OK; | |
50 } | |
51 | |
52 /* copy out the DB */ | |
53 for (x = 0; x < modulus_len - hLen - 1; x++) { | |
54 DB[x] = sig[x]; | |
55 } | |
56 | |
57 /* copy out the hash */ | |
58 for (y = 0; y < hLen; y++) { | |
59 hash[y] = sig[x++]; | |
60 } | |
61 | |
62 /* check the MSB */ | |
63 if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) { | |
64 return CRYPT_OK; | |
65 } | |
66 | |
67 /* generate mask of length modulus_len - hLen - 1 from hash */ | |
68 if ((err = pkcs_1_mgf1(hash, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { | |
69 return err; | |
70 } | |
71 | |
72 /* xor against DB */ | |
73 for (y = 0; y < (modulus_len - hLen - 1); y++) { | |
74 DB[y] ^= mask[y]; | |
75 } | |
76 | |
77 /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ | |
78 | |
79 /* check for zeroes and 0x01 */ | |
80 for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { | |
81 if (DB[x] != 0x00) { | |
82 return CRYPT_OK; | |
83 } | |
84 } | |
85 | |
86 if (DB[x++] != 0x01) { | |
87 return CRYPT_OK; | |
88 } | |
89 | |
90 /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ | |
91 hash_descriptor[hash_idx].init(&md); | |
92 zeromem(mask, 8); | |
93 if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { | |
94 return err; | |
95 } | |
96 if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { | |
97 return err; | |
98 } | |
99 if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { | |
100 return err; | |
101 } | |
102 if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { | |
103 return err; | |
104 } | |
105 | |
106 /* mask == hash means valid signature */ | |
107 if (memcmp(mask, hash, hLen) == 0) { | |
108 *res = 1; | |
109 } | |
110 | |
111 #ifdef CLEAN_STACK | |
112 zeromem(DB, sizeof(DB)); | |
113 zeromem(mask, sizeof(mask)); | |
114 zeromem(salt, sizeof(salt)); | |
115 zeromem(hash, sizeof(hash)); | |
116 #endif | |
117 | |
118 return CRYPT_OK; | |
119 } | |
120 | |
121 #endif /* PKCS_1 */ |