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