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.
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.
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]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Deimos - cryptographic acceleration based upon Broadcom 582x.
33 #include <sys/types.h>
35 #include <sys/sunddi.h>
38 #include <sys/crypto/spi.h>
39 #include <sys/crypto/dca.h>
42 static void dca_rsaverifydone(dca_request_t
*, int);
43 static void dca_rsadone(dca_request_t
*, int);
45 /* Exported function prototypes */
46 int dca_rsastart(crypto_ctx_t
*, crypto_data_t
*, crypto_data_t
*,
47 crypto_req_handle_t
, int);
48 int dca_rsainit(crypto_ctx_t
*, crypto_mechanism_t
*, crypto_key_t
*, int);
49 void dca_rsactxfree(void *);
50 int dca_rsaatomic(crypto_provider_handle_t
, crypto_session_id_t
,
51 crypto_mechanism_t
*, crypto_key_t
*, crypto_data_t
*, crypto_data_t
*,
52 int, crypto_req_handle_t
, int);
54 /* Local function prototypes */
55 static int dca_pkcs1_padding(dca_t
*dca
, caddr_t buf
, int flen
, int tlen
,
57 static int dca_pkcs1_unpadding(char *buf
, int *tlen
, int flen
, int mode
);
58 static int dca_x509_padding(caddr_t buf
, int flen
, int tlen
);
59 static int dca_x509_unpadding(char *buf
, int tlen
, int flen
, int mode
);
60 static int decrypt_error_code(int mode
, int decrypt
, int verify
, int def
);
63 int dca_rsastart(crypto_ctx_t
*ctx
, crypto_data_t
*in
, crypto_data_t
*out
,
64 crypto_req_handle_t req
, int mode
)
66 dca_request_t
*reqp
= ctx
->cc_provider_private
;
67 dca_t
*dca
= ctx
->cc_provider
;
69 int rv
= CRYPTO_QUEUED
;
72 /* We don't support non-contiguous buffers for RSA */
73 if (dca_sgcheck(dca
, in
, DCA_SG_CONTIG
) ||
74 dca_sgcheck(dca
, out
, DCA_SG_CONTIG
)) {
75 rv
= CRYPTO_NOT_SUPPORTED
;
81 /* Extracting the key attributes is now done in dca_rsainit(). */
82 if (mode
== DCA_RSA_ENC
|| mode
== DCA_RSA_SIGN
||
83 mode
== DCA_RSA_SIGNR
) {
85 * Return length needed to store the output.
86 * For sign, sign-recover, and encrypt, the output buffer
87 * should not be smaller than modlen since PKCS or X_509
88 * padding will be applied
90 if (dca_length(out
) < reqp
->dr_ctx
.modlen
) {
92 "dca_rsastart: output buffer too short (%d < %d)",
93 dca_length(out
), reqp
->dr_ctx
.modlen
);
94 out
->cd_length
= reqp
->dr_ctx
.modlen
;
95 rv
= CRYPTO_BUFFER_TOO_SMALL
;
99 if (out
!= in
&& out
->cd_length
> reqp
->dr_ctx
.modlen
)
100 out
->cd_length
= reqp
->dr_ctx
.modlen
;
102 /* The input length should not be bigger than the modulus */
103 if (len
> reqp
->dr_ctx
.modlen
) {
104 rv
= decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_LEN_RANGE
,
105 CRYPTO_SIGNATURE_LEN_RANGE
, CRYPTO_DATA_LEN_RANGE
);
110 * For decryption, verify, and verifyRecover, the input length should
111 * not be less than the modulus
113 if (len
< reqp
->dr_ctx
.modlen
&& (mode
== DCA_RSA_DEC
||
114 mode
== DCA_RSA_VRFY
|| mode
== DCA_RSA_VRFYR
)) {
115 rv
= decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_LEN_RANGE
,
116 CRYPTO_SIGNATURE_LEN_RANGE
, CRYPTO_DATA_LEN_RANGE
);
121 * For decryption and verifyRecover, the output buffer should not
122 * be less than the modulus
124 if (out
->cd_length
< reqp
->dr_ctx
.modlen
&& (mode
== DCA_RSA_DEC
||
125 mode
== DCA_RSA_VRFYR
) &&
126 reqp
->dr_ctx
.ctx_cm_type
== RSA_X_509_MECH_INFO_TYPE
) {
127 out
->cd_length
= reqp
->dr_ctx
.modlen
;
128 rv
= CRYPTO_BUFFER_TOO_SMALL
;
132 /* For decrypt and verify, the input should not be less than output */
133 if (out
&& len
< out
->cd_length
) {
134 if ((rv
= decrypt_error_code(mode
,
135 CRYPTO_ENCRYPTED_DATA_LEN_RANGE
,
136 CRYPTO_SIGNATURE_LEN_RANGE
, CRYPTO_SUCCESS
)) !=
141 if ((daddr
= dca_bufdaddr(in
)) == NULL
&& len
> 0) {
142 rv
= CRYPTO_ARGUMENTS_BAD
;
146 if (dca_numcmp(daddr
, len
, (char *)reqp
->dr_ctx
.mod
,
147 reqp
->dr_ctx
.modlen
) > 0) {
149 "dca_rsastart: input larger (numerically) than modulus!");
150 rv
= decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_INVALID
,
151 CRYPTO_SIGNATURE_INVALID
, CRYPTO_DATA_INVALID
);
155 reqp
->dr_byte_stat
= -1;
158 reqp
->dr_kcf_req
= req
;
159 if (mode
== DCA_RSA_VRFY
)
160 reqp
->dr_callback
= dca_rsaverifydone
;
162 reqp
->dr_callback
= dca_rsadone
;
164 dca_reverse(daddr
, reqp
->dr_ibuf_kaddr
, len
, reqp
->dr_pkt_length
);
165 if (mode
== DCA_RSA_ENC
|| mode
== DCA_RSA_SIGN
||
166 mode
== DCA_RSA_SIGNR
) {
168 * Needs to pad appropriately for encrypt, sign, and
171 if (reqp
->dr_ctx
.ctx_cm_type
== RSA_PKCS_MECH_INFO_TYPE
) {
172 if ((rv
= dca_pkcs1_padding(dca
, reqp
->dr_ibuf_kaddr
,
173 len
, reqp
->dr_ctx
.modlen
, reqp
->dr_ctx
.pqfix
)) !=
176 } else if (reqp
->dr_ctx
.ctx_cm_type
==
177 RSA_X_509_MECH_INFO_TYPE
) {
178 if ((rv
= dca_x509_padding(reqp
->dr_ibuf_kaddr
,
179 len
, reqp
->dr_pkt_length
)) != CRYPTO_QUEUED
)
183 reqp
->dr_ctx
.mode
= mode
;
186 * Since the max RSA input size is 256 bytes (2048 bits), the firstx
187 * page (at least 4096 bytes) in the pre-mapped buffer is large enough.
188 * Therefore, we use this first page for RSA.
190 reqp
->dr_in_paddr
= reqp
->dr_ibuf_head
.dc_buffer_paddr
;
191 reqp
->dr_in_next
= 0;
192 reqp
->dr_in_len
= reqp
->dr_pkt_length
;
193 reqp
->dr_out_paddr
= reqp
->dr_obuf_head
.dc_buffer_paddr
;
194 reqp
->dr_out_next
= 0;
195 reqp
->dr_out_len
= reqp
->dr_pkt_length
;
197 /* schedule the work by doing a submit */
198 rv
= dca_start(dca
, reqp
, MCR2
, 1);
202 if (rv
!= CRYPTO_QUEUED
&& rv
!= CRYPTO_BUFFER_TOO_SMALL
)
203 (void) dca_free_context(ctx
);
209 dca_rsadone(dca_request_t
*reqp
, int errno
)
211 if (errno
== CRYPTO_SUCCESS
) {
212 int outsz
= reqp
->dr_out
->cd_length
;
215 (void) ddi_dma_sync(reqp
->dr_obuf_dmah
, 0, reqp
->dr_out_len
,
216 DDI_DMA_SYNC_FORKERNEL
);
217 if (dca_check_dma_handle(reqp
->dr_dca
, reqp
->dr_obuf_dmah
,
218 DCA_FM_ECLASS_NONE
) != DDI_SUCCESS
) {
219 reqp
->destroy
= TRUE
;
220 errno
= CRYPTO_DEVICE_ERROR
;
224 if (reqp
->dr_ctx
.mode
== DCA_RSA_DEC
||
225 reqp
->dr_ctx
.mode
== DCA_RSA_VRFY
||
226 reqp
->dr_ctx
.mode
== DCA_RSA_VRFYR
) {
228 * Needs to unpad appropriately for decrypt, verify,
231 if (reqp
->dr_ctx
.ctx_cm_type
==
232 RSA_PKCS_MECH_INFO_TYPE
) {
233 errno
= dca_pkcs1_unpadding(
234 reqp
->dr_obuf_kaddr
, &outsz
,
235 reqp
->dr_ctx
.modlen
, reqp
->dr_ctx
.mode
);
237 /* check for bad data errors */
238 if (errno
!= CRYPTO_SUCCESS
&&
239 errno
!= CRYPTO_BUFFER_TOO_SMALL
) {
242 if (dca_bufdaddr(reqp
->dr_out
) == NULL
) {
243 errno
= CRYPTO_BUFFER_TOO_SMALL
;
245 if (errno
== CRYPTO_BUFFER_TOO_SMALL
) {
246 reqp
->dr_out
->cd_length
= outsz
;
249 /* Reset the output data length */
250 reqp
->dr_out
->cd_length
= outsz
;
251 } else if (reqp
->dr_ctx
.ctx_cm_type
==
252 RSA_X_509_MECH_INFO_TYPE
) {
253 if ((errno
= dca_x509_unpadding(
254 reqp
->dr_obuf_kaddr
, outsz
,
255 reqp
->dr_pkt_length
, reqp
->dr_ctx
.mode
)) !=
261 if ((daddr
= dca_bufdaddr(reqp
->dr_out
)) == NULL
) {
262 DBG(reqp
->dr_dca
, DINTR
,
263 "dca_rsadone: reqp->dr_out is bad");
264 errno
= CRYPTO_ARGUMENTS_BAD
;
268 * Note that there may be some number of null bytes
269 * at the end of the source (result), but we don't care
270 * about them -- they are place holders only and are
273 dca_reverse(reqp
->dr_obuf_kaddr
, daddr
, outsz
, outsz
);
276 ASSERT(reqp
->dr_kcf_req
!= NULL
);
278 /* notify framework that request is completed */
279 crypto_op_notification(reqp
->dr_kcf_req
, errno
);
280 DBG(reqp
->dr_dca
, DINTR
,
281 "dca_rsadone: returning 0x%x to the kef via crypto_op_notification",
285 * For non-atomic operations, reqp will be freed in the kCF
286 * callback function since it may be needed again if
287 * CRYPTO_BUFFER_TOO_SMALL is returned to kCF
289 if (reqp
->dr_ctx
.atomic
) {
291 ctx
.cc_provider_private
= reqp
;
292 dca_rsactxfree(&ctx
);
297 dca_rsaverifydone(dca_request_t
*reqp
, int errno
)
299 if (errno
== CRYPTO_SUCCESS
) {
300 char scratch
[RSA_MAX_KEY_LEN
];
301 int outsz
= reqp
->dr_out
->cd_length
;
305 * ASSUMPTION: the signature length was already
306 * checked on the way in, and it is a valid length.
308 (void) ddi_dma_sync(reqp
->dr_obuf_dmah
, 0, outsz
,
309 DDI_DMA_SYNC_FORKERNEL
);
310 if (dca_check_dma_handle(reqp
->dr_dca
, reqp
->dr_obuf_dmah
,
311 DCA_FM_ECLASS_NONE
) != DDI_SUCCESS
) {
312 reqp
->destroy
= TRUE
;
313 errno
= CRYPTO_DEVICE_ERROR
;
317 if (reqp
->dr_ctx
.mode
== DCA_RSA_DEC
||
318 reqp
->dr_ctx
.mode
== DCA_RSA_VRFY
||
319 reqp
->dr_ctx
.mode
== DCA_RSA_VRFYR
) {
321 * Needs to unpad appropriately for decrypt, verify,
324 if (reqp
->dr_ctx
.ctx_cm_type
==
325 RSA_PKCS_MECH_INFO_TYPE
) {
326 errno
= dca_pkcs1_unpadding(
327 reqp
->dr_obuf_kaddr
, &outsz
,
328 reqp
->dr_ctx
.modlen
, reqp
->dr_ctx
.mode
);
330 /* check for bad data errors */
331 if (errno
!= CRYPTO_SUCCESS
&&
332 errno
!= CRYPTO_BUFFER_TOO_SMALL
) {
335 if (dca_bufdaddr(reqp
->dr_out
) == NULL
) {
336 errno
= CRYPTO_BUFFER_TOO_SMALL
;
338 if (errno
== CRYPTO_BUFFER_TOO_SMALL
) {
339 reqp
->dr_out
->cd_length
= outsz
;
342 /* Reset the output data length */
343 reqp
->dr_out
->cd_length
= outsz
;
344 } else if (reqp
->dr_ctx
.ctx_cm_type
==
345 RSA_X_509_MECH_INFO_TYPE
) {
346 if ((errno
= dca_x509_unpadding(
347 reqp
->dr_obuf_kaddr
, outsz
,
348 reqp
->dr_pkt_length
, reqp
->dr_ctx
.mode
)) !=
354 dca_reverse(reqp
->dr_obuf_kaddr
, scratch
, outsz
, outsz
);
356 if ((daddr
= dca_bufdaddr(reqp
->dr_out
)) == NULL
) {
357 errno
= CRYPTO_ARGUMENTS_BAD
;
360 if (dca_numcmp(daddr
, reqp
->dr_out
->cd_length
, scratch
,
363 errno
= CRYPTO_SIGNATURE_INVALID
;
367 ASSERT(reqp
->dr_kcf_req
!= NULL
);
369 /* notify framework that request is completed */
370 crypto_op_notification(reqp
->dr_kcf_req
, errno
);
371 DBG(reqp
->dr_dca
, DINTR
,
372 "dca_rsaverifydone: rtn 0x%x to the kef via crypto_op_notification",
376 * For non-atomic operations, reqp will be freed in the kCF
377 * callback function since it may be needed again if
378 * CRYPTO_BUFFER_TOO_SMALL is returned to kCF
380 if (reqp
->dr_ctx
.atomic
) {
382 ctx
.cc_provider_private
= reqp
;
383 dca_rsactxfree(&ctx
);
388 * Setup either a public or a private RSA key for subsequent uses
391 dca_rsainit(crypto_ctx_t
*ctx
, crypto_mechanism_t
*mechanism
,
392 crypto_key_t
*key
, int kmflag
)
394 crypto_object_attribute_t
*attr
;
395 unsigned expname
= 0;
411 unsigned pinvlen
= 0;
413 unsigned modbits
, expbits
, pbits
, qbits
;
414 unsigned modfix
, expfix
, pqfix
= 0;
417 dca_request_t
*reqp
= NULL
;
418 dca_t
*dca
= (dca_t
*)ctx
->cc_provider
;
420 DBG(NULL
, DENTRY
, "dca_rsainit: start");
422 if ((reqp
= dca_getreq(dca
, MCR2
, 1)) == NULL
) {
424 "dca_rsainit: unable to allocate request for RSA");
425 rv
= CRYPTO_HOST_MEMORY
;
429 reqp
->dr_ctx
.ctx_cm_type
= mechanism
->cm_type
;
430 ctx
->cc_provider_private
= reqp
;
433 * Key type can be either RAW, or REFERENCE, or ATTR_LIST (VALUE).
434 * Only ATTR_LIST is supported on Deimos for RSA.
436 if ((attr
= dca_get_key_attr(key
)) == NULL
) {
437 DBG(NULL
, DWARN
, "dca_rsainit: key attributes missing");
438 rv
= CRYPTO_KEY_TYPE_INCONSISTENT
;
442 if (dca_find_attribute(attr
, key
->ck_count
, CKA_PUBLIC_EXPONENT
))
443 expname
= CKA_PUBLIC_EXPONENT
;
446 * RSA public key has only public exponent. RSA private key must have
447 * private exponent. However, it may also have public exponent.
448 * Thus, the existance of a private exponent indicates a private key.
450 if (dca_find_attribute(attr
, key
->ck_count
, CKA_PRIVATE_EXPONENT
))
451 expname
= CKA_PRIVATE_EXPONENT
;
454 DBG(NULL
, DWARN
, "dca_rsainit: no exponent in key");
455 rv
= CRYPTO_ARGUMENTS_BAD
;
460 if ((rv
= dca_attr_lookup_uint8_array(attr
, key
->ck_count
, CKA_MODULUS
,
461 &attrdata
, &(reqp
->dr_ctx
.modlen
))) != CRYPTO_SUCCESS
) {
462 DBG(NULL
, DWARN
, "dca_rsainit: failed to retrieve modulus");
465 if ((reqp
->dr_ctx
.modlen
== 0) ||
466 (reqp
->dr_ctx
.modlen
> RSA_MAX_KEY_LEN
)) {
467 DBG(NULL
, DWARN
, "dca_rsainit: bad modulus size");
468 rv
= CRYPTO_ARGUMENTS_BAD
;
471 if ((reqp
->dr_ctx
.mod
= kmem_alloc(reqp
->dr_ctx
.modlen
, kmflag
)) ==
473 rv
= CRYPTO_HOST_MEMORY
;
476 bcopy(attrdata
, reqp
->dr_ctx
.mod
, reqp
->dr_ctx
.modlen
);
479 if ((rv
= dca_attr_lookup_uint8_array(attr
, key
->ck_count
, expname
,
480 (void **) &exp
, &explen
)) != CRYPTO_SUCCESS
) {
481 DBG(NULL
, DWARN
, "dca_rsainit: failed to retrieve exponent");
484 if ((explen
== 0) || (explen
> RSA_MAX_KEY_LEN
)) {
485 DBG(NULL
, DWARN
, "dca_rsainit: bad exponent size");
486 rv
= CRYPTO_ARGUMENTS_BAD
;
490 /* Lookup private attributes */
491 if (expname
== CKA_PRIVATE_EXPONENT
) {
493 (void) dca_attr_lookup_uint8_array(attr
, key
->ck_count
,
494 CKA_PRIME_1
, (void **)&q
, &qlen
);
497 (void) dca_attr_lookup_uint8_array(attr
, key
->ck_count
,
498 CKA_PRIME_2
, (void **)&p
, &plen
);
501 (void) dca_attr_lookup_uint8_array(attr
, key
->ck_count
,
502 CKA_EXPONENT_1
, (void **)&dq
, &dqlen
);
505 (void) dca_attr_lookup_uint8_array(attr
, key
->ck_count
,
506 CKA_EXPONENT_2
, (void **)&dp
, &dplen
);
509 (void) dca_attr_lookup_uint8_array(attr
, key
->ck_count
,
510 CKA_COEFFICIENT
, (void **)&pinv
, &pinvlen
);
513 modbits
= dca_bitlen(reqp
->dr_ctx
.mod
, reqp
->dr_ctx
.modlen
);
514 expbits
= dca_bitlen(exp
, explen
);
516 if ((modfix
= dca_padfull(modbits
)) == 0) {
517 DBG(NULL
, DWARN
, "dca_rsainit: modulus too long");
518 rv
= CRYPTO_KEY_SIZE_RANGE
;
521 expfix
= ROUNDUP(explen
, sizeof (uint32_t));
523 if (plen
&& qlen
&& dplen
&& dqlen
&& pinvlen
) {
525 qbits
= dca_bitlen(q
, qlen
);
526 pbits
= dca_bitlen(p
, plen
);
527 qfix
= dca_padhalf(qbits
);
528 pfix
= dca_padhalf(pbits
);
530 pqfix
= max(pfix
, qfix
);
534 reqp
->dr_job_stat
= DS_RSAPRIVATE
;
535 reqp
->dr_pkt_length
= 2 * pqfix
;
537 reqp
->dr_job_stat
= DS_RSAPUBLIC
;
538 reqp
->dr_pkt_length
= modfix
;
543 * NOTE: chip's notion of p vs. q is reversed from
544 * PKCS#11. We use the chip's notion in our variable
547 ctxlen
= 8 + pqfix
* 5;
549 /* write out the context structure */
550 PUTCTX16(reqp
, CTX_CMD
, CMD_RSAPRIVATE
);
551 PUTCTX16(reqp
, CTX_LENGTH
, ctxlen
);
552 /* exponent and modulus length in bits!!! */
553 PUTCTX16(reqp
, CTX_RSAQLEN
, qbits
);
554 PUTCTX16(reqp
, CTX_RSAPLEN
, pbits
);
556 kaddr
= reqp
->dr_ctx_kaddr
+ CTX_RSABIGNUMS
;
558 /* store the bignums */
559 dca_reverse(p
, kaddr
, plen
, pqfix
);
562 dca_reverse(q
, kaddr
, qlen
, pqfix
);
565 dca_reverse(dp
, kaddr
, dplen
, pqfix
);
568 dca_reverse(dq
, kaddr
, dqlen
, pqfix
);
571 dca_reverse(pinv
, kaddr
, pinvlen
, pqfix
);
574 ctxlen
= 8 + modfix
+ expfix
;
575 /* write out the context structure */
576 PUTCTX16(reqp
, CTX_CMD
, CMD_RSAPUBLIC
);
577 PUTCTX16(reqp
, CTX_LENGTH
, (uint16_t)ctxlen
);
578 /* exponent and modulus length in bits!!! */
579 PUTCTX16(reqp
, CTX_RSAEXPLEN
, expbits
);
580 PUTCTX16(reqp
, CTX_RSAMODLEN
, modbits
);
582 kaddr
= reqp
->dr_ctx_kaddr
+ CTX_RSABIGNUMS
;
584 /* store the bignums */
585 dca_reverse(reqp
->dr_ctx
.mod
, kaddr
, reqp
->dr_ctx
.modlen
,
589 dca_reverse(exp
, kaddr
, explen
, expfix
);
593 reqp
->dr_ctx
.pqfix
= pqfix
;
596 if (rv
!= CRYPTO_SUCCESS
)
603 dca_rsactxfree(void *arg
)
605 crypto_ctx_t
*ctx
= (crypto_ctx_t
*)arg
;
606 dca_request_t
*reqp
= ctx
->cc_provider_private
;
611 if (reqp
->dr_ctx
.mod
)
612 kmem_free(reqp
->dr_ctx
.mod
, reqp
->dr_ctx
.modlen
);
614 reqp
->dr_ctx
.mode
= 0;
615 reqp
->dr_ctx
.ctx_cm_type
= 0;
616 reqp
->dr_ctx
.mod
= NULL
;
617 reqp
->dr_ctx
.modlen
= 0;
618 reqp
->dr_ctx
.pqfix
= 0;
619 reqp
->dr_ctx
.atomic
= 0;
622 dca_destroyreq(reqp
);
626 ctx
->cc_provider_private
= NULL
;
630 dca_rsaatomic(crypto_provider_handle_t provider
,
631 crypto_session_id_t session_id
, crypto_mechanism_t
*mechanism
,
632 crypto_key_t
*key
, crypto_data_t
*input
, crypto_data_t
*output
,
633 int kmflag
, crypto_req_handle_t req
, int mode
)
635 crypto_ctx_t ctx
; /* on the stack */
638 ctx
.cc_provider
= provider
;
639 ctx
.cc_session
= session_id
;
641 rv
= dca_rsainit(&ctx
, mechanism
, key
, kmflag
);
642 if (rv
!= CRYPTO_SUCCESS
) {
643 DBG(NULL
, DWARN
, "dca_rsaatomic: dca_rsainit() failed");
644 /* The content of ctx should have been freed already */
649 * Set the atomic flag so that the hardware callback function
650 * will free the context.
652 ((dca_request_t
*)ctx
.cc_provider_private
)->dr_ctx
.atomic
= 1;
654 /* check for inplace ops */
655 if (input
== output
) {
656 ((dca_request_t
*)ctx
.cc_provider_private
)->dr_flags
660 rv
= dca_rsastart(&ctx
, input
, output
, req
, mode
);
663 * The context will be freed in the hardware callback function if it
666 if (rv
!= CRYPTO_QUEUED
)
667 dca_rsactxfree(&ctx
);
674 * For RSA_PKCS padding and unpadding:
675 * 1. The minimum padding is 11 bytes.
676 * 2. The first and the last bytes must 0.
677 * 3. The second byte is 1 for private and 2 for public keys.
678 * 4. Pad with 0xff for private and non-zero random for public keys.
681 dca_pkcs1_padding(dca_t
*dca
, caddr_t buf
, int flen
, int tlen
, int private)
686 "dca_pkcs1_padding: tlen: %d, flen: %d: private: %d\n",
687 tlen
, flen
, private);
689 if (flen
> tlen
- 11)
690 return (CRYPTO_DATA_LEN_RANGE
);
693 /* Padding for private encrypt */
695 for (i
= flen
+ 1; i
< tlen
- 2; i
++) {
696 buf
[i
] = (unsigned char) 0xff;
701 /* Padding for public encrypt */
704 if (dca_random_buffer(dca
, &buf
[flen
+1], tlen
- flen
- 3) !=
706 return (CRYPTO_RANDOM_NO_RNG
);
712 return (CRYPTO_QUEUED
);
716 dca_pkcs1_unpadding(char *buf
, int *tlen
, int flen
, int mode
)
719 const unsigned char *p
;
722 DBG(NULL
, DENTRY
, "dca_pkcs1_unpadding: tlen: %d, flen: %d\n",
725 p
= (unsigned char *) buf
+ (flen
-1);
727 return decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_INVALID
,
728 CRYPTO_SIGNATURE_INVALID
, CRYPTO_DATA_INVALID
);
730 /* It is ok if the data length is 0 after removing the padding */
733 for (i
= flen
- 3; i
>= 0; i
--) {
739 return decrypt_error_code(mode
,
740 CRYPTO_ENCRYPTED_DATA_INVALID
,
741 CRYPTO_SIGNATURE_INVALID
,
742 CRYPTO_DATA_INVALID
);
747 } else if (type
== 02) {
748 for (i
= flen
- 3; i
>= 0; i
--) {
756 return decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_INVALID
,
757 CRYPTO_SIGNATURE_INVALID
, CRYPTO_DATA_INVALID
);
760 /* i < 0 means did not find the end of the padding */
762 return decrypt_error_code(mode
, CRYPTO_ENCRYPTED_DATA_INVALID
,
763 CRYPTO_SIGNATURE_INVALID
, CRYPTO_DATA_INVALID
);
767 return (CRYPTO_BUFFER_TOO_SMALL
);
771 return decrypt_error_code(mode
,
772 CRYPTO_ENCRYPTED_DATA_LEN_RANGE
,
773 CRYPTO_SIGNATURE_LEN_RANGE
, CRYPTO_DATA_LEN_RANGE
);
775 /* Return the unpadded length to the caller */
778 return (CRYPTO_SUCCESS
);
782 * For RSA_X_509 padding and unpadding, pad all 0s before actual data.
783 * Note that the data will be in reverse order.
786 dca_x509_padding(caddr_t buf
, int flen
, int tlen
)
788 DBG(NULL
, DENTRY
, "dca_x509_padding: tlen: %d, flen: %d\n",
791 bzero(buf
+tlen
, tlen
- flen
);
793 return (CRYPTO_QUEUED
);
798 dca_x509_unpadding(char *buf
, int tlen
, int flen
, int mode
)
801 const unsigned char *p
;
803 DBG(NULL
, DENTRY
, "dca_x509_unpadding: tlen: %d, flen: %d\n",
806 p
= (unsigned char *) buf
+ flen
;
807 for (i
= tlen
; i
< flen
; i
++) {
809 return (CRYPTO_SIGNATURE_INVALID
);
812 return (CRYPTO_SUCCESS
);
815 static int decrypt_error_code(int mode
, int decrypt
, int verify
, int def
)