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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * This file contains RSA helper routines common to 31 * the PKCS11 soft token code and the kernel RSA code. 32 */ 33 34 #include <sys/types.h> 35 #include "rsa_impl.h" 36 37 #ifdef _KERNEL 38 #include <sys/param.h> 39 #else 40 #include <strings.h> 41 #include "softRandom.h" 42 #endif 43 44 /* 45 * DER encoding T of the DigestInfo values for MD5 and SHA1 46 * from PKCS#1 v2.1: RSA Cryptography Standard Section 9.2 Note 1 47 * 48 * MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H 49 * SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H 50 * 51 * Where H is the digested output from MD5 or SHA1. We define the constant 52 * byte array (the prefix) here and use it rather than doing the DER 53 * encoding of the OID in a separate routine. 54 */ 55 const CK_BYTE MD5_DER_PREFIX[MD5_DER_PREFIX_Len] = {0x30, 0x20, 0x30, 0x0c, 56 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 57 0x04, 0x10}; 58 59 const CK_BYTE SHA1_DER_PREFIX[SHA1_DER_PREFIX_Len] = {0x30, 0x21, 0x30, 60 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; 61 62 BIG_ERR_CODE 63 RSA_key_init(RSAkey *key, int psize, int qsize) 64 { 65 BIG_ERR_CODE err = BIG_OK; 66 67 /* EXPORT DELETE START */ 68 69 int plen, qlen, nlen; 70 71 plen = (psize + 31) / 32; 72 qlen = (qsize + 31) / 32; 73 nlen = plen + qlen; 74 key->size = psize + qsize; 75 if ((err = big_init(&(key->p), plen)) != BIG_OK) 76 return (err); 77 if ((err = big_init(&(key->q), qlen)) != BIG_OK) 78 goto ret1; 79 if ((err = big_init(&(key->n), nlen)) != BIG_OK) 80 goto ret2; 81 if ((err = big_init(&(key->d), nlen)) != BIG_OK) 82 goto ret3; 83 if ((err = big_init(&(key->e), nlen)) != BIG_OK) 84 goto ret4; 85 if ((err = big_init(&(key->dmodpminus1), plen)) != BIG_OK) 86 goto ret5; 87 if ((err = big_init(&(key->dmodqminus1), qlen)) != BIG_OK) 88 goto ret6; 89 if ((err = big_init(&(key->pinvmodq), qlen)) != BIG_OK) 90 goto ret7; 91 if ((err = big_init(&(key->p_rr), plen)) != BIG_OK) 92 goto ret8; 93 if ((err = big_init(&(key->q_rr), qlen)) != BIG_OK) 94 goto ret9; 95 if ((err = big_init(&(key->n_rr), nlen)) != BIG_OK) 96 goto ret10; 97 98 return (BIG_OK); 99 100 ret10: 101 big_finish(&(key->q_rr)); 102 ret9: 103 big_finish(&(key->p_rr)); 104 ret8: 105 big_finish(&(key->pinvmodq)); 106 ret7: 107 big_finish(&(key->dmodqminus1)); 108 ret6: 109 big_finish(&(key->dmodpminus1)); 110 ret5: 111 big_finish(&(key->e)); 112 ret4: 113 big_finish(&(key->d)); 114 ret3: 115 big_finish(&(key->n)); 116 ret2: 117 big_finish(&(key->q)); 118 ret1: 119 big_finish(&(key->p)); 120 121 /* EXPORT DELETE END */ 122 123 return (err); 124 } 125 126 127 void 128 RSA_key_finish(RSAkey *key) 129 { 130 131 /* EXPORT DELETE START */ 132 133 big_finish(&(key->n_rr)); 134 big_finish(&(key->q_rr)); 135 big_finish(&(key->p_rr)); 136 big_finish(&(key->pinvmodq)); 137 big_finish(&(key->dmodqminus1)); 138 big_finish(&(key->dmodpminus1)); 139 big_finish(&(key->e)); 140 big_finish(&(key->d)); 141 big_finish(&(key->n)); 142 big_finish(&(key->q)); 143 big_finish(&(key->p)); 144 145 /* EXPORT DELETE END */ 146 147 } 148 149 150 /* 151 * To create a block type "02" encryption block for RSA PKCS encryption 152 * process. 153 * 154 * The RSA PKCS Padding before encryption is in the following format: 155 * +------+--------------------+----+-----------------------------+ 156 * |0x0002| 8 bytes or more RN |0x00| DATA | 157 * +------+--------------------+----+-----------------------------+ 158 * 159 */ 160 CK_RV 161 soft_encrypt_rsa_pkcs_encode(uint8_t *databuf, 162 size_t datalen, uint8_t *padbuf, size_t padbuflen) 163 { 164 165 /* EXPORT DELETE START */ 166 167 size_t padlen; 168 CK_RV rv; 169 170 padlen = padbuflen - datalen; 171 if (padlen < MIN_PKCS1_PADLEN) { 172 return (CKR_DATA_LEN_RANGE); 173 } 174 175 /* Pad with 0x0002+non-zero pseudorandom numbers+0x00. */ 176 padbuf[0] = 0x00; 177 padbuf[1] = 0x02; 178 #ifdef _KERNEL 179 rv = knzero_random_generator(padbuf + 2, padbuflen - 3); 180 #else 181 rv = soft_nzero_random_generator(padbuf + 2, padbuflen - 3); 182 #endif 183 if (rv != CKR_OK) { 184 return (rv); 185 } 186 padbuf[padlen - 1] = 0x00; 187 188 bcopy(databuf, padbuf + padlen, datalen); 189 190 /* EXPORT DELETE END */ 191 192 return (CKR_OK); 193 } 194 195 196 /* 197 * The RSA PKCS Padding after decryption is in the following format: 198 * +------+--------------------+----+-----------------------------+ 199 * |0x0002| 8 bytes or more RN |0x00| DATA | 200 * +------+--------------------+----+-----------------------------+ 201 * 202 * 'padbuf' points to the recovered message which is the modulus 203 * length. As a result, 'plen' is changed to hold the actual data length. 204 */ 205 CK_RV 206 soft_decrypt_rsa_pkcs_decode(uint8_t *padbuf, int *plen) 207 { 208 209 /* EXPORT DELETE START */ 210 211 int i; 212 213 /* Check to see if the recovered data is padded is 0x0002. */ 214 if (padbuf[0] != 0x00 || padbuf[1] != 0x02) { 215 return (CKR_ENCRYPTED_DATA_INVALID); 216 } 217 218 /* Remove all the random bits up to 0x00 (= NULL char) */ 219 for (i = 2; (*plen - i) > 0; i++) { 220 if (padbuf[i] == 0x00) { 221 i++; 222 if (i < MIN_PKCS1_PADLEN) { 223 return (CKR_ENCRYPTED_DATA_INVALID); 224 } 225 *plen -= i; 226 227 return (CKR_OK); 228 } 229 } 230 231 /* EXPORT DELETE END */ 232 233 return (CKR_ENCRYPTED_DATA_INVALID); 234 } 235 236 /* 237 * To create a block type "01" block for RSA PKCS signature process. 238 * 239 * The RSA PKCS Padding before Signing is in the following format: 240 * +------+--------------+----+-----------------------------+ 241 * |0x0001| 0xFFFF.......|0x00| DATA | 242 * +------+--------------+----+-----------------------------+ 243 */ 244 CK_RV 245 soft_sign_rsa_pkcs_encode(uint8_t *pData, size_t dataLen, uint8_t *data, 246 size_t mbit_l) 247 { 248 249 /* EXPORT DELETE START */ 250 251 size_t padlen; 252 253 padlen = mbit_l - dataLen; 254 if (padlen < MIN_PKCS1_PADLEN) { 255 return (CKR_DATA_LEN_RANGE); 256 } 257 258 padlen -= 3; 259 data[0] = 0x00; 260 data[1] = 0x01; 261 #ifdef _KERNEL 262 kmemset(data + 2, 0xFF, padlen); 263 #else 264 (void) memset(data + 2, 0xFF, padlen); 265 #endif 266 data[padlen + 2] = 0x00; 267 bcopy(pData, data + padlen + 3, dataLen); 268 269 /* EXPORT DELETE END */ 270 271 return (CKR_OK); 272 } 273 274 275 CK_RV 276 soft_verify_rsa_pkcs_decode(uint8_t *data, int *mbit_l) 277 { 278 279 /* EXPORT DELETE START */ 280 281 int i; 282 283 /* Check to see if the padding of recovered data starts with 0x0001. */ 284 if ((data[0] != 0x00) || (data[1] != 0x01)) { 285 return (CKR_SIGNATURE_INVALID); 286 } 287 /* Check to see if the recovered data is padded with 0xFFF...00. */ 288 for (i = 2; i < *mbit_l; i++) { 289 if (data[i] == 0x00) { 290 i++; 291 if (i < MIN_PKCS1_PADLEN) { 292 return (CKR_SIGNATURE_INVALID); 293 } 294 *mbit_l -= i; 295 296 return (CKR_OK); 297 } else if (data[i] != 0xFF) { 298 return (CKR_SIGNATURE_INVALID); 299 } 300 } 301 302 /* EXPORT DELETE END */ 303 304 return (CKR_SIGNATURE_INVALID); 305 } 306