rsa_impl.c revision 7b79d84636ec82b45f00c982cf6810db81852d17
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file contains RSA helper routines common to
* the PKCS11 soft token code and the kernel RSA code.
*/
#include "rsa_impl.h"
#ifdef _KERNEL
#else
#include <strings.h>
#include <cryptoutil.h>
#include "softRandom.h"
#endif
/*
* DER encoding T of the DigestInfo values for MD5, SHA1, and SHA2
* from PKCS#1 v2.1: RSA Cryptography Standard Section 9.2 Note 1
*
* MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H
* SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H
* SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H.
* SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H.
* SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H.
*
* Where H is the digested output from MD5 or SHA1. We define the constant
* byte array (the prefix) here and use it rather than doing the DER
* encoding of the OID in a separate routine.
*/
0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
0x04, 0x10};
0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14};
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20};
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
0x00, 0x04, 0x30};
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40};
/* psize and qsize are in bits */
{
/* EXPORT DELETE START */
return (err);
goto ret1;
goto ret2;
goto ret3;
goto ret4;
goto ret5;
goto ret6;
goto ret7;
goto ret8;
goto ret9;
goto ret10;
return (BIG_OK);
ret9:
ret8:
ret7:
ret6:
ret5:
big_finish(&(key->e));
ret4:
big_finish(&(key->d));
ret3:
big_finish(&(key->n));
ret2:
big_finish(&(key->q));
ret1:
big_finish(&(key->p));
/* EXPORT DELETE END */
return (err);
}
void
{
/* EXPORT DELETE START */
big_finish(&(key->e));
big_finish(&(key->d));
big_finish(&(key->n));
big_finish(&(key->q));
big_finish(&(key->p));
/* EXPORT DELETE END */
}
/*
* To create a block type "02" encryption block for RSA PKCS encryption
* process.
*
* The RSA PKCS Padding before encryption is in the following format:
* +------+--------------------+----+-----------------------------+
* |0x0002| 8 bytes or more RN |0x00| DATA |
* +------+--------------------+----+-----------------------------+
*
*/
{
/* EXPORT DELETE START */
if (padlen < MIN_PKCS1_PADLEN) {
return (CKR_DATA_LEN_RANGE);
}
/* Pad with 0x0002+non-zero pseudorandom numbers+0x00. */
padbuf[0] = 0x00;
#ifdef _KERNEL
#else
#endif
return (rv);
}
/* EXPORT DELETE END */
return (CKR_OK);
}
/*
* The RSA PKCS Padding after decryption is in the following format:
* +------+--------------------+----+-----------------------------+
* |0x0002| 8 bytes or more RN |0x00| DATA |
* +------+--------------------+----+-----------------------------+
*
* 'padbuf' points to the recovered message which is the modulus
* length. As a result, 'plen' is changed to hold the actual data length.
*/
{
/* EXPORT DELETE START */
int i;
/* Check to see if the recovered data is padded is 0x0002. */
return (CKR_ENCRYPTED_DATA_INVALID);
}
/* Remove all the random bits up to 0x00 (= NULL char) */
for (i = 2; (*plen - i) > 0; i++) {
if (padbuf[i] == 0x00) {
i++;
if (i < MIN_PKCS1_PADLEN) {
return (CKR_ENCRYPTED_DATA_INVALID);
}
*plen -= i;
return (CKR_OK);
}
}
/* EXPORT DELETE END */
return (CKR_ENCRYPTED_DATA_INVALID);
}
/*
* To create a block type "01" block for RSA PKCS signature process.
*
* The RSA PKCS Padding before Signing is in the following format:
* +------+--------------+----+-----------------------------+
* |0x0001| 0xFFFF.......|0x00| DATA |
* +------+--------------+----+-----------------------------+
*/
{
/* EXPORT DELETE START */
if (padlen < MIN_PKCS1_PADLEN) {
return (CKR_DATA_LEN_RANGE);
}
padlen -= 3;
data[0] = 0x00;
#ifdef _KERNEL
#else
#endif
/* EXPORT DELETE END */
return (CKR_OK);
}
{
/* EXPORT DELETE START */
int i;
/* Check to see if the padding of recovered data starts with 0x0001. */
return (CKR_SIGNATURE_INVALID);
}
/* Check to see if the recovered data is padded with 0xFFF...00. */
for (i = 2; i < *mbit_l; i++) {
if (data[i] == 0x00) {
i++;
if (i < MIN_PKCS1_PADLEN) {
return (CKR_SIGNATURE_INVALID);
}
*mbit_l -= i;
return (CKR_OK);
} else if (data[i] != 0xFF) {
return (CKR_SIGNATURE_INVALID);
}
}
/* EXPORT DELETE END */
return (CKR_SIGNATURE_INVALID);
}