summaryrefslogtreecommitdiff
path: root/usr/src/common/crypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common/crypto/rsa')
-rw-r--r--usr/src/common/crypto/rsa/rsa_impl.c545
-rw-r--r--usr/src/common/crypto/rsa/rsa_impl.h101
2 files changed, 491 insertions, 155 deletions
diff --git a/usr/src/common/crypto/rsa/rsa_impl.c b/usr/src/common/crypto/rsa/rsa_impl.c
index 220fe0be83..f6e637fe68 100644
--- a/usr/src/common/crypto/rsa/rsa_impl.c
+++ b/usr/src/common/crypto/rsa/rsa_impl.c
@@ -18,9 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -29,16 +29,18 @@
*/
#include <sys/types.h>
-#include "rsa_impl.h"
+#include <bignum.h>
#ifdef _KERNEL
#include <sys/param.h>
#else
#include <strings.h>
#include <cryptoutil.h>
-#include "softRandom.h"
#endif
+#include <sys/crypto/common.h>
+#include "rsa_impl.h"
+
/*
* 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
@@ -77,8 +79,32 @@ const CK_BYTE SHA512_DER_PREFIX[SHA2_DER_PREFIX_Len] = {0x30, 0x51, 0x30, 0x0d,
const CK_BYTE DEFAULT_PUB_EXPO[DEFAULT_PUB_EXPO_Len] = { 0x01, 0x00, 0x01 };
+
+static CK_RV
+convert_rv(BIG_ERR_CODE err)
+{
+ switch (err) {
+
+ case BIG_OK:
+ return (CKR_OK);
+
+ case BIG_NO_MEM:
+ return (CKR_HOST_MEMORY);
+
+ case BIG_NO_RANDOM:
+ return (CKR_DEVICE_ERROR);
+
+ case BIG_INVALID_ARGS:
+ return (CKR_ARGUMENTS_BAD);
+
+ case BIG_DIV_BY_0:
+ default:
+ return (CKR_GENERAL_ERROR);
+ }
+}
+
/* psize and qsize are in bits */
-BIG_ERR_CODE
+static BIG_ERR_CODE
RSA_key_init(RSAkey *key, int psize, int qsize)
{
BIG_ERR_CODE err = BIG_OK;
@@ -142,8 +168,7 @@ ret1:
return (err);
}
-
-void
+static void
RSA_key_finish(RSAkey *key)
{
@@ -165,162 +190,472 @@ RSA_key_finish(RSAkey *key)
}
-
/*
- * 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 |
- * +------+--------------------+----+-----------------------------+
- *
+ * Generate RSA key
*/
-CK_RV
-soft_encrypt_rsa_pkcs_encode(uint8_t *databuf,
- size_t datalen, uint8_t *padbuf, size_t padbuflen)
+static CK_RV
+generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM *pubexp,
+ int (*rfunc)(void *, size_t))
{
+ CK_RV rv = CKR_OK;
/* EXPORT DELETE START */
- size_t padlen;
- CK_RV rv;
-
- padlen = padbuflen - datalen;
- if (padlen < MIN_PKCS1_PADLEN) {
- return (CKR_DATA_LEN_RANGE);
+ int (*rf)(void *, size_t);
+ BIGNUM a, b, c, d, e, f, g, h;
+ int len, keylen, size;
+ BIG_ERR_CODE brv = BIG_OK;
+
+ size = psize + qsize;
+ keylen = BITLEN2BIGNUMLEN(size);
+ len = keylen * 2 + 1;
+ key->size = size;
+
+ /*
+ * Note: It is not really necessary to compute e, it is in pubexp:
+ * (void) big_copy(&(key->e), pubexp);
+ */
+
+ a.malloced = 0;
+ b.malloced = 0;
+ c.malloced = 0;
+ d.malloced = 0;
+ e.malloced = 0;
+ f.malloced = 0;
+ g.malloced = 0;
+ h.malloced = 0;
+
+ if ((big_init(&a, len) != BIG_OK) ||
+ (big_init(&b, len) != BIG_OK) ||
+ (big_init(&c, len) != BIG_OK) ||
+ (big_init(&d, len) != BIG_OK) ||
+ (big_init(&e, len) != BIG_OK) ||
+ (big_init(&f, len) != BIG_OK) ||
+ (big_init(&g, len) != BIG_OK) ||
+ (big_init(&h, len) != BIG_OK)) {
+ 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);
}
- /* Pad with 0x0002+non-zero pseudorandom numbers+0x00. */
- padbuf[0] = 0x00;
- padbuf[1] = 0x02;
+ rf = rfunc;
+ if (rf == NULL) {
#ifdef _KERNEL
- rv = knzero_random_generator(padbuf + 2, padbuflen - 3);
+ rf = (int (*)(void *, size_t))random_get_pseudo_bytes;
#else
- rv = CKR_OK;
- if (pkcs11_get_nzero_urandom(padbuf + 2, padbuflen - 3) < 0)
- rv = CKR_DEVICE_ERROR;
+ rf = pkcs11_get_urandom;
#endif
- if (rv != CKR_OK) {
- return (rv);
}
- padbuf[padlen - 1] = 0x00;
- bcopy(databuf, padbuf + padlen, datalen);
+nextp:
+ if ((brv = big_random(&a, psize, rf)) != BIG_OK) {
+ goto ret;
+ }
+
+ if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
+ goto ret;
+ }
+ /* b now contains the potential prime p */
+
+ (void) big_sub_pos(&a, &b, &big_One);
+ if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
+ goto ret;
+ }
+ if (big_cmp_abs(&f, &big_One) != 0) {
+ goto nextp;
+ }
+
+ if ((brv = big_random(&c, qsize, rf)) != BIG_OK) {
+ goto ret;
+ }
+
+nextq:
+ (void) big_add(&a, &c, &big_Two);
+
+ if (big_bitlength(&a) != qsize) {
+ goto nextp;
+ }
+ if (big_cmp_abs(&a, &b) == 0) {
+ goto nextp;
+ }
+ if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
+ goto ret;
+ }
+ /* c now contains the potential prime q */
+
+ if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
+ goto ret;
+ }
+ if (big_bitlength(&g) != size) {
+ goto nextp;
+ }
+ /* g now contains the potential modulus n */
+
+ (void) big_sub_pos(&a, &b, &big_One);
+ (void) big_sub_pos(&d, &c, &big_One);
+
+ if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
+ goto ret;
+ }
+ if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
+ goto ret;
+ }
+ if (big_cmp_abs(&f, &big_One) != 0) {
+ goto nextq;
+ } else {
+ (void) big_copy(&e, pubexp);
+ }
+ if (d.sign == -1) {
+ if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
+ goto ret;
+ }
+ }
+ (void) big_copy(&(key->p), &b);
+ (void) big_copy(&(key->q), &c);
+ (void) big_copy(&(key->n), &g);
+ (void) big_copy(&(key->d), &d);
+ (void) big_copy(&(key->e), &e);
+
+ if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
+ goto ret;
+ }
+ if (f.sign == -1) {
+ if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
+ goto ret;
+ }
+ }
+ (void) big_copy(&(key->pinvmodq), &f);
+
+ (void) big_sub(&a, &b, &big_One);
+ if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
+ goto ret;
+ }
+ (void) big_copy(&(key->dmodpminus1), &f);
+ (void) big_sub(&a, &c, &big_One);
+ if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
+ goto ret;
+ }
+ (void) big_copy(&(key->dmodqminus1), &f);
+
+ /* pairwise consistency check: decrypt and encrypt restores value */
+ if ((brv = big_random(&h, size, rf)) != BIG_OK) {
+ goto ret;
+ }
+ if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
+ goto ret;
+ }
+ if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
+ goto ret;
+ }
+
+ if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
+ goto ret;
+ }
+
+ if (big_cmp_abs(&b, &h) != 0) {
+ /* this should not happen */
+ rv = generate_rsa_key(key, psize, qsize, pubexp, rf);
+ goto ret1;
+ } else {
+ brv = BIG_OK;
+ }
+
+ret:
+ rv = convert_rv(brv);
+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 (CKR_OK);
+ return (rv);
}
-
-/*
- * 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.
- */
CK_RV
-soft_decrypt_rsa_pkcs_decode(uint8_t *padbuf, int *plen)
+rsa_genkey_pair(RSAbytekey *bkey)
{
+ /*
+ * NOTE: Whomever originally wrote this function swapped p and q.
+ * This table shows the mapping between name convention used here
+ * versus what is used in most texts that describe RSA key generation.
+ * This function: Standard convention:
+ * -------------- --------------------
+ * modulus, n -same-
+ * prime 1, q prime 1, p
+ * prime 2, p prime 2, q
+ * private exponent, d -same-
+ * public exponent, e -same-
+ * exponent 1, d mod (q-1) d mod (p-1)
+ * exponent 2, d mod (p-1) d mod (q-1)
+ * coefficient, p^-1 mod q q^-1 mod p
+ *
+ * Also notice the struct member for coefficient is named .pinvmodq
+ * rather than .qinvmodp, reflecting the switch.
+ *
+ * The code here wasn't unswapped, because "it works". Further,
+ * p and q are interchangeable as long as exponent 1 and 2 and
+ * the coefficient are kept straight too. This note is here to
+ * make the reader aware of the switcheroo.
+ */
+ CK_RV rv = CKR_OK;
/* EXPORT DELETE START */
- int i;
+ BIGNUM public_exponent = {0};
+ RSAkey rsakey;
+ uint32_t modulus_bytes;
+
+ if (bkey == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* Must have modulus bits set */
+ if (bkey->modulus_bits == 0)
+ return (CKR_ARGUMENTS_BAD);
- /* Check to see if the recovered data is padded is 0x0002. */
- if (padbuf[0] != 0x00 || padbuf[1] != 0x02) {
- return (CKR_ENCRYPTED_DATA_INVALID);
+ /* Must have public exponent set */
+ if (bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+ modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+ /* Modulus length needs to be between min key size and max key size. */
+ if ((modulus_bytes < MIN_RSA_KEYLENGTH_IN_BYTES) ||
+ (modulus_bytes > MAX_RSA_KEYLENGTH_IN_BYTES)) {
+ return (CKR_KEY_SIZE_RANGE);
}
- /* 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;
+ /*
+ * Initialize the RSA key.
+ */
+ if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
+ BIG_OK) {
+ return (CKR_HOST_MEMORY);
+ }
- return (CKR_OK);
- }
+ /* Create a public exponent in bignum format. */
+ if (big_init(&public_exponent,
+ CHARLEN2BIGNUMLEN(bkey->pubexpo_bytes)) != BIG_OK) {
+ rv = CKR_HOST_MEMORY;
+ goto clean1;
+ }
+ bytestring2bignum(&public_exponent, bkey->pubexpo, bkey->pubexpo_bytes);
+
+ /* Generate RSA key pair. */
+ if ((rv = generate_rsa_key(&rsakey,
+ modulus_bytes * 4, modulus_bytes * 4, &public_exponent,
+ bkey->rfunc)) != CKR_OK) {
+ big_finish(&public_exponent);
+ goto clean1;
}
+ big_finish(&public_exponent);
+
+ /* modulus_bytes = rsakey.n.len * (int)sizeof (BIG_CHUNK_TYPE); */
+ bignum2bytestring(bkey->modulus, &(rsakey.n), modulus_bytes);
+
+ bkey->privexpo_bytes = rsakey.d.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->privexpo, &(rsakey.d), bkey->privexpo_bytes);
+
+ bkey->pubexpo_bytes = rsakey.e.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->pubexpo, &(rsakey.e), bkey->pubexpo_bytes);
+
+ bkey->prime1_bytes = rsakey.q.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->prime1, &(rsakey.q), bkey->prime1_bytes);
+
+ bkey->prime2_bytes = rsakey.p.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->prime2, &(rsakey.p), bkey->prime2_bytes);
+
+ bkey->expo1_bytes =
+ rsakey.dmodqminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->expo1, &(rsakey.dmodqminus1),
+ bkey->expo1_bytes);
+
+ bkey->expo2_bytes =
+ rsakey.dmodpminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->expo2,
+ &(rsakey.dmodpminus1), bkey->expo2_bytes);
+
+ bkey->coeff_bytes =
+ rsakey.pinvmodq.len * (int)sizeof (BIG_CHUNK_TYPE);
+ bignum2bytestring(bkey->coeff, &(rsakey.pinvmodq), bkey->coeff_bytes);
+
+clean1:
+ RSA_key_finish(&rsakey);
/* EXPORT DELETE END */
- return (CKR_ENCRYPTED_DATA_INVALID);
+ return (rv);
}
/*
- * 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 |
- * +------+--------------+----+-----------------------------+
+ * RSA encrypt operation
*/
CK_RV
-soft_sign_rsa_pkcs_encode(uint8_t *pData, size_t dataLen, uint8_t *data,
- size_t mbit_l)
+rsa_encrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
{
+ CK_RV rv = CKR_OK;
/* EXPORT DELETE START */
- size_t padlen;
+ BIGNUM msg;
+ RSAkey rsakey;
+ uint32_t modulus_bytes;
+
+ if (bkey == NULL)
+ return (CKR_ARGUMENTS_BAD);
- padlen = mbit_l - dataLen;
- if (padlen < MIN_PKCS1_PADLEN) {
- return (CKR_DATA_LEN_RANGE);
+ /* Must have modulus and public exponent set */
+ if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
+ bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+ modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+ if (bkey->pubexpo_bytes > modulus_bytes) {
+ return (CKR_KEY_SIZE_RANGE);
}
- padlen -= 3;
- data[0] = 0x00;
- data[1] = 0x01;
-#ifdef _KERNEL
- kmemset(data + 2, 0xFF, padlen);
-#else
- (void) memset(data + 2, 0xFF, padlen);
-#endif
- data[padlen + 2] = 0x00;
- bcopy(pData, data + padlen + 3, dataLen);
+ /* psize and qsize for RSA_key_init is in bits. */
+ if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
+ BIG_OK) {
+ return (CKR_HOST_MEMORY);
+ }
+
+ /* Size for big_init is in BIG_CHUNK_TYPE words. */
+ if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
+ rv = CKR_HOST_MEMORY;
+ goto clean2;
+ }
+ bytestring2bignum(&msg, in, in_len);
+
+ /* Convert public exponent and modulus to big integer format. */
+ bytestring2bignum(&(rsakey.e), bkey->pubexpo, bkey->pubexpo_bytes);
+ bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
+
+ if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
+ rv = CKR_DATA_LEN_RANGE;
+ goto clean3;
+ }
+
+ /* Perform RSA computation on big integer input data. */
+ if (big_modexp(&msg, &msg, &(rsakey.e), &(rsakey.n), NULL) !=
+ BIG_OK) {
+ rv = CKR_HOST_MEMORY;
+ goto clean3;
+ }
+
+ /* Convert the big integer output data to octet string. */
+ bignum2bytestring(out, &msg, modulus_bytes);
+
+clean3:
+ big_finish(&msg);
+clean2:
+ RSA_key_finish(&rsakey);
/* EXPORT DELETE END */
- return (CKR_OK);
+ return (rv);
}
-
+/*
+ * RSA decrypt operation
+ */
CK_RV
-soft_verify_rsa_pkcs_decode(uint8_t *data, int *mbit_l)
+rsa_decrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
{
+ CK_RV rv = CKR_OK;
/* EXPORT DELETE START */
- int i;
+ BIGNUM msg;
+ RSAkey rsakey;
+ uint32_t modulus_bytes;
+
+ if (bkey == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* Must have modulus, prime1, prime2, expo1, expo2, and coeff set */
+ if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
+ bkey->prime1_bytes == 0 || bkey->prime1 == NULL ||
+ bkey->prime2_bytes == 0 || bkey->prime2 == NULL ||
+ bkey->expo1_bytes == 0 || bkey->expo1 == NULL ||
+ bkey->expo2_bytes == 0 || bkey->expo2 == NULL ||
+ bkey->coeff_bytes == 0 || bkey->coeff == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+ modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+ /* psize and qsize for RSA_key_init is in bits. */
+ if (RSA_key_init(&rsakey, CRYPTO_BYTES2BITS(bkey->prime2_bytes),
+ CRYPTO_BYTES2BITS(bkey->prime1_bytes)) != BIG_OK) {
+ return (CKR_HOST_MEMORY);
+ }
- /* Check to see if the padding of recovered data starts with 0x0001. */
- if ((data[0] != 0x00) || (data[1] != 0x01)) {
- return (CKR_SIGNATURE_INVALID);
+ /* Size for big_init is in BIG_CHUNK_TYPE words. */
+ if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
+ rv = CKR_HOST_MEMORY;
+ goto clean3;
}
- /* 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;
+ /* Convert octet string input data to big integer format. */
+ bytestring2bignum(&msg, in, in_len);
- return (CKR_OK);
- } else if (data[i] != 0xFF) {
- return (CKR_SIGNATURE_INVALID);
- }
+ /* Convert octet string modulus to big integer format. */
+ bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
+
+ if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
+ rv = CKR_DATA_LEN_RANGE;
+ goto clean4;
}
+ /* Convert the rest of private key attributes to big integer format. */
+ bytestring2bignum(&(rsakey.q), bkey->prime1, bkey->prime1_bytes);
+ bytestring2bignum(&(rsakey.p), bkey->prime2, bkey->prime2_bytes);
+ bytestring2bignum(&(rsakey.dmodqminus1),
+ bkey->expo1, bkey->expo1_bytes);
+ bytestring2bignum(&(rsakey.dmodpminus1),
+ bkey->expo2, bkey->expo2_bytes);
+ bytestring2bignum(&(rsakey.pinvmodq),
+ bkey->coeff, bkey->coeff_bytes);
+
+ if ((big_cmp_abs(&(rsakey.dmodpminus1), &(rsakey.p)) > 0) ||
+ (big_cmp_abs(&(rsakey.dmodqminus1), &(rsakey.q)) > 0) ||
+ (big_cmp_abs(&(rsakey.pinvmodq), &(rsakey.q)) > 0)) {
+ rv = CKR_KEY_SIZE_RANGE;
+ goto clean4;
+ }
+
+ /* Perform RSA computation on big integer input data. */
+ if (big_modexp_crt(&msg, &msg, &(rsakey.dmodpminus1),
+ &(rsakey.dmodqminus1), &(rsakey.p), &(rsakey.q),
+ &(rsakey.pinvmodq), NULL, NULL) != BIG_OK) {
+ rv = CKR_HOST_MEMORY;
+ goto clean4;
+ }
+
+ /* Convert the big integer output data to octet string. */
+ bignum2bytestring(out, &msg, modulus_bytes);
+
+clean4:
+ big_finish(&msg);
+clean3:
+ RSA_key_finish(&rsakey);
+
/* EXPORT DELETE END */
- return (CKR_SIGNATURE_INVALID);
+ return (rv);
}
diff --git a/usr/src/common/crypto/rsa/rsa_impl.h b/usr/src/common/crypto/rsa/rsa_impl.h
index 89a7d49a50..60aba07d72 100644
--- a/usr/src/common/crypto/rsa/rsa_impl.h
+++ b/usr/src/common/crypto/rsa/rsa_impl.h
@@ -18,9 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _RSA_IMPL_H
@@ -38,8 +38,6 @@ extern "C" {
#define RSA_MIN_KEY_LEN 256 /* RSA min key length in bits */
#define RSA_MAX_KEY_LEN 4096 /* RSA max key length in bits */
-#define MIN_PKCS1_PADLEN 11
-
#ifdef _KERNEL
#include <sys/sunddi.h>
@@ -48,12 +46,17 @@ extern "C" {
#define CK_BYTE uchar_t
#define CK_ULONG ulong_t
#define CK_RV int
+
#define CKR_OK CRYPTO_SUCCESS
-#define CKR_HOST_MEMORY CRYPTO_HOST_MEMORY
+#define CKR_ARGUMENTS_BAD CRYPTO_ARGUMENTS_BAD
#define CKR_DATA_LEN_RANGE CRYPTO_DATA_LEN_RANGE
-#define CKR_ENCRYPTED_DATA_INVALID CRYPTO_ENCRYPTED_DATA_INVALID
-#define CKR_SIGNATURE_INVALID CRYPTO_SIGNATURE_INVALID
-#define CKR_FUNCTION_FAILED CRYPTO_NOT_SUPPORTED
+#define CKR_DEVICE_ERROR CRYPTO_DEVICE_ERROR
+#define CKR_GENERAL_ERROR CRYPTO_GENERAL_ERROR
+#define CKR_HOST_MEMORY CRYPTO_HOST_MEMORY
+#define CKR_KEY_SIZE_RANGE CRYPTO_KEY_SIZE_RANGE
+
+int random_get_bytes(uint8_t *ran_out, size_t ran_len);
+int random_get_pseudo_bytes(uint8_t *ran_out, size_t ran_len);
#else
@@ -76,6 +79,8 @@ extern const CK_BYTE SHA384_DER_PREFIX[SHA2_DER_PREFIX_Len];
extern const CK_BYTE SHA512_DER_PREFIX[SHA2_DER_PREFIX_Len];
extern const CK_BYTE DEFAULT_PUB_EXPO[DEFAULT_PUB_EXPO_Len];
+
+/* RSA key using BIGNUM representations */
typedef struct {
int size; /* key size in bits */
BIGNUM p; /* p */
@@ -83,29 +88,46 @@ typedef struct {
BIGNUM n; /* n = p * q (the modulus) */
BIGNUM d; /* private exponent */
BIGNUM e; /* public exponent */
- BIGNUM dmodpminus1; /* d mod (p - 1) */
- BIGNUM dmodqminus1; /* d mod (q - 1) */
- BIGNUM pinvmodq; /* p^(-1) mod q */
+ BIGNUM dmodpminus1; /* d mod (p - 1) (exponent 1) */
+ BIGNUM dmodqminus1; /* d mod (q - 1) (exponent 2) */
+ BIGNUM pinvmodq; /* p^(-1) mod q (the coefficient) */
BIGNUM p_rr; /* 2^(2*(32*p->len)) mod p */
BIGNUM q_rr; /* 2^(2*(32*q->len)) mod q */
BIGNUM n_rr; /* 2^(2*(32*n->len)) mod n */
} RSAkey;
-BIG_ERR_CODE RSA_key_init(RSAkey *key, int psize, int qsize);
-void RSA_key_finish(RSAkey *key);
-
-CK_RV soft_encrypt_rsa_pkcs_encode(uint8_t *databuf,
- size_t datalen, uint8_t *padbuf, size_t padbuflen);
-CK_RV soft_decrypt_rsa_pkcs_decode(uint8_t *padbuf, int *plen);
-
-CK_RV soft_sign_rsa_pkcs_encode(uint8_t *pData, size_t dataLen,
- uint8_t *data, size_t mbit_l);
-CK_RV soft_verify_rsa_pkcs_decode(uint8_t *data, int *mbit_l);
-
-#ifdef _KERNEL
-int knzero_random_generator(uint8_t *ran_out, size_t ran_len);
-void kmemset(uint8_t *buf, char pattern, size_t len);
-#endif
+/* RSA key using byte string representations, useful for parameter lists */
+typedef struct {
+ uint32_t modulus_bits; /* size */
+ uchar_t *modulus; /* n */
+ uint32_t privexpo_bytes;
+ uchar_t *privexpo; /* d */
+ uint32_t pubexpo_bytes;
+ uchar_t *pubexpo; /* e */
+ uint32_t prime1_bytes;
+ uchar_t *prime1; /* p */
+ uint32_t prime2_bytes;
+ uchar_t *prime2; /* q */
+ uint32_t expo1_bytes;
+ uchar_t *expo1; /* = d mod (p - 1) */
+ uint32_t expo2_bytes;
+ uchar_t *expo2; /* = d mod (q - 1) */
+ uint32_t coeff_bytes; /* = q bytes, .... or = p bytes */
+ uchar_t *coeff; /* = p^(-1) mod q, or = q^(-1) mod p */
+ int (*rfunc)(void *, size_t); /* random function */
+} RSAbytekey;
+
+
+CK_RV rsa_genkey_pair(RSAbytekey *bkey);
+
+CK_RV rsa_encrypt(RSAbytekey *bkey,
+ uchar_t *msg, uint32_t msglen, uchar_t *encrmsg);
+
+CK_RV rsa_decrypt(RSAbytekey *bkey,
+ uchar_t *encrmsg, uint32_t encrmsglen, uchar_t *msg);
+
+#define rsa_sign(key, msg, len, sig) rsa_decrypt((key), (msg), (len), (sig))
+#define rsa_verify(key, msg, len, sig) rsa_encrypt((key), (msg), (len), (sig))
/*
* The following definitions and declarations are only used by RSA FIPS POST
@@ -131,34 +153,13 @@ void kmemset(uint8_t *buf, char pattern, size_t len);
typedef struct RSAPrivateKey_s {
uint8_t *version;
int version_len;
- uint8_t *modulus;
- int modulus_len;
- uint8_t *public_expo;
- int public_expo_len;
- uint8_t *private_expo;
- int private_expo_len;
- uint8_t *prime1;
- int prime1_len;
- uint8_t *prime2;
- int prime2_len;
- uint8_t *exponent1;
- int exponent1_len;
- uint8_t *exponent2;
- int exponent2_len;
- uint8_t *coef;
- int coef_len;
+ RSAbytekey bkey;
} RSAPrivateKey_t;
/* RSA FIPS functions */
extern int fips_rsa_post(void);
-extern int fips_rsa_encrypt(uint8_t *, int, uint8_t *,
- int, uint8_t *, int, uint8_t *);
-extern int fips_rsa_decrypt(RSAPrivateKey_t *, uint8_t *,
- int, uint8_t *);
-extern int fips_rsa_sign(RSAPrivateKey_t *, uint8_t *,
- uint32_t, uint8_t *);
-extern int fips_rsa_verify(RSAPrivateKey_t *, uint8_t *, uint32_t,
- uint8_t *);
+extern int fips_rsa_encrypt(RSAPrivateKey_t *, uint8_t *, int, uint8_t *);
+extern int fips_rsa_decrypt(RSAPrivateKey_t *, uint8_t *, int, uint8_t *);
#endif /* _RSA_FIPS_POST */