softRSA.c revision f66d273d14eede3a1bb803a39414588d8f143a98
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <security/cryptoki.h>
#include <bignum.h>
#include "softGlobal.h"
#include "softSession.h"
#include "softObject.h"
#include "softOps.h"
#include "softRSA.h"
#include "softMAC.h"
#include "softRandom.h"
#include "softCrypt.h"
{
/* EXPORT DELETE START */
if (realpublic) {
&expo_len);
goto clean1;
}
} else {
&expo_len);
goto clean1;
}
}
goto clean1;
}
if (expo_len > modulus_len) {
goto clean1;
}
goto clean1;
}
goto clean4;
}
/* Size for big_init is in (32-bit) words. */
goto clean5;
}
/* Convert octet string exponent to big integer format. */
/* Convert octet string modulus to big integer format. */
/* Convert octet string input data to big integer format. */
goto clean6;
}
/* Perform RSA computation on big integer input data. */
BIG_OK) {
goto clean6;
}
/* Convert the big integer output data to octet string. */
big_finish(&msg);
/* EXPORT DELETE END */
return (rv);
}
{
/* EXPORT DELETE START */
goto clean1;
}
goto clean1;
} else {
goto clean1;
}
goto clean1;
} else {
goto clean1;
}
goto clean1;
} else {
goto clean1;
}
goto clean1;
} else {
goto clean1;
}
goto clean1;
} else {
goto clean1;
}
goto clean1;
}
/* psize and qsize for RSA_key_init is in bits. */
goto clean8;
}
/* Size for big_init is in (32-bit) words. */
goto clean9;
}
/* Convert octet string input data to big integer format. */
/* Convert octet string modulus to big integer format. */
goto clean10;
}
/* Convert the rest of private key attributes to big integer format. */
goto clean10;
}
/* Perform RSA computation on big integer input data. */
goto clean10;
}
/* Convert the big integer output data to octet string. */
big_finish(&msg);
/* EXPORT DELETE END */
return (rv);
}
/*
* Allocate a RSA context for the active encryption or decryption operation.
* This function is called without the session lock held.
*/
{
return (CKR_HOST_MEMORY);
}
/*
* Make a copy of the encryption or decryption key, and save it
* in the RSA crypto context since it will be used later for
* encryption/decryption. We don't want to hold any object reference
* on this original key while doing encryption/decryption.
*/
NULL);
/* Most likely we ran out of space. */
return (rv);
}
/* No need to hold the lock on the old object. */
if (encrypt) {
/* Called by C_EncryptInit. */
} else {
/* Called by C_DecryptInit. */
}
return (CKR_OK);
}
{
goto clean_exit;
}
if (pEncrypted == NULL) {
/*
* Application asks for the length of the output buffer
* to hold the ciphertext.
*/
goto clean1;
}
if (mechanism == CKM_RSA_PKCS) {
/*
* Input data length needs to be <=
* modulus length-MIN_PKCS1_PADLEN.
*/
goto clean_exit;
}
} else {
/* Input data length needs to be <= modulus length. */
goto clean_exit;
}
}
/* Is the application-supplied buffer large enough? */
goto clean1;
}
if (mechanism == CKM_RSA_PKCS) {
/*
* Add PKCS padding to the input data to format a block
* type "02" encryption block.
*/
goto clean_exit;
} else {
/* Pad zeros for the leading bytes of the input data. */
}
}
return (rv);
}
{
goto clean_exit;
}
goto clean_exit;
}
/*
* Application asks for the length of the output buffer
* to hold the recovered data.
*/
goto clean1;
}
if (mechanism == CKM_RSA_X_509) {
goto clean1;
}
}
goto clean_exit;
}
if (mechanism == CKM_RSA_PKCS) {
int plain_len = modulus_len;
/* Strip off the PKCS block formatting data. */
goto clean_exit;
*pulDataLen = plain_len;
goto clean1;
}
*pulDataLen = plain_len;
} else {
}
return (rv);
}
/*
* Allocate a RSA context for the active sign or verify operation.
* This function is called without the session lock held.
*/
{
if (sign) {
return (CKR_KEY_TYPE_INCONSISTENT);
} else {
return (CKR_KEY_TYPE_INCONSISTENT);
}
switch (pMechanism->mechanism) {
case CKM_MD5_RSA_PKCS:
return (rv);
break;
case CKM_SHA1_RSA_PKCS:
return (rv);
break;
case CKM_SHA256_RSA_PKCS:
return (rv);
break;
case CKM_SHA384_RSA_PKCS:
return (rv);
break;
case CKM_SHA512_RSA_PKCS:
return (rv);
break;
}
goto clean_exit;
}
NULL);
/* Most likely we ran out of space. */
goto clean_exit;
}
/* No need to hold the lock on the old object. */
if (sign) {
} else {
}
return (CKR_OK);
}
return (rv);
}
{
goto clean_exit;
}
/* Application asks for the length of the output buffer. */
goto clean1;
}
switch (mechanism) {
case CKM_RSA_PKCS:
/*
* Input data length needs to be <=
* modulus length-MIN_PKCS1_PADLEN.
*/
goto clean_exit;
}
break;
case CKM_RSA_X_509:
/* Input data length needs to be <= modulus length. */
goto clean_exit;
}
break;
}
/* Is the application-supplied buffer large enough? */
goto clean1;
}
switch (mechanism) {
case CKM_RSA_PKCS:
case CKM_MD5_RSA_PKCS:
case CKM_SHA1_RSA_PKCS:
case CKM_SHA256_RSA_PKCS:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA512_RSA_PKCS:
/*
* Add PKCS padding to the input data to format a block
* type "01" encryption block.
*/
goto clean_exit;
}
break;
case CKM_RSA_X_509:
/* Pad zeros for the leading bytes of the input data. */
break;
}
/*
* Perform RSA encryption with the signer's RSA private key
* for signature process.
*/
}
}
return (rv);
}
{
goto clean_exit;
}
goto clean_exit;
}
/*
* Perform RSA decryption with the signer's RSA public key
* for verification process.
*/
switch (mechanism) {
case CKM_RSA_PKCS:
case CKM_MD5_RSA_PKCS:
case CKM_SHA1_RSA_PKCS:
case CKM_SHA256_RSA_PKCS:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA512_RSA_PKCS:
{
/*
* Strip off the encoded padding bytes in front of the
* recovered data, then compare the recovered data with
* the original data.
*/
int data_len = modulus_len;
goto clean_exit;
}
goto clean_exit;
ulDataLen) != 0) {
goto clean_exit;
}
break;
}
case CKM_RSA_X_509:
/*
* Strip off the encoded padding bytes in front of the
* recovered plain_data, then compare the input data
* with the recovered data.
*/
ulDataLen) != 0) {
goto clean_exit;
}
break;
}
}
if (rv == CKR_DATA_LEN_RANGE) {
if ((mechanism == CKM_MD5_RSA_PKCS) ||
(mechanism == CKM_SHA1_RSA_PKCS) ||
(mechanism == CKM_SHA256_RSA_PKCS) ||
(mechanism == CKM_SHA384_RSA_PKCS) ||
(mechanism == CKM_SHA512_RSA_PKCS))
}
}
return (rv);
}
{
/*
* Allocate the buffer used to store the value of key fields
* for bignum2bytestring. Since bignum only deals with a buffer
* whose size is multiple of 4, modulus_len is rounded up to be
* multiple of 4.
*/
goto cleanexit;
}
switch (type) {
case CKA_MODULUS:
if (public)
else
break;
case CKA_PUBLIC_EXPONENT:
if (public)
else
break;
case CKA_PRIVATE_EXPONENT:
break;
case CKA_PRIME_1:
break;
case CKA_PRIME_2:
break;
case CKA_EXPONENT_1:
break;
case CKA_EXPONENT_2:
break;
case CKA_COEFFICIENT:
break;
}
while (buf[0] == 0) { /* remove proceeding 0x00 */
buf++;
buflen--;
}
goto cleanexit;
}
/* Copy the attribute in the key object. */
return (rv);
}
{
/* EXPORT DELETE START */
BIGNUM a, b, c, d, e, f, g, h;
a.malloced = 0;
b.malloced = 0;
c.malloced = 0;
d.malloced = 0;
e.malloced = 0;
f.malloced = 0;
g.malloced = 0;
h.malloced = 0;
big_finish(&h);
big_finish(&g);
big_finish(&f);
big_finish(&e);
big_finish(&d);
big_finish(&c);
big_finish(&b);
big_finish(&a);
return (CKR_HOST_MEMORY);
}
goto ret;
}
goto ret;
}
(void) big_sub_pos(&a, &b, &One);
goto ret;
}
if (big_cmp_abs(&f, &One) != 0) {
goto nextp;
}
goto ret;
}
if (big_bitlength(&a) != qsize) {
goto nextp;
}
if (big_cmp_abs(&a, &b) == 0) {
goto nextp;
}
goto ret;
}
goto ret;
}
if (big_bitlength(&g) != size) {
goto nextp;
}
(void) big_sub_pos(&a, &b, &One);
(void) big_sub_pos(&d, &c, &One);
goto ret;
}
goto ret;
}
if (big_cmp_abs(&f, &One) != 0) {
goto nextq;
} else {
}
if (d.sign == -1) {
goto ret;
}
}
goto ret;
}
if (f.sign == -1) {
goto ret;
}
}
goto ret;
}
goto ret;
}
goto ret;
}
goto ret;
}
goto ret;
}
goto ret;
}
if (big_cmp_abs(&b, &h) != 0) {
goto ret1;
} else {
}
ret:
ret1:
big_finish(&h);
big_finish(&g);
big_finish(&f);
big_finish(&e);
big_finish(&d);
big_finish(&c);
big_finish(&b);
big_finish(&a);
/* EXPORT DELETE END */
return (rv);
}
{
BIGNUM public_exponent = {0};
return (CKR_ARGUMENTS_BAD);
}
return (CKR_HOST_MEMORY);
}
&template);
goto clean0;
}
#ifdef __sparcv9
/* LINTED */
#else /* !__sparcv9 */
#endif /* __sparcv9 */
/* Convert modulus length from bit length to byte length. */
/* Modulus length needs to be between min key size and max key size. */
if ((modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES) ||
goto clean0;
}
&pub_expo_len);
goto clean0;
}
/* Create a public exponent in bignum format. */
goto clean0;
}
goto clean2;
}
/* Generate RSA key pair. */
goto clean3;
}
/*
* Add modulus in public template, and add all eight key fields
* in private template.
*/
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
goto clean3;
}
return (rv);
}
{
/* space enough for all mechs */
goto clean1;
}
/* Check arguments before performing message digest. */
/* Application asks for the length of the output buffer. */
goto clean1;
}
/* Is the application-supplied buffer large enough? */
goto clean1;
}
if (Final) {
} else {
}
/* free the signature key */
goto clean_exit;
}
/*
* Prepare the DER encoding of the DigestInfo value as follows:
* MD5: MD5_DER_PREFIX || H
* SHA-1: SHA1_DER_PREFIX || H
* SHA2: SHA2_DER_PREFIX || H
*
* See rsa_impl.c for more details.
*/
case CKM_MD5:
break;
case CKM_SHA_1:
break;
case CKM_SHA256:
break;
case CKM_SHA384:
break;
case CKM_SHA512:
break;
}
/*
* Now, we are ready to sign the DER_ENCODED data
* soft_rsa_sign_common() will free the signature key.
*/
/* soft_digest_common() has freed the digest context */
return (rv);
}
{
if (Final) {
} else {
}
/* free the verification key */
goto clean_exit;
}
/*
* Prepare the DER encoding of the DigestInfo value as follows:
* MD5: MD5_DER_PREFIX || H
* SHA-1: SHA1_DER_PREFIX || H
* SHA2: SHA2_DER_PREFIX || H
*
* See rsa_impl.c for more details.
*/
case CKM_MD5:
break;
case CKM_SHA_1:
break;
case CKM_SHA256:
break;
case CKM_SHA384:
break;
case CKM_SHA512:
break;
}
/*
* Now, we are ready to verify the DER_ENCODED data using signature.
* soft_rsa_verify_common() will free the verification key.
*/
/* soft_digest_common() has freed the digest context */
return (rv);
}
{
goto clean_exit;
}
goto clean_exit;
}
/*
* Perform RSA decryption with the signer's RSA public key
* for verification process.
*/
switch (mechanism) {
case CKM_RSA_PKCS:
{
/*
* Strip off the encoded padding bytes in front of the
* recovered data.
*/
int data_len = modulus_len;
goto clean_exit;
}
/*
* If application asks for the length of the output
* buffer?
*/
*pulDataLen = data_len;
goto clean1;
}
/* Is the application-supplied buffer large enough? */
*pulDataLen = data_len;
goto clean1;
}
*pulDataLen = data_len;
break;
}
case CKM_RSA_X_509:
/*
* If application asks for the length of the output
* buffer?
*/
goto clean1;
}
/* Is the application-supplied buffer large enough? */
goto clean1;
}
break;
}
}
return (rv);
}