comparison pkcs_1_pss_decode.c @ 3:7faae8f46238 libtomcrypt-orig

Branch renaming
author Matt Johnston <matt@ucc.asn.au>
date Mon, 31 May 2004 18:25:41 +0000
parents
children 6362d3854bb4
comparison
equal deleted inserted replaced
-1:000000000000 3:7faae8f46238
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 */