3 * $Id: pkcs1.c,v 1.4 2004/04/08 01:36:15 mdw Exp $
7 * (c) 2000 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
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.
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.
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,
30 /*----- Header files ------------------------------------------------------*/
34 #include <mLib/bits.h>
35 #include <mLib/dstr.h>
40 /*----- Main code ---------------------------------------------------------*/
42 /* --- @pkcs1_cryptencode@ --- *
44 * Arguments: @mp *d@ = where to put the answer
45 * @const void *m@ = pointer to message data
46 * @size_t msz@ = size of message data
47 * @octet *b@ = spare buffer
48 * @size_t sz@ = size of the buffer (big enough)
49 * @unsigned long nbits@ = length of bits of @n@
50 * @void *p@ = pointer to PKCS1 parameter block
52 * Returns: The encoded result, or null.
54 * Use: Implements the operation @EME-PKCS1-V1_5-ENCODE@, as defined
55 * in PKCS#1 v. 2.0 (RFC2437).
58 mp
*pkcs1_cryptencode(mp
*d
, const void *m
, size_t msz
, octet
*b
, size_t sz
,
59 unsigned long nbits
, void *p
)
66 /* --- Ensure that the buffer is sensibly sized --- */
68 if (pp
->epsz
+ msz
+ 11 > sz
)
71 /* --- Allocate the buffer and fill it in --- */
76 n
= sz
- msz
- pp
->epsz
- 3;
78 for (i
= 0; i
< n
; i
++) {
80 *q
= r
->ops
->range(r
, 255) + 1;
85 memcpy(q
, pp
->ep
, pp
->epsz
);
92 /* --- Collect the result --- */
94 return (mp_loadb(d
, b
, sz
));
97 /* --- @pkcs1_cryptdecode@ --- *
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@
103 * @void *p@ = pointer to PKCS1 parameter block
105 * Returns: The length of the output string if successful, negative on
108 * Use: Implements the operation @EME-PKCS1-V1_5-DECODE@, as defined
109 * in PKCS#1 v. 2.0 (RFC2437).
112 static int memeq(const void *xx
, const void *yy
, size_t sz
)
115 const octet
*x
= xx
, *y
= yy
;
116 while (sz
) { /* Always check every byte */
117 if (*x
++ != *y
++) eq
= 0;
123 int pkcs1_cryptdecode(mp
*m
, octet
*b
, size_t sz
,
124 unsigned long nbits
, void *p
)
131 /* --- Check the size of the block looks sane --- */
133 if (pp
->epsz
+ 11 > sz
) /* OK: independent of ciphertext */
139 /* --- Ensure that the block looks OK --- */
141 bad
|= (*q
++ != 0x00 || *q
++ != 0x02);
143 /* --- Check the nonzero padding --- */
146 while (*q
!= 0 && q
< qq
)
148 bad
|= (i
< 8 || qq
- q
< pp
->epsz
+ 1);
151 /* --- Check the encoding parameters --- */
153 bad
|= (pp
->ep
&& !memeq(bad ? b
: q
, pp
->ep
, pp
->epsz
));
159 memmove(b
, bad ? b
+ 1 : q
, n
);
160 return (bad ?
-1 : n
);
163 /* --- @pkcs1_sigencode@ --- *
165 * Arguments: @mp *d@ = where to put the answer
166 * @const void *m@ = pointer to message data
167 * @size_t msz@ = size of message data
168 * @octet *b@ = spare buffer
169 * @size_t sz@ = size of the buffer (big enough)
170 * @unsigned long nbits@ = length of bits of @n@
171 * @void *p@ = pointer to PKCS1 parameter block
173 * Returns: The encoded message representative, or null.
175 * Use: Implements the operation @EMSA-PKCS1-V1_5-ENCODE@, as defined
176 * in PKCS#1 v. 2.0 (RFC2437).
179 mp
*pkcs1_sigencode(mp
*d
, const void *m
, size_t msz
, octet
*b
, size_t sz
,
180 unsigned long nbits
, void *p
)
186 /* --- Ensure that the buffer is sensibly sized --- */
188 if (pp
->epsz
+ msz
+ 11 > sz
)
191 /* --- Fill in the buffer --- */
196 n
= sz
- msz
- pp
->epsz
- 3;
201 memcpy(q
, pp
->ep
, pp
->epsz
);
207 return (mp_loadb(d
, b
, sz
));
210 /* --- @pkcs1_sigdecode@ --- *
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
220 * Returns: The length of the output string if successful, negative on
223 * Use: Implements the operation @EMSA-PKCS1-V1_5-DECODE@, as defined
224 * in PKCS#1 v. 2.0 (RFC2437).
227 int pkcs1_sigdecode(mp
*s
, const void *m
, size_t msz
, octet
*b
, size_t sz
,
228 unsigned long nbits
, void *p
)
234 /* --- Check the size of the block looks sane --- */
236 if (pp
->epsz
+ 10 > sz
)
242 /* --- Ensure that the block looks OK --- */
244 if (*q
++ != 0x00 || *q
++ != 0x01)
247 /* --- Check the padding --- */
250 while (*q
== 0xff && q
< qq
)
252 if (i
< 8 || qq
- q
< pp
->epsz
+ 1 || *q
++ != 0)
255 /* --- Check the encoding parameters --- */
257 if (pp
->ep
&& memcmp(q
, pp
->ep
, pp
->epsz
) != 0)
268 /*----- That's all, folks -------------------------------------------------*/