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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
27 * This file contains padding helper routines common to
28 * the PKCS11 soft token code and the kernel crypto code.
31 #include <sys/types.h>
35 #include <sys/param.h>
38 #include <cryptoutil.h>
42 * To create a block type "02" encryption block for RSA PKCS encryption
45 * This is EME-PKCS1-v1_5 encoding as described in RSA PKCS#1.
47 * The RSA PKCS Padding before encryption is in the following format:
48 * +----+----+--------------------+----+-----------------------------+
49 * |0x00|0x02| 8 bytes or more RN |0x00| DATA |
50 * +----+----+--------------------+----+-----------------------------+
53 * To create a block type "01" block for RSA PKCS signature process.
55 * This EMSA-PKCS1-1_5 encoding as decribed in RSA PKCS#1.
57 * The RSA PKCS Padding before Signing is in the following format:
58 * +----+----+----------------------+----+-----------------------------+
59 * |0x00|0x01| 8 bytes of more 0xFF |0x00| DATA |
60 * +----+----+----------------------+----+-----------------------------+
64 pkcs1_encode(int method
, uint8_t *databuf
, size_t datalen
, uint8_t *padbuf
,
70 padlen
= padbuflen
- datalen
;
71 if (padlen
< MIN_PKCS1_PADLEN
) {
72 return (CKR_DATA_LEN_RANGE
);
78 padbuf
[1] = (method
== PKCS1_ENCRYPT
) ? 0x02 : 0x01;
80 if (method
== PKCS1_ENCRYPT
) {
82 rv
= knzero_random_generator(padbuf
+ 2, padlen
- 3);
84 rv
= (pkcs11_get_nzero_urandom(padbuf
+ 2, padlen
- 3) < 0) ?
87 } else if (method
== PKCS1_SIGN
) {
89 kmemset(padbuf
+ 2, 0xFF, padlen
- 3);
91 (void) memset(padbuf
+ 2, 0xFF, padlen
- 3);
99 padbuf
[padlen
- 1] = 0x00;
101 bcopy(databuf
, padbuf
+ padlen
, datalen
);
107 * The RSA PKCS Padding in the following format:
108 * +----+----+-------------------------+----+------------------------+
109 * |0x00| BT | 8 bytes or more padding |0x00| DATA |
110 * +----+----+-+++++-------------------+----+------------------------+
111 * where BT is block type: 0x02 for encrypt/decrypt, 0x01 for sign/verify
113 * 'padbuf' points to the recovered message. Strip off the padding and
114 * validate it as much as possible. 'plen' is changed to hold the actual
118 pkcs1_decode(int method
, uint8_t *padbuf
, size_t *plen
)
120 int rv
= ((method
== PKCS1_DECRYPT
) ? CKR_ENCRYPTED_DATA_INVALID
:
121 CKR_SIGNATURE_INVALID
);
124 /* Check to see if the recovered data is padded is 0x0002 or 0x0001. */
125 if (padbuf
[0] != 0x00 || padbuf
[1] != (method
== PKCS1_DECRYPT
?
130 /* Remove all the random bits up to 0x00 (= NULL char) */
131 for (i
= 2; (*plen
- i
) > 0; i
++) {
132 if (padbuf
[i
] == 0x00) {
134 if (i
< MIN_PKCS1_PADLEN
) {
140 } else if (method
== PKCS1_VERIFY
&& padbuf
[i
] != 0xFF) {