Pollard's rho algorithm for computing discrete logs.
[u/mdw/catacomb] / pkcs1.c
1 /* -*-c-*-
2 *
3 * $Id: pkcs1.c,v 1.2 2000/07/05 17:49:48 mdw Exp $
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
30 /*----- Revision history --------------------------------------------------*
31 *
32 * $Log: pkcs1.c,v $
33 * Revision 1.2 2000/07/05 17:49:48 mdw
34 * Fix decoding functions, so that they don't run off the end of the
35 * buffer.
36 *
37 * Revision 1.1 2000/07/01 11:17:38 mdw
38 * New support for PKCS#1 message encoding.
39 *
40 */
41
42 /*----- Header files ------------------------------------------------------*/
43
44 #include <string.h>
45
46 #include <mLib/bits.h>
47 #include <mLib/dstr.h>
48
49 #include "grand.h"
50 #include "pkcs1.h"
51
52 /*----- Main code ---------------------------------------------------------*/
53
54 /* --- @pkcs1_cryptencode@ --- *
55 *
56 * Arguments: @const void *msg@ = pointer to message data
57 * @size_t msz@ = size of message data
58 * @void *buf@ = pointer to output buffer
59 * @size_t sz@ = size of the output buffer
60 * @void *p@ = pointer to PKCS1 parameter block
61 *
62 * Returns: Zero if all went well, negative on failure.
63 *
64 * Use: Implements the operation @EME-PKCS1-V1_5-ENCODE@, as defined
65 * in PKCS#1 v. 2.0 (RFC2437).
66 */
67
68 int pkcs1_cryptencode(const void *msg, size_t msz, void *buf, size_t sz,
69 void *p)
70 {
71 pkcs1 *pp = p;
72 grand *r = pp->r;
73 octet *q, *qq;
74 size_t i, n;
75
76 /* --- Ensure that the buffer is sensibly sized --- */
77
78 if (pp->epsz + msz + 11 > sz)
79 return (-1);
80
81 /* --- Fill in the buffer --- */
82
83 q = buf;
84 qq = q + sz;
85 *q++ = 0;
86 *q++ = 2;
87 n = sz - msz - pp->epsz - 3;
88 r->ops->fill(r, q, n);
89 for (i = 0; i < n; i++) {
90 if (*q == 0)
91 *q = r->ops->range(r, 255) + 1;
92 q++;
93 }
94 *q++ = 0;
95 memcpy(q, pp->ep, pp->epsz);
96 q += pp->epsz;
97 memcpy(q, msg, msz);
98 return (0);
99 }
100
101 /* --- @pkcs1_cryptdecode@ --- *
102 *
103 * Arguments: @const void *buf@ = pointer to encoded buffer
104 * @size_t sz@ = size of the encoded buffer
105 * @dstr *d@ = pointer to destination string
106 * @void *p@ = pointer to PKCS1 parameter block
107 *
108 * Returns: The length of the output string if successful, negative on
109 * failure.
110 *
111 * Use: Implements the operation @EME-PKCS1-V1_5-DECODE@, as defined
112 * in PKCS#1 v. 2.0 (RFC2437).
113 */
114
115 int pkcs1_cryptdecode(const void *buf, size_t sz, dstr *d, void *p)
116 {
117 pkcs1 *pp = p;
118 const octet *q, *qq;
119 size_t n, i;
120
121 /* --- Check the size of the block looks sane --- */
122
123 if (pp->epsz + 11 > sz)
124 return (-1);
125 q = buf;
126 qq = buf + sz;
127
128 /* --- Ensure that the block looks OK --- */
129
130 if (*q++ != 0 || *q++ != 2)
131 return (-1);
132
133 /* --- Check the nonzero padding --- */
134
135 i = 0;
136 while (*q != 0 && q < qq)
137 i++, q++;
138 if (i < 8 || qq - q < pp->epsz + 1)
139 return (-1);
140 q++;
141
142 /* --- Check the encoding parameters --- */
143
144 if (memcmp(q, pp->ep, pp->epsz) != 0)
145 return (-1);
146 q += pp->epsz;
147
148 /* --- Done --- */
149
150 n = qq - q;
151 dstr_putm(d, q, n);
152 return (n);
153 }
154
155 /* --- @pkcs1_sigencode@ --- *
156 *
157 * Arguments: @const void *msg@ = pointer to message data
158 * @size_t msz@ = size of message data
159 * @void *buf@ = pointer to output buffer
160 * @size_t sz@ = size of the output buffer
161 * @void *p@ = pointer to PKCS1 parameter block
162 *
163 * Returns: Zero if all went well, negative on failure.
164 *
165 * Use: Implements the operation @EMSA-PKCS1-V1_5-ENCODE@, as defined
166 * in PKCS#1 v. 2.0 (RFC2437).
167 */
168
169 int pkcs1_sigencode(const void *msg, size_t msz, void *buf, size_t sz,
170 void *p)
171 {
172 pkcs1 *pp = p;
173 octet *q, *qq;
174 size_t n;
175
176 /* --- Ensure that the buffer is sensibly sized --- */
177
178 if (pp->epsz + msz + 11 > sz)
179 return (-1);
180
181 /* --- Fill in the buffer --- */
182
183 q = buf;
184 qq = q + sz;
185 *q++ = 0;
186 *q++ = 1;
187 n = sz - msz - pp->epsz - 3;
188 memset(q, 0xff, n);
189 q += n;
190 *q++ = 0;
191 memcpy(q, pp->ep, pp->epsz);
192 q += pp->epsz;
193 memcpy(q, msg, msz);
194 return (0);
195 }
196
197 /* --- @pkcs1_sigdecode@ --- *
198 *
199 * Arguments: @const void *buf@ = pointer to encoded buffer
200 * @size_t sz@ = size of the encoded buffer
201 * @dstr *d@ = pointer to destination string
202 * @void *p@ = pointer to PKCS1 parameter block
203 *
204 * Returns: The length of the output string if successful, negative on
205 * failure.
206 *
207 * Use: Implements the operation @EMSA-PKCS1-V1_5-DECODE@, as defined
208 * in PKCS#1 v. 2.0 (RFC2437).
209 */
210
211 int pkcs1_sigdecode(const void *buf, size_t sz, dstr *d, void *p)
212 {
213 pkcs1 *pp = p;
214 const octet *q, *qq;
215 size_t i, n;
216
217 /* --- Check the size of the block looks sane --- */
218
219 if (pp->epsz + 10 > sz)
220 return (-1);
221 q = buf;
222 qq = buf + sz;
223
224 /* --- Ensure that the block looks OK --- */
225
226 if (*q++ != 0 || *q++ != 1)
227 return (-1);
228
229 /* --- Check the padding --- */
230
231 i = 0;
232 while (*q == 0xff && q < qq)
233 i++, q++;
234 if (i < 8 || qq - q < pp->epsz + 1 || *q++ != 0)
235 return (-1);
236
237 /* --- Check the encoding parameters --- */
238
239 if (memcmp(q, pp->ep, pp->epsz) != 0)
240 return (-1);
241 q += pp->epsz;
242
243 /* --- Done --- */
244
245 n = qq - q;
246 dstr_putm(d, q, n);
247 return (n);
248 }
249
250 /*----- That's all, folks -------------------------------------------------*/