1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Deimos - cryptographic acceleration based upon Broadcom 582x.
29 */
30
31 #include <sys/types.h>
32 #include <sys/ddi.h>
33 #include <sys/sunddi.h>
34 #include <sys/kmem.h>
35 #include <sys/note.h>
36 #include <sys/crypto/spi.h>
37 #include <sys/crypto/dca.h>
38
39
40 static void dca_rsaverifydone(dca_request_t *, int);
41 static void dca_rsadone(dca_request_t *, int);
42
43 /* Exported function prototypes */
44 int dca_rsastart(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
45 crypto_req_handle_t, int);
46 int dca_rsainit(crypto_ctx_t *, crypto_mechanism_t *, crypto_key_t *, int);
47 void dca_rsactxfree(void *);
48 int dca_rsaatomic(crypto_provider_handle_t, crypto_session_id_t,
49 crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
50 int, crypto_req_handle_t, int);
51
52 /* Local function prototypes */
53 static int dca_pkcs1_padding(dca_t *dca, caddr_t buf, int flen, int tlen,
54 int private);
55 static int dca_pkcs1_unpadding(char *buf, int *tlen, int flen, int mode);
56 static int dca_x509_padding(caddr_t buf, int flen, int tlen);
57 static int dca_x509_unpadding(char *buf, int tlen, int flen, int mode);
58 static int decrypt_error_code(int mode, int decrypt, int verify, int def);
59
60
dca_rsastart(crypto_ctx_t * ctx,crypto_data_t * in,crypto_data_t * out,crypto_req_handle_t req,int mode)61 int dca_rsastart(crypto_ctx_t *ctx, crypto_data_t *in, crypto_data_t *out,
62 crypto_req_handle_t req, int mode)
63 {
64 dca_request_t *reqp = ctx->cc_provider_private;
65 dca_t *dca = ctx->cc_provider;
66 caddr_t daddr;
67 int rv = CRYPTO_QUEUED;
68 int len;
69
70 /* We don't support non-contiguous buffers for RSA */
71 if (dca_sgcheck(dca, in, DCA_SG_CONTIG) ||
72 dca_sgcheck(dca, out, DCA_SG_CONTIG)) {
73 rv = CRYPTO_NOT_SUPPORTED;
74 goto errout;
75 }
76
77 len = dca_length(in);
78
79 /* Extracting the key attributes is now done in dca_rsainit(). */
80 if (mode == DCA_RSA_ENC || mode == DCA_RSA_SIGN ||
81 mode == DCA_RSA_SIGNR) {
82 /*
83 * Return length needed to store the output.
84 * For sign, sign-recover, and encrypt, the output buffer
85 * should not be smaller than modlen since PKCS or X_509
86 * padding will be applied
87 */
88 if (dca_length(out) < reqp->dr_ctx.modlen) {
89 DBG(dca, DWARN,
90 "dca_rsastart: output buffer too short (%d < %d)",
91 dca_length(out), reqp->dr_ctx.modlen);
92 out->cd_length = reqp->dr_ctx.modlen;
93 rv = CRYPTO_BUFFER_TOO_SMALL;
94 goto errout;
95 }
96 }
97 if (out != in && out->cd_length > reqp->dr_ctx.modlen)
98 out->cd_length = reqp->dr_ctx.modlen;
99
100 /* The input length should not be bigger than the modulus */
101 if (len > reqp->dr_ctx.modlen) {
102 rv = decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
103 CRYPTO_SIGNATURE_LEN_RANGE, CRYPTO_DATA_LEN_RANGE);
104 goto errout;
105 }
106
107 /*
108 * For decryption, verify, and verifyRecover, the input length should
109 * not be less than the modulus
110 */
111 if (len < reqp->dr_ctx.modlen && (mode == DCA_RSA_DEC ||
112 mode == DCA_RSA_VRFY || mode == DCA_RSA_VRFYR)) {
113 rv = decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
114 CRYPTO_SIGNATURE_LEN_RANGE, CRYPTO_DATA_LEN_RANGE);
115 goto errout;
116 }
117
118 /*
119 * For decryption and verifyRecover, the output buffer should not
120 * be less than the modulus
121 */
122 if (out->cd_length < reqp->dr_ctx.modlen && (mode == DCA_RSA_DEC ||
123 mode == DCA_RSA_VRFYR) &&
124 reqp->dr_ctx.ctx_cm_type == RSA_X_509_MECH_INFO_TYPE) {
125 out->cd_length = reqp->dr_ctx.modlen;
126 rv = CRYPTO_BUFFER_TOO_SMALL;
127 goto errout;
128 }
129
130 /* For decrypt and verify, the input should not be less than output */
131 if (out && len < out->cd_length) {
132 if ((rv = decrypt_error_code(mode,
133 CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
134 CRYPTO_SIGNATURE_LEN_RANGE, CRYPTO_SUCCESS)) !=
135 CRYPTO_SUCCESS)
136 goto errout;
137 }
138
139 if ((daddr = dca_bufdaddr(in)) == NULL && len > 0) {
140 rv = CRYPTO_ARGUMENTS_BAD;
141 goto errout;
142 }
143
144 if (dca_numcmp(daddr, len, (char *)reqp->dr_ctx.mod,
145 reqp->dr_ctx.modlen) > 0) {
146 DBG(dca, DWARN,
147 "dca_rsastart: input larger (numerically) than modulus!");
148 rv = decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_INVALID,
149 CRYPTO_SIGNATURE_INVALID, CRYPTO_DATA_INVALID);
150 goto errout;
151 }
152
153 reqp->dr_byte_stat = -1;
154 reqp->dr_in = in;
155 reqp->dr_out = out;
156 reqp->dr_kcf_req = req;
157 if (mode == DCA_RSA_VRFY)
158 reqp->dr_callback = dca_rsaverifydone;
159 else
160 reqp->dr_callback = dca_rsadone;
161
162 dca_reverse(daddr, reqp->dr_ibuf_kaddr, len, reqp->dr_pkt_length);
163 if (mode == DCA_RSA_ENC || mode == DCA_RSA_SIGN ||
164 mode == DCA_RSA_SIGNR) {
165 /*
166 * Needs to pad appropriately for encrypt, sign, and
167 * sign_recover
168 */
169 if (reqp->dr_ctx.ctx_cm_type == RSA_PKCS_MECH_INFO_TYPE) {
170 if ((rv = dca_pkcs1_padding(dca, reqp->dr_ibuf_kaddr,
171 len, reqp->dr_ctx.modlen, reqp->dr_ctx.pqfix)) !=
172 CRYPTO_QUEUED)
173 goto errout;
174 } else if (reqp->dr_ctx.ctx_cm_type ==
175 RSA_X_509_MECH_INFO_TYPE) {
176 if ((rv = dca_x509_padding(reqp->dr_ibuf_kaddr,
177 len, reqp->dr_pkt_length)) != CRYPTO_QUEUED)
178 goto errout;
179 }
180 }
181 reqp->dr_ctx.mode = mode;
182
183 /*
184 * Since the max RSA input size is 256 bytes (2048 bits), the firstx
185 * page (at least 4096 bytes) in the pre-mapped buffer is large enough.
186 * Therefore, we use this first page for RSA.
187 */
188 reqp->dr_in_paddr = reqp->dr_ibuf_head.dc_buffer_paddr;
189 reqp->dr_in_next = 0;
190 reqp->dr_in_len = reqp->dr_pkt_length;
191 reqp->dr_out_paddr = reqp->dr_obuf_head.dc_buffer_paddr;
192 reqp->dr_out_next = 0;
193 reqp->dr_out_len = reqp->dr_pkt_length;
194
195 /* schedule the work by doing a submit */
196 rv = dca_start(dca, reqp, MCR2, 1);
197
198
199 errout:
200 if (rv != CRYPTO_QUEUED && rv != CRYPTO_BUFFER_TOO_SMALL)
201 (void) dca_free_context(ctx);
202
203 return (rv);
204 }
205
206 void
dca_rsadone(dca_request_t * reqp,int errno)207 dca_rsadone(dca_request_t *reqp, int errno)
208 {
209 if (errno == CRYPTO_SUCCESS) {
210 int outsz = reqp->dr_out->cd_length;
211 caddr_t daddr;
212
213 (void) ddi_dma_sync(reqp->dr_obuf_dmah, 0, reqp->dr_out_len,
214 DDI_DMA_SYNC_FORKERNEL);
215 if (dca_check_dma_handle(reqp->dr_dca, reqp->dr_obuf_dmah,
216 DCA_FM_ECLASS_NONE) != DDI_SUCCESS) {
217 reqp->destroy = TRUE;
218 errno = CRYPTO_DEVICE_ERROR;
219 goto errout;
220 }
221
222 if (reqp->dr_ctx.mode == DCA_RSA_DEC ||
223 reqp->dr_ctx.mode == DCA_RSA_VRFY ||
224 reqp->dr_ctx.mode == DCA_RSA_VRFYR) {
225 /*
226 * Needs to unpad appropriately for decrypt, verify,
227 * and verify_recover
228 */
229 if (reqp->dr_ctx.ctx_cm_type ==
230 RSA_PKCS_MECH_INFO_TYPE) {
231 errno = dca_pkcs1_unpadding(
232 reqp->dr_obuf_kaddr, &outsz,
233 reqp->dr_ctx.modlen, reqp->dr_ctx.mode);
234
235 /* check for bad data errors */
236 if (errno != CRYPTO_SUCCESS &&
237 errno != CRYPTO_BUFFER_TOO_SMALL) {
238 goto errout;
239 }
240 if (dca_bufdaddr(reqp->dr_out) == NULL) {
241 errno = CRYPTO_BUFFER_TOO_SMALL;
242 }
243 if (errno == CRYPTO_BUFFER_TOO_SMALL) {
244 reqp->dr_out->cd_length = outsz;
245 goto errout;
246 }
247 /* Reset the output data length */
248 reqp->dr_out->cd_length = outsz;
249 } else if (reqp->dr_ctx.ctx_cm_type ==
250 RSA_X_509_MECH_INFO_TYPE) {
251 if ((errno = dca_x509_unpadding(
252 reqp->dr_obuf_kaddr, outsz,
253 reqp->dr_pkt_length, reqp->dr_ctx.mode)) !=
254 CRYPTO_SUCCESS)
255 goto errout;
256 }
257 }
258
259 if ((daddr = dca_bufdaddr(reqp->dr_out)) == NULL) {
260 DBG(reqp->dr_dca, DINTR,
261 "dca_rsadone: reqp->dr_out is bad");
262 errno = CRYPTO_ARGUMENTS_BAD;
263 goto errout;
264 }
265 /*
266 * Note that there may be some number of null bytes
267 * at the end of the source (result), but we don't care
268 * about them -- they are place holders only and are
269 * truncated here.
270 */
271 dca_reverse(reqp->dr_obuf_kaddr, daddr, outsz, outsz);
272 }
273 errout:
274 ASSERT(reqp->dr_kcf_req != NULL);
275
276 /* notify framework that request is completed */
277 crypto_op_notification(reqp->dr_kcf_req, errno);
278 DBG(reqp->dr_dca, DINTR,
279 "dca_rsadone: returning 0x%x to the kef via crypto_op_notification",
280 errno);
281
282 /*
283 * For non-atomic operations, reqp will be freed in the kCF
284 * callback function since it may be needed again if
285 * CRYPTO_BUFFER_TOO_SMALL is returned to kCF
286 */
287 if (reqp->dr_ctx.atomic) {
288 crypto_ctx_t ctx;
289 ctx.cc_provider_private = reqp;
290 dca_rsactxfree(&ctx);
291 }
292 }
293
294 void
dca_rsaverifydone(dca_request_t * reqp,int errno)295 dca_rsaverifydone(dca_request_t *reqp, int errno)
296 {
297 if (errno == CRYPTO_SUCCESS) {
298 char scratch[RSA_MAX_KEY_LEN];
299 int outsz = reqp->dr_out->cd_length;
300 caddr_t daddr;
301
302 /*
303 * ASSUMPTION: the signature length was already
304 * checked on the way in, and it is a valid length.
305 */
306 (void) ddi_dma_sync(reqp->dr_obuf_dmah, 0, outsz,
307 DDI_DMA_SYNC_FORKERNEL);
308 if (dca_check_dma_handle(reqp->dr_dca, reqp->dr_obuf_dmah,
309 DCA_FM_ECLASS_NONE) != DDI_SUCCESS) {
310 reqp->destroy = TRUE;
311 errno = CRYPTO_DEVICE_ERROR;
312 goto errout;
313 }
314
315 if (reqp->dr_ctx.mode == DCA_RSA_DEC ||
316 reqp->dr_ctx.mode == DCA_RSA_VRFY ||
317 reqp->dr_ctx.mode == DCA_RSA_VRFYR) {
318 /*
319 * Needs to unpad appropriately for decrypt, verify,
320 * and verify_recover
321 */
322 if (reqp->dr_ctx.ctx_cm_type ==
323 RSA_PKCS_MECH_INFO_TYPE) {
324 errno = dca_pkcs1_unpadding(
325 reqp->dr_obuf_kaddr, &outsz,
326 reqp->dr_ctx.modlen, reqp->dr_ctx.mode);
327
328 /* check for bad data errors */
329 if (errno != CRYPTO_SUCCESS &&
330 errno != CRYPTO_BUFFER_TOO_SMALL) {
331 goto errout;
332 }
333 if (dca_bufdaddr(reqp->dr_out) == NULL) {
334 errno = CRYPTO_BUFFER_TOO_SMALL;
335 }
336 if (errno == CRYPTO_BUFFER_TOO_SMALL) {
337 reqp->dr_out->cd_length = outsz;
338 goto errout;
339 }
340 /* Reset the output data length */
341 reqp->dr_out->cd_length = outsz;
342 } else if (reqp->dr_ctx.ctx_cm_type ==
343 RSA_X_509_MECH_INFO_TYPE) {
344 if ((errno = dca_x509_unpadding(
345 reqp->dr_obuf_kaddr, outsz,
346 reqp->dr_pkt_length, reqp->dr_ctx.mode)) !=
347 CRYPTO_SUCCESS)
348 goto errout;
349 }
350 }
351
352 dca_reverse(reqp->dr_obuf_kaddr, scratch, outsz, outsz);
353
354 if ((daddr = dca_bufdaddr(reqp->dr_out)) == NULL) {
355 errno = CRYPTO_ARGUMENTS_BAD;
356 goto errout;
357 }
358 if (dca_numcmp(daddr, reqp->dr_out->cd_length, scratch,
359 outsz) != 0) {
360 /* VERIFY FAILED */
361 errno = CRYPTO_SIGNATURE_INVALID;
362 }
363 }
364 errout:
365 ASSERT(reqp->dr_kcf_req != NULL);
366
367 /* notify framework that request is completed */
368 crypto_op_notification(reqp->dr_kcf_req, errno);
369 DBG(reqp->dr_dca, DINTR,
370 "dca_rsaverifydone: rtn 0x%x to the kef via crypto_op_notification",
371 errno);
372
373 /*
374 * For non-atomic operations, reqp will be freed in the kCF
375 * callback function since it may be needed again if
376 * CRYPTO_BUFFER_TOO_SMALL is returned to kCF
377 */
378 if (reqp->dr_ctx.atomic) {
379 crypto_ctx_t ctx;
380 ctx.cc_provider_private = reqp;
381 dca_rsactxfree(&ctx);
382 }
383 }
384
385 /*
386 * Setup either a public or a private RSA key for subsequent uses
387 */
388 int
dca_rsainit(crypto_ctx_t * ctx,crypto_mechanism_t * mechanism,crypto_key_t * key,int kmflag)389 dca_rsainit(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
390 crypto_key_t *key, int kmflag)
391 {
392 crypto_object_attribute_t *attr;
393 unsigned expname = 0;
394 void *attrdata;
395 int rv;
396
397 uchar_t *exp;
398 uchar_t *p;
399 uchar_t *q;
400 uchar_t *dp;
401 uchar_t *dq;
402 uchar_t *pinv;
403
404 unsigned explen = 0;
405 unsigned plen = 0;
406 unsigned qlen = 0;
407 unsigned dplen = 0;
408 unsigned dqlen = 0;
409 unsigned pinvlen = 0;
410
411 unsigned modbits, expbits, pbits, qbits;
412 unsigned modfix, expfix, pqfix = 0;
413 uint16_t ctxlen;
414 caddr_t kaddr;
415 dca_request_t *reqp = NULL;
416 dca_t *dca = (dca_t *)ctx->cc_provider;
417
418 DBG(NULL, DENTRY, "dca_rsainit: start");
419
420 if ((reqp = dca_getreq(dca, MCR2, 1)) == NULL) {
421 DBG(NULL, DWARN,
422 "dca_rsainit: unable to allocate request for RSA");
423 rv = CRYPTO_HOST_MEMORY;
424 goto errout;
425 }
426
427 reqp->dr_ctx.ctx_cm_type = mechanism->cm_type;
428 ctx->cc_provider_private = reqp;
429
430 /*
431 * Key type can be either RAW, or REFERENCE, or ATTR_LIST (VALUE).
432 * Only ATTR_LIST is supported on Deimos for RSA.
433 */
434 if ((attr = dca_get_key_attr(key)) == NULL) {
435 DBG(NULL, DWARN, "dca_rsainit: key attributes missing");
436 rv = CRYPTO_KEY_TYPE_INCONSISTENT;
437 goto errout;
438 }
439
440 if (dca_find_attribute(attr, key->ck_count, CKA_PUBLIC_EXPONENT))
441 expname = CKA_PUBLIC_EXPONENT;
442
443 /*
444 * RSA public key has only public exponent. RSA private key must have
445 * private exponent. However, it may also have public exponent.
446 * Thus, the existance of a private exponent indicates a private key.
447 */
448 if (dca_find_attribute(attr, key->ck_count, CKA_PRIVATE_EXPONENT))
449 expname = CKA_PRIVATE_EXPONENT;
450
451 if (!expname) {
452 DBG(NULL, DWARN, "dca_rsainit: no exponent in key");
453 rv = CRYPTO_ARGUMENTS_BAD;
454 goto errout;
455 }
456
457 /* Modulus */
458 if ((rv = dca_attr_lookup_uint8_array(attr, key->ck_count, CKA_MODULUS,
459 &attrdata, &(reqp->dr_ctx.modlen))) != CRYPTO_SUCCESS) {
460 DBG(NULL, DWARN, "dca_rsainit: failed to retrieve modulus");
461 goto errout;
462 }
463 if ((reqp->dr_ctx.modlen == 0) ||
464 (reqp->dr_ctx.modlen > RSA_MAX_KEY_LEN)) {
465 DBG(NULL, DWARN, "dca_rsainit: bad modulus size");
466 rv = CRYPTO_ARGUMENTS_BAD;
467 goto errout;
468 }
469 if ((reqp->dr_ctx.mod = kmem_alloc(reqp->dr_ctx.modlen, kmflag)) ==
470 NULL) {
471 rv = CRYPTO_HOST_MEMORY;
472 goto errout;
473 }
474 bcopy(attrdata, reqp->dr_ctx.mod, reqp->dr_ctx.modlen);
475
476 /* Exponent */
477 if ((rv = dca_attr_lookup_uint8_array(attr, key->ck_count, expname,
478 (void **) &exp, &explen)) != CRYPTO_SUCCESS) {
479 DBG(NULL, DWARN, "dca_rsainit: failed to retrieve exponent");
480 goto errout;
481 }
482 if ((explen == 0) || (explen > RSA_MAX_KEY_LEN)) {
483 DBG(NULL, DWARN, "dca_rsainit: bad exponent size");
484 rv = CRYPTO_ARGUMENTS_BAD;
485 goto errout;
486 }
487
488 /* Lookup private attributes */
489 if (expname == CKA_PRIVATE_EXPONENT) {
490 /* Prime 1 */
491 (void) dca_attr_lookup_uint8_array(attr, key->ck_count,
492 CKA_PRIME_1, (void **)&q, &qlen);
493
494 /* Prime 2 */
495 (void) dca_attr_lookup_uint8_array(attr, key->ck_count,
496 CKA_PRIME_2, (void **)&p, &plen);
497
498 /* Exponent 1 */
499 (void) dca_attr_lookup_uint8_array(attr, key->ck_count,
500 CKA_EXPONENT_1, (void **)&dq, &dqlen);
501
502 /* Exponent 2 */
503 (void) dca_attr_lookup_uint8_array(attr, key->ck_count,
504 CKA_EXPONENT_2, (void **)&dp, &dplen);
505
506 /* Coefficient */
507 (void) dca_attr_lookup_uint8_array(attr, key->ck_count,
508 CKA_COEFFICIENT, (void **)&pinv, &pinvlen);
509 }
510
511 modbits = dca_bitlen(reqp->dr_ctx.mod, reqp->dr_ctx.modlen);
512 expbits = dca_bitlen(exp, explen);
513
514 if ((modfix = dca_padfull(modbits)) == 0) {
515 DBG(NULL, DWARN, "dca_rsainit: modulus too long");
516 rv = CRYPTO_KEY_SIZE_RANGE;
517 goto errout;
518 }
519 expfix = ROUNDUP(explen, sizeof (uint32_t));
520
521 if (plen && qlen && dplen && dqlen && pinvlen) {
522 unsigned pfix, qfix;
523 qbits = dca_bitlen(q, qlen);
524 pbits = dca_bitlen(p, plen);
525 qfix = dca_padhalf(qbits);
526 pfix = dca_padhalf(pbits);
527 if (pfix & qfix)
528 pqfix = max(pfix, qfix);
529 }
530
531 if (pqfix) {
532 reqp->dr_job_stat = DS_RSAPRIVATE;
533 reqp->dr_pkt_length = 2 * pqfix;
534 } else {
535 reqp->dr_job_stat = DS_RSAPUBLIC;
536 reqp->dr_pkt_length = modfix;
537 }
538
539 if (pqfix) {
540 /*
541 * NOTE: chip's notion of p vs. q is reversed from
542 * PKCS#11. We use the chip's notion in our variable
543 * naming.
544 */
545 ctxlen = 8 + pqfix * 5;
546
547 /* write out the context structure */
548 PUTCTX16(reqp, CTX_CMD, CMD_RSAPRIVATE);
549 PUTCTX16(reqp, CTX_LENGTH, ctxlen);
550 /* exponent and modulus length in bits!!! */
551 PUTCTX16(reqp, CTX_RSAQLEN, qbits);
552 PUTCTX16(reqp, CTX_RSAPLEN, pbits);
553
554 kaddr = reqp->dr_ctx_kaddr + CTX_RSABIGNUMS;
555
556 /* store the bignums */
557 dca_reverse(p, kaddr, plen, pqfix);
558 kaddr += pqfix;
559
560 dca_reverse(q, kaddr, qlen, pqfix);
561 kaddr += pqfix;
562
563 dca_reverse(dp, kaddr, dplen, pqfix);
564 kaddr += pqfix;
565
566 dca_reverse(dq, kaddr, dqlen, pqfix);
567 kaddr += pqfix;
568
569 dca_reverse(pinv, kaddr, pinvlen, pqfix);
570 kaddr += pqfix;
571 } else {
572 ctxlen = 8 + modfix + expfix;
573 /* write out the context structure */
574 PUTCTX16(reqp, CTX_CMD, CMD_RSAPUBLIC);
575 PUTCTX16(reqp, CTX_LENGTH, (uint16_t)ctxlen);
576 /* exponent and modulus length in bits!!! */
577 PUTCTX16(reqp, CTX_RSAEXPLEN, expbits);
578 PUTCTX16(reqp, CTX_RSAMODLEN, modbits);
579
580 kaddr = reqp->dr_ctx_kaddr + CTX_RSABIGNUMS;
581
582 /* store the bignums */
583 dca_reverse(reqp->dr_ctx.mod, kaddr, reqp->dr_ctx.modlen,
584 modfix);
585 kaddr += modfix;
586
587 dca_reverse(exp, kaddr, explen, expfix);
588 kaddr += expfix;
589 }
590
591 reqp->dr_ctx.pqfix = pqfix;
592
593 errout:
594 if (rv != CRYPTO_SUCCESS)
595 dca_rsactxfree(ctx);
596
597 return (rv);
598 }
599
600 void
dca_rsactxfree(void * arg)601 dca_rsactxfree(void *arg)
602 {
603 crypto_ctx_t *ctx = (crypto_ctx_t *)arg;
604 dca_request_t *reqp = ctx->cc_provider_private;
605
606 if (reqp == NULL)
607 return;
608
609 if (reqp->dr_ctx.mod)
610 kmem_free(reqp->dr_ctx.mod, reqp->dr_ctx.modlen);
611
612 reqp->dr_ctx.mode = 0;
613 reqp->dr_ctx.ctx_cm_type = 0;
614 reqp->dr_ctx.mod = NULL;
615 reqp->dr_ctx.modlen = 0;
616 reqp->dr_ctx.pqfix = 0;
617 reqp->dr_ctx.atomic = 0;
618
619 if (reqp->destroy)
620 dca_destroyreq(reqp);
621 else
622 dca_freereq(reqp);
623
624 ctx->cc_provider_private = NULL;
625 }
626
627 int
dca_rsaatomic(crypto_provider_handle_t provider,crypto_session_id_t session_id,crypto_mechanism_t * mechanism,crypto_key_t * key,crypto_data_t * input,crypto_data_t * output,int kmflag,crypto_req_handle_t req,int mode)628 dca_rsaatomic(crypto_provider_handle_t provider,
629 crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
630 crypto_key_t *key, crypto_data_t *input, crypto_data_t *output,
631 int kmflag, crypto_req_handle_t req, int mode)
632 {
633 crypto_ctx_t ctx; /* on the stack */
634 int rv;
635
636 ctx.cc_provider = provider;
637 ctx.cc_session = session_id;
638
639 rv = dca_rsainit(&ctx, mechanism, key, kmflag);
640 if (rv != CRYPTO_SUCCESS) {
641 DBG(NULL, DWARN, "dca_rsaatomic: dca_rsainit() failed");
642 /* The content of ctx should have been freed already */
643 return (rv);
644 }
645
646 /*
647 * Set the atomic flag so that the hardware callback function
648 * will free the context.
649 */
650 ((dca_request_t *)ctx.cc_provider_private)->dr_ctx.atomic = 1;
651
652 /* check for inplace ops */
653 if (input == output) {
654 ((dca_request_t *)ctx.cc_provider_private)->dr_flags
655 |= DR_INPLACE;
656 }
657
658 rv = dca_rsastart(&ctx, input, output, req, mode);
659
660 /*
661 * The context will be freed in the hardware callback function if it
662 * is queued
663 */
664 if (rv != CRYPTO_QUEUED)
665 dca_rsactxfree(&ctx);
666
667 return (rv);
668 }
669
670
671 /*
672 * For RSA_PKCS padding and unpadding:
673 * 1. The minimum padding is 11 bytes.
674 * 2. The first and the last bytes must 0.
675 * 3. The second byte is 1 for private and 2 for public keys.
676 * 4. Pad with 0xff for private and non-zero random for public keys.
677 */
678 static int
dca_pkcs1_padding(dca_t * dca,caddr_t buf,int flen,int tlen,int private)679 dca_pkcs1_padding(dca_t *dca, caddr_t buf, int flen, int tlen, int private)
680 {
681 int i;
682
683 DBG(NULL, DENTRY,
684 "dca_pkcs1_padding: tlen: %d, flen: %d: private: %d\n",
685 tlen, flen, private);
686
687 if (flen > tlen - 11)
688 return (CRYPTO_DATA_LEN_RANGE);
689
690 if (private) {
691 /* Padding for private encrypt */
692 buf[flen] = '\0';
693 for (i = flen + 1; i < tlen - 2; i++) {
694 buf[i] = (unsigned char) 0xff;
695 }
696 buf[tlen - 2] = 1;
697 buf[tlen - 1] = 0;
698 } else {
699 /* Padding for public encrypt */
700 buf[flen] = '\0';
701
702 if (dca_random_buffer(dca, &buf[flen+1], tlen - flen - 3) !=
703 CRYPTO_SUCCESS)
704 return (CRYPTO_RANDOM_NO_RNG);
705
706 buf[tlen - 2] = 2;
707 buf[tlen - 1] = 0;
708 }
709
710 return (CRYPTO_QUEUED);
711 }
712
713 static int
dca_pkcs1_unpadding(char * buf,int * tlen,int flen,int mode)714 dca_pkcs1_unpadding(char *buf, int *tlen, int flen, int mode)
715 {
716 int i;
717 const unsigned char *p;
718 unsigned char type;
719
720 DBG(NULL, DENTRY, "dca_pkcs1_unpadding: tlen: %d, flen: %d\n",
721 *tlen, flen);
722
723 p = (unsigned char *) buf + (flen-1);
724 if (*(p--) != 0)
725 return decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_INVALID,
726 CRYPTO_SIGNATURE_INVALID, CRYPTO_DATA_INVALID);
727
728 /* It is ok if the data length is 0 after removing the padding */
729 type = *(p--);
730 if (type == 01) {
731 for (i = flen - 3; i >= 0; i--) {
732 if (*p != 0xff) {
733 if (*p == '\0') {
734 p--;
735 break;
736 } else {
737 return decrypt_error_code(mode,
738 CRYPTO_ENCRYPTED_DATA_INVALID,
739 CRYPTO_SIGNATURE_INVALID,
740 CRYPTO_DATA_INVALID);
741 }
742 }
743 p--;
744 }
745 } else if (type == 02) {
746 for (i = flen - 3; i >= 0; i--) {
747 if (*p == '\0') {
748 p--;
749 break;
750 }
751 p--;
752 }
753 } else {
754 return decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_INVALID,
755 CRYPTO_SIGNATURE_INVALID, CRYPTO_DATA_INVALID);
756 }
757
758 /* i < 0 means did not find the end of the padding */
759 if (i < 0)
760 return decrypt_error_code(mode, CRYPTO_ENCRYPTED_DATA_INVALID,
761 CRYPTO_SIGNATURE_INVALID, CRYPTO_DATA_INVALID);
762
763 if (i > *tlen) {
764 *tlen = i;
765 return (CRYPTO_BUFFER_TOO_SMALL);
766 }
767
768 if (flen - i < 11)
769 return decrypt_error_code(mode,
770 CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
771 CRYPTO_SIGNATURE_LEN_RANGE, CRYPTO_DATA_LEN_RANGE);
772
773 /* Return the unpadded length to the caller */
774 *tlen = i;
775
776 return (CRYPTO_SUCCESS);
777 }
778
779 /*
780 * For RSA_X_509 padding and unpadding, pad all 0s before actual data.
781 * Note that the data will be in reverse order.
782 */
783 static int
dca_x509_padding(caddr_t buf,int flen,int tlen)784 dca_x509_padding(caddr_t buf, int flen, int tlen)
785 {
786 DBG(NULL, DENTRY, "dca_x509_padding: tlen: %d, flen: %d\n",
787 tlen, flen);
788
789 bzero(buf+tlen, tlen - flen);
790
791 return (CRYPTO_QUEUED);
792 }
793
794 /* ARGSUSED */
795 static int
dca_x509_unpadding(char * buf,int tlen,int flen,int mode)796 dca_x509_unpadding(char *buf, int tlen, int flen, int mode)
797 {
798 int i;
799 const unsigned char *p;
800
801 DBG(NULL, DENTRY, "dca_x509_unpadding: tlen: %d, flen: %d\n",
802 tlen, flen);
803
804 p = (unsigned char *) buf + flen;
805 for (i = tlen; i < flen; i++) {
806 if (*(--p) != 0)
807 return (CRYPTO_SIGNATURE_INVALID);
808 }
809
810 return (CRYPTO_SUCCESS);
811 }
812
decrypt_error_code(int mode,int decrypt,int verify,int def)813 static int decrypt_error_code(int mode, int decrypt, int verify, int def)
814 {
815 switch (mode) {
816 case DCA_RSA_DEC:
817 return (decrypt);
818 case DCA_RSA_VRFY:
819 case DCA_RSA_VRFYR:
820 return (verify);
821 default:
822 return (def);
823 }
824 }
825