Uprating of the passphrase pixie.
[u/mdw/catacomb] / pkcs1.c
CommitLineData
cd6c3eeb 1/* -*-c-*-
2 *
b817bfc6 3 * $Id: pkcs1.c,v 1.4 2004/04/08 01:36:15 mdw Exp $
cd6c3eeb 4 *
5 * PKCS#1 1.5 packing
6 *
7 * (c) 2000 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Catacomb.
13 *
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
cd6c3eeb 30/*----- Header files ------------------------------------------------------*/
31
32#include <string.h>
33
34#include <mLib/bits.h>
35#include <mLib/dstr.h>
36
37#include "grand.h"
b817bfc6 38#include "rsa.h"
cd6c3eeb 39
40/*----- Main code ---------------------------------------------------------*/
41
42/* --- @pkcs1_cryptencode@ --- *
43 *
b817bfc6 44 * Arguments: @mp *d@ = where to put the answer
45 * @const void *m@ = pointer to message data
cd6c3eeb 46 * @size_t msz@ = size of message data
b817bfc6 47 * @octet *b@ = spare buffer
48 * @size_t sz@ = size of the buffer (big enough)
49 * @unsigned long nbits@ = length of bits of @n@
cd6c3eeb 50 * @void *p@ = pointer to PKCS1 parameter block
51 *
b817bfc6 52 * Returns: The encoded result, or null.
cd6c3eeb 53 *
54 * Use: Implements the operation @EME-PKCS1-V1_5-ENCODE@, as defined
55 * in PKCS#1 v. 2.0 (RFC2437).
56 */
57
b817bfc6 58mp *pkcs1_cryptencode(mp *d, const void *m, size_t msz, octet *b, size_t sz,
59 unsigned long nbits, void *p)
cd6c3eeb 60{
61 pkcs1 *pp = p;
62 grand *r = pp->r;
b817bfc6 63 octet *q;
cd6c3eeb 64 size_t i, n;
65
66 /* --- Ensure that the buffer is sensibly sized --- */
67
68 if (pp->epsz + msz + 11 > sz)
b817bfc6 69 return (0);
cd6c3eeb 70
b817bfc6 71 /* --- Allocate the buffer and fill it in --- */
cd6c3eeb 72
b817bfc6 73 q = b;
74 *q++ = 0x00;
75 *q++ = 0x02;
cd6c3eeb 76 n = sz - msz - pp->epsz - 3;
b817bfc6 77 GR_FILL(r, q, n);
cd6c3eeb 78 for (i = 0; i < n; i++) {
79 if (*q == 0)
80 *q = r->ops->range(r, 255) + 1;
81 q++;
82 }
83 *q++ = 0;
b817bfc6 84 if (pp->ep) {
85 memcpy(q, pp->ep, pp->epsz);
86 q += pp->epsz;
87 }
88 memcpy(q, m, msz);
89 q += msz;
90 assert(q == b + sz);
91
92 /* --- Collect the result --- */
93
94 return (mp_loadb(d, b, sz));
cd6c3eeb 95}
96
97/* --- @pkcs1_cryptdecode@ --- *
98 *
b817bfc6 99 * Arguments: @mp *m@ = the decrypted message
100 * @octet *b@ = pointer to a buffer to work in
101 * @size_t sz@ = the size of the buffer (big enough)
102 * @unsigned long nbits@ = the number of bits in @n@
cd6c3eeb 103 * @void *p@ = pointer to PKCS1 parameter block
104 *
105 * Returns: The length of the output string if successful, negative on
106 * failure.
107 *
108 * Use: Implements the operation @EME-PKCS1-V1_5-DECODE@, as defined
109 * in PKCS#1 v. 2.0 (RFC2437).
110 */
111
b817bfc6 112static int memeq(const void *xx, const void *yy, size_t sz)
113{
114 int eq = 1;
115 const octet *x = xx, *y = yy;
116 while (sz) { /* Always check every byte */
117 if (*x++ != *y++) eq = 0;
118 sz--;
119 }
120 return (eq);
121}
122
123int pkcs1_cryptdecode(mp *m, octet *b, size_t sz,
124 unsigned long nbits, void *p)
cd6c3eeb 125{
126 pkcs1 *pp = p;
127 const octet *q, *qq;
128 size_t n, i;
b817bfc6 129 int bad = 0;
cd6c3eeb 130
131 /* --- Check the size of the block looks sane --- */
132
b817bfc6 133 if (pp->epsz + 11 > sz) /* OK: independent of ciphertext */
cd6c3eeb 134 return (-1);
b817bfc6 135 mp_storeb(m, b, sz);
136 q = b;
7629bca8 137 qq = q + sz;
cd6c3eeb 138
139 /* --- Ensure that the block looks OK --- */
140
b817bfc6 141 bad |= (*q++ != 0x00 || *q++ != 0x02);
cd6c3eeb 142
143 /* --- Check the nonzero padding --- */
144
145 i = 0;
146 while (*q != 0 && q < qq)
147 i++, q++;
b817bfc6 148 bad |= (i < 8 || qq - q < pp->epsz + 1);
cd6c3eeb 149 q++;
150
151 /* --- Check the encoding parameters --- */
152
b817bfc6 153 bad |= (pp->ep && !memeq(bad ? b : q, pp->ep, pp->epsz));
cd6c3eeb 154 q += pp->epsz;
155
156 /* --- Done --- */
157
158 n = qq - q;
b817bfc6 159 memmove(b, bad ? b + 1 : q, n);
160 return (bad ? -1 : n);
cd6c3eeb 161}
162
163/* --- @pkcs1_sigencode@ --- *
164 *
b817bfc6 165 * Arguments: @mp *d@ = where to put the answer
166 * @const void *m@ = pointer to message data
cd6c3eeb 167 * @size_t msz@ = size of message data
b817bfc6 168 * @octet *b@ = spare buffer
169 * @size_t sz@ = size of the buffer (big enough)
170 * @unsigned long nbits@ = length of bits of @n@
cd6c3eeb 171 * @void *p@ = pointer to PKCS1 parameter block
172 *
b817bfc6 173 * Returns: The encoded message representative, or null.
cd6c3eeb 174 *
175 * Use: Implements the operation @EMSA-PKCS1-V1_5-ENCODE@, as defined
176 * in PKCS#1 v. 2.0 (RFC2437).
177 */
178
b817bfc6 179mp *pkcs1_sigencode(mp *d, const void *m, size_t msz, octet *b, size_t sz,
180 unsigned long nbits, void *p)
cd6c3eeb 181{
182 pkcs1 *pp = p;
b817bfc6 183 octet *q;
cd6c3eeb 184 size_t n;
185
186 /* --- Ensure that the buffer is sensibly sized --- */
187
188 if (pp->epsz + msz + 11 > sz)
b817bfc6 189 return (0);
cd6c3eeb 190
191 /* --- Fill in the buffer --- */
192
b817bfc6 193 q = b;
194 *q++ = 0x00;
195 *q++ = 0x01;
cd6c3eeb 196 n = sz - msz - pp->epsz - 3;
197 memset(q, 0xff, n);
198 q += n;
199 *q++ = 0;
b817bfc6 200 if (pp->ep) {
201 memcpy(q, pp->ep, pp->epsz);
202 q += pp->epsz;
203 }
204 memcpy(q, m, msz);
205 q += msz;
206 assert(q == b + sz);
207 return (mp_loadb(d, b, sz));
cd6c3eeb 208}
209
210/* --- @pkcs1_sigdecode@ --- *
211 *
b817bfc6 212 * Arguments: @mp *s@ = the message representative
213 * @const void *m@ = the original message, or null (ignored)
214 * @size_t msz@ = the message size (ignored)
215 * @octet *b@ = a scratch buffer
216 * @size_t sz@ = size of the buffer (large enough)
217 * @unsigned long nbits@ = number of bits in @n@
218 * @void *p@ = pointer to PKCS1 parameters
cd6c3eeb 219 *
220 * Returns: The length of the output string if successful, negative on
221 * failure.
222 *
223 * Use: Implements the operation @EMSA-PKCS1-V1_5-DECODE@, as defined
224 * in PKCS#1 v. 2.0 (RFC2437).
225 */
226
b817bfc6 227int pkcs1_sigdecode(mp *s, const void *m, size_t msz, octet *b, size_t sz,
228 unsigned long nbits, void *p)
cd6c3eeb 229{
230 pkcs1 *pp = p;
231 const octet *q, *qq;
232 size_t i, n;
233
234 /* --- Check the size of the block looks sane --- */
235
236 if (pp->epsz + 10 > sz)
237 return (-1);
b817bfc6 238 mp_storeb(s, b, sz);
239 q = b;
7629bca8 240 qq = q + sz;
cd6c3eeb 241
242 /* --- Ensure that the block looks OK --- */
243
b817bfc6 244 if (*q++ != 0x00 || *q++ != 0x01)
cd6c3eeb 245 return (-1);
246
247 /* --- Check the padding --- */
248
249 i = 0;
250 while (*q == 0xff && q < qq)
251 i++, q++;
0586d2a1 252 if (i < 8 || qq - q < pp->epsz + 1 || *q++ != 0)
cd6c3eeb 253 return (-1);
cd6c3eeb 254
255 /* --- Check the encoding parameters --- */
256
b817bfc6 257 if (pp->ep && memcmp(q, pp->ep, pp->epsz) != 0)
cd6c3eeb 258 return (-1);
259 q += pp->epsz;
260
261 /* --- Done --- */
262
263 n = qq - q;
b817bfc6 264 memmove(b, q, n);
cd6c3eeb 265 return (n);
266}
267
268/*----- That's all, folks -------------------------------------------------*/