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