diff options
author | dinak <none@none> | 2008-02-28 13:44:32 -0800 |
---|---|---|
committer | dinak <none@none> | 2008-02-28 13:44:32 -0800 |
commit | 26ff1ce9e5494c59fafe62a0c6e3ca41cd0f2a99 (patch) | |
tree | dbb32aebaf673fd792dee06c4125ff6aa2492fd8 | |
parent | 9d68b18ee78271952aa02af7a316bfb825f35d97 (diff) | |
download | illumos-joyent-26ff1ce9e5494c59fafe62a0c6e3ca41cd0f2a99.tar.gz |
6665460 move random and nonzero random funcs out of pkcs11 to libcryptoutil
6665548 convert pkcs11 mechanism to corresponding key generation mechanism
-rw-r--r-- | usr/src/lib/libcryptoutil/Makefile.com | 5 | ||||
-rw-r--r-- | usr/src/lib/libcryptoutil/common/cryptoutil.h | 5 | ||||
-rw-r--r-- | usr/src/lib/libcryptoutil/common/mapfile-vers | 4 | ||||
-rw-r--r-- | usr/src/lib/libcryptoutil/common/mechkeygen.c | 362 | ||||
-rw-r--r-- | usr/src/lib/libcryptoutil/common/random.c | 163 |
5 files changed, 525 insertions, 14 deletions
diff --git a/usr/src/lib/libcryptoutil/Makefile.com b/usr/src/lib/libcryptoutil/Makefile.com index ecefbef41b..7f8c7a0a43 100644 --- a/usr/src/lib/libcryptoutil/Makefile.com +++ b/usr/src/lib/libcryptoutil/Makefile.com @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -33,7 +33,8 @@ OBJECTS= \ mechstr.o \ config_parsing.o \ tohexstr.o \ - mechkeytype.o\ + mechkeygen.o \ + mechkeytype.o \ pkcserror.o \ passutils.o \ random.o \ diff --git a/usr/src/lib/libcryptoutil/common/cryptoutil.h b/usr/src/lib/libcryptoutil/common/cryptoutil.h index 5d0c3c9ab3..671e02a1fe 100644 --- a/usr/src/lib/libcryptoutil/common/cryptoutil.h +++ b/usr/src/lib/libcryptoutil/common/cryptoutil.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -127,6 +127,8 @@ extern uentry_t *getent_uef(char *); extern void tohexstr(uchar_t *bytes, size_t blen, char *hexstr, size_t hexlen); extern CK_RV pkcs11_mech2keytype(CK_MECHANISM_TYPE mech_type, CK_KEY_TYPE *ktype); +extern CK_RV pkcs11_mech2keygen(CK_MECHANISM_TYPE mech_type, + CK_MECHANISM_TYPE *gen_mech); extern char *pkcs11_strerror(CK_RV rv); extern int @@ -141,6 +143,7 @@ extern int pkcs11_get_pass(char *token_name, char **pdata, size_t *psize, size_t min_psize, boolean_t with_confirmation); extern int pkcs11_random_data(void *dbuf, size_t dlen); +extern int pkcs11_nzero_random_data(void *dbuf, size_t dlen); extern int pkcs11_read_data(char *filename, void **dbuf, size_t *dlen); #ifdef __cplusplus diff --git a/usr/src/lib/libcryptoutil/common/mapfile-vers b/usr/src/lib/libcryptoutil/common/mapfile-vers index b5e9fe2019..0e10ac1772 100644 --- a/usr/src/lib/libcryptoutil/common/mapfile-vers +++ b/usr/src/lib/libcryptoutil/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -41,7 +41,9 @@ SUNWprivate { pkcs11_default_token; pkcs11_get_pass; pkcs11_mech2keytype; + pkcs11_mech2keygen; pkcs11_mech2str; + pkcs11_nzero_random_data; pkcs11_random_data; pkcs11_read_data; pkcs11_str2mech; diff --git a/usr/src/lib/libcryptoutil/common/mechkeygen.c b/usr/src/lib/libcryptoutil/common/mechkeygen.c new file mode 100644 index 0000000000..586b913510 --- /dev/null +++ b/usr/src/lib/libcryptoutil/common/mechkeygen.c @@ -0,0 +1,362 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <cryptoutil.h> + +/* + * Get the key generation mechanism for the given mechanism. + * + * All mechanisms in PKCS #11 v2.20 are listed here. + */ +CK_RV +pkcs11_mech2keygen(CK_MECHANISM_TYPE mech_type, CK_MECHANISM_TYPE *gen_mech) +{ + switch (mech_type) { + + case CKM_RSA_PKCS_KEY_PAIR_GEN: + case CKM_RSA_PKCS: + case CKM_RSA_9796: + case CKM_RSA_X_509: + case CKM_MD2_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: + case CKM_SHA256_RSA_PKCS_PSS: + case CKM_SHA384_RSA_PKCS_PSS: + case CKM_SHA512_RSA_PKCS_PSS: + case CKM_RIPEMD128_RSA_PKCS: + case CKM_RIPEMD160_RSA_PKCS: + case CKM_RSA_PKCS_OAEP: + *gen_mech = CKM_RSA_PKCS_KEY_PAIR_GEN; + break; + + case CKM_RSA_X9_31_KEY_PAIR_GEN: + case CKM_RSA_X9_31: + case CKM_SHA1_RSA_X9_31: + *gen_mech = CKM_RSA_X9_31_KEY_PAIR_GEN; + break; + + case CKM_RSA_PKCS_PSS: + case CKM_SHA1_RSA_PKCS_PSS: + *gen_mech = CKM_RSA_PKCS_KEY_PAIR_GEN; + break; + + case CKM_DH_PKCS_PARAMETER_GEN: + *gen_mech = CKM_DH_PKCS_PARAMETER_GEN; + break; + + case CKM_DSA_KEY_PAIR_GEN: + case CKM_DSA: + case CKM_DSA_SHA1: + *gen_mech = CKM_DSA_KEY_PAIR_GEN; + break; + + case CKM_DSA_PARAMETER_GEN: + *gen_mech = CKM_DSA_PARAMETER_GEN; + break; + + case CKM_FORTEZZA_TIMESTAMP: + *gen_mech = CKM_DSA_KEY_PAIR_GEN; + break; + + case CKM_DH_PKCS_KEY_PAIR_GEN: + case CKM_DH_PKCS_DERIVE: + *gen_mech = CKM_DH_PKCS_KEY_PAIR_GEN; + break; + + case CKM_ECDSA: + case CKM_ECDSA_SHA1: + case CKM_EC_KEY_PAIR_GEN: + case CKM_ECDH1_DERIVE: + case CKM_ECDH1_COFACTOR_DERIVE: + case CKM_ECMQV_DERIVE: + *gen_mech = CKM_EC_KEY_PAIR_GEN; + break; + + case CKM_X9_42_DH_KEY_PAIR_GEN: + case CKM_X9_42_DH_DERIVE: + case CKM_X9_42_DH_HYBRID_DERIVE: + case CKM_X9_42_MQV_DERIVE: + *gen_mech = CKM_X9_42_DH_KEY_PAIR_GEN; + break; + + case CKM_X9_42_DH_PARAMETER_GEN: + *gen_mech = CKM_X9_42_DH_PARAMETER_GEN; + break; + + case CKM_KEA_KEY_PAIR_GEN: + case CKM_KEA_KEY_DERIVE: + *gen_mech = CKM_KEA_KEY_PAIR_GEN; + break; + + case CKM_MD2: + case CKM_MD2_HMAC: + case CKM_MD2_HMAC_GENERAL: + case CKM_MD5: + case CKM_MD5_HMAC: + case CKM_MD5_HMAC_GENERAL: + case CKM_SHA_1: + case CKM_SHA_1_HMAC: + case CKM_SHA_1_HMAC_GENERAL: + case CKM_SHA256: + case CKM_SHA256_HMAC: + case CKM_SHA256_HMAC_GENERAL: + case CKM_SHA384: + case CKM_SHA384_HMAC: + case CKM_SHA384_HMAC_GENERAL: + case CKM_SHA512: + case CKM_SHA512_HMAC: + case CKM_SHA512_HMAC_GENERAL: + case CKM_GENERIC_SECRET_KEY_GEN: + case CKM_FASTHASH: + case CKM_PKCS5_PBKD2: + case CKM_PBA_SHA1_WITH_SHA1_HMAC: + *gen_mech = CKM_GENERIC_SECRET_KEY_GEN; + break; + + case CKM_SSL3_MD5_MAC: + case CKM_SSL3_SHA1_MAC: + case CKM_SSL3_PRE_MASTER_KEY_GEN: + case CKM_SSL3_MASTER_KEY_DERIVE: + case CKM_SSL3_KEY_AND_MAC_DERIVE: + case CKM_SSL3_MASTER_KEY_DERIVE_DH: + *gen_mech = CKM_SSL3_PRE_MASTER_KEY_GEN; + break; + + case CKM_TLS_PRE_MASTER_KEY_GEN: + case CKM_TLS_MASTER_KEY_DERIVE: + case CKM_TLS_KEY_AND_MAC_DERIVE: + case CKM_TLS_MASTER_KEY_DERIVE_DH: + case CKM_TLS_PRF: + *gen_mech = CKM_TLS_PRE_MASTER_KEY_GEN; + break; + + case CKM_WTLS_PRE_MASTER_KEY_GEN: + case CKM_WTLS_MASTER_KEY_DERIVE: + case CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC: + case CKM_WTLS_PRF: + case CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE: + case CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE: + *gen_mech = CKM_WTLS_PRE_MASTER_KEY_GEN; + break; + + case CKM_CONCATENATE_BASE_AND_KEY: + case CKM_CONCATENATE_BASE_AND_DATA: + case CKM_CONCATENATE_DATA_AND_BASE: + case CKM_XOR_BASE_AND_DATA: + case CKM_EXTRACT_KEY_FROM_KEY: + case CKM_RIPEMD128: + case CKM_RIPEMD128_HMAC: + case CKM_RIPEMD128_HMAC_GENERAL: + case CKM_RIPEMD160: + case CKM_RIPEMD160_HMAC: + case CKM_RIPEMD160_HMAC_GENERAL: + case CKM_SHA1_KEY_DERIVATION: + case CKM_SHA256_KEY_DERIVATION: + case CKM_SHA384_KEY_DERIVATION: + case CKM_SHA512_KEY_DERIVATION: + case CKM_MD5_KEY_DERIVATION: + case CKM_MD2_KEY_DERIVATION: + /* not sure the following 2 should be CKK_DES or not */ + case CKM_KEY_WRAP_LYNKS: /* wrap/unwrap secret key w/ DES key */ + case CKM_KEY_WRAP_SET_OAEP: /* wrap/unwarp DES key w/ RSA key */ + *gen_mech = CKM_GENERIC_SECRET_KEY_GEN; + break; + + case CKM_RC2_KEY_GEN: + case CKM_RC2_ECB: + case CKM_RC2_CBC: + case CKM_RC2_MAC: + case CKM_RC2_MAC_GENERAL: + case CKM_RC2_CBC_PAD: + case CKM_PBE_SHA1_RC2_128_CBC: + case CKM_PBE_SHA1_RC2_40_CBC: + *gen_mech = CKM_RC2_KEY_GEN; + break; + + case CKM_RC4_KEY_GEN: + case CKM_RC4: + case CKM_PBE_SHA1_RC4_128: + case CKM_PBE_SHA1_RC4_40: + *gen_mech = CKM_RC4_KEY_GEN; + break; + + case CKM_DES_KEY_GEN: + case CKM_DES_ECB: + case CKM_DES_CBC: + case CKM_DES_MAC: + case CKM_DES_MAC_GENERAL: + case CKM_DES_CBC_PAD: + case CKM_PBE_MD2_DES_CBC: + case CKM_PBE_MD5_DES_CBC: + case CKM_DES_OFB64: + case CKM_DES_OFB8: + case CKM_DES_CFB64: + case CKM_DES_CFB8: + case CKM_DES_ECB_ENCRYPT_DATA: + case CKM_DES_CBC_ENCRYPT_DATA: + *gen_mech = CKM_DES_KEY_GEN; + break; + + case CKM_DES2_KEY_GEN: + case CKM_PBE_SHA1_DES2_EDE_CBC: + *gen_mech = CKM_DES2_KEY_GEN; + break; + + case CKM_DES3_KEY_GEN: + case CKM_DES3_ECB: + case CKM_DES3_CBC: + case CKM_DES3_MAC: + case CKM_DES3_MAC_GENERAL: + case CKM_DES3_CBC_PAD: + case CKM_PBE_SHA1_DES3_EDE_CBC: + case CKM_DES3_ECB_ENCRYPT_DATA: + case CKM_DES3_CBC_ENCRYPT_DATA: + *gen_mech = CKM_DES3_KEY_GEN; + break; + + case CKM_CAST_KEY_GEN: + case CKM_CAST_ECB: + case CKM_CAST_CBC: + case CKM_CAST_MAC: + case CKM_CAST_MAC_GENERAL: + case CKM_CAST_CBC_PAD: + case CKM_PBE_MD5_CAST_CBC: + *gen_mech = CKM_CAST_KEY_GEN; + break; + + case CKM_CAST3_KEY_GEN: + case CKM_CAST3_ECB: + case CKM_CAST3_CBC: + case CKM_CAST3_MAC: + case CKM_CAST3_MAC_GENERAL: + case CKM_CAST3_CBC_PAD: + case CKM_PBE_MD5_CAST3_CBC: + *gen_mech = CKM_CAST3_KEY_GEN; + break; + + case CKM_CAST128_KEY_GEN: + case CKM_CAST128_ECB: + case CKM_CAST128_CBC: + case CKM_CAST128_MAC: + case CKM_CAST128_MAC_GENERAL: + case CKM_CAST128_CBC_PAD: + case CKM_PBE_MD5_CAST128_CBC: + case CKM_PBE_SHA1_CAST128_CBC: + *gen_mech = CKM_CAST128_KEY_GEN; + break; + + case CKM_RC5_KEY_GEN: + case CKM_RC5_ECB: + case CKM_RC5_CBC: + case CKM_RC5_MAC: + case CKM_RC5_MAC_GENERAL: + case CKM_RC5_CBC_PAD: + *gen_mech = CKM_RC5_KEY_GEN; + break; + + case CKM_IDEA_KEY_GEN: + case CKM_IDEA_ECB: + case CKM_IDEA_CBC: + case CKM_IDEA_MAC: + case CKM_IDEA_MAC_GENERAL: + case CKM_IDEA_CBC_PAD: + *gen_mech = CKM_IDEA_KEY_GEN; + break; + + case CKM_SKIPJACK_KEY_GEN: + case CKM_SKIPJACK_ECB64: + case CKM_SKIPJACK_CBC64: + case CKM_SKIPJACK_OFB64: + case CKM_SKIPJACK_CFB64: + case CKM_SKIPJACK_CFB32: + case CKM_SKIPJACK_CFB16: + case CKM_SKIPJACK_CFB8: + case CKM_SKIPJACK_WRAP: + case CKM_SKIPJACK_PRIVATE_WRAP: + case CKM_SKIPJACK_RELAYX: + *gen_mech = CKM_SKIPJACK_KEY_GEN; + break; + + case CKM_BATON_KEY_GEN: + case CKM_BATON_ECB128: + case CKM_BATON_ECB96: + case CKM_BATON_CBC128: + case CKM_BATON_COUNTER: + case CKM_BATON_SHUFFLE: + case CKM_BATON_WRAP: + *gen_mech = CKM_BATON_KEY_GEN; + break; + + case CKM_JUNIPER_KEY_GEN: + case CKM_JUNIPER_ECB128: + case CKM_JUNIPER_CBC128: + case CKM_JUNIPER_COUNTER: + case CKM_JUNIPER_SHUFFLE: + case CKM_JUNIPER_WRAP: + *gen_mech = CKM_JUNIPER_KEY_GEN; + break; + + case CKM_CDMF_KEY_GEN: + case CKM_CDMF_ECB: + case CKM_CDMF_CBC: + case CKM_CDMF_MAC: + case CKM_CDMF_MAC_GENERAL: + case CKM_CDMF_CBC_PAD: + *gen_mech = CKM_CDMF_KEY_GEN; + break; + + case CKM_AES_KEY_GEN: + case CKM_AES_ECB: + case CKM_AES_CBC: + case CKM_AES_MAC: + case CKM_AES_MAC_GENERAL: + case CKM_AES_CBC_PAD: + case CKM_AES_ECB_ENCRYPT_DATA: + case CKM_AES_CBC_ENCRYPT_DATA: + *gen_mech = CKM_AES_KEY_GEN; + break; + + case CKM_BLOWFISH_KEY_GEN: + case CKM_BLOWFISH_CBC: + *gen_mech = CKM_BLOWFISH_KEY_GEN; + break; + + case CKM_TWOFISH_KEY_GEN: + case CKM_TWOFISH_CBC: + *gen_mech = CKM_TWOFISH_KEY_GEN; + break; + + default: + return (CKR_MECHANISM_INVALID); + break; + } + + return (CKR_OK); +} diff --git a/usr/src/lib/libcryptoutil/common/random.c b/usr/src/lib/libcryptoutil/common/random.c index ea3e83dedd..6d91dbfea4 100644 --- a/usr/src/lib/libcryptoutil/common/random.c +++ b/usr/src/lib/libcryptoutil/common/random.c @@ -19,19 +19,133 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> +#include <unistd.h> +#include <errno.h> #include <string.h> #include <fcntl.h> #include <locale.h> #include <cryptoutil.h> -#define RANDOM_DEVICE "/dev/urandom" /* random device name */ +#ifdef _REENTRANT + +#include <pthread.h> + +static pthread_mutex_t random_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t urandom_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define RAND_LOCK(x) (void) pthread_mutex_lock(x) +#define RAND_UNLOCK(x) (void) pthread_mutex_unlock(x) + +#else + +#define RAND_LOCK(x) +#define RAND_UNLOCK(x) + +#endif + +#define RANDOM_DEVICE "/dev/random" /* random device name */ +#define URANDOM_DEVICE "/dev/urandom" /* urandom device name */ + +static int random_fd = -1; +static int urandom_fd = -1; + +/* + * Equivalent of open(2) insulated from EINTR. + * Also sets close-on-exec. + */ +static int +OPEN(const char *path, int oflag) +{ + int fd; + + do { + if ((fd = open(path, oflag)) >= 0) { + (void) fcntl(fd, F_SETFD, FD_CLOEXEC); + break; + } + /* errno definitely set by failed open() */ + } while (errno == EINTR); + return (fd); +} + +/* + * Equivalent of read(2) insulated from EINTR. + */ +static ssize_t +READ(int fd, void *dbuf, size_t dlen) +{ + char *marker = dbuf; + size_t left = dlen; + ssize_t nread = 0, err; + + for (err = 0; left > 0 && nread != -1; marker += nread, left -= nread) { + if ((nread = read(fd, marker, left)) < 0) { + if (errno == EINTR) { /* keep trying */ + nread = 0; + continue; + } + err = nread; /* hard error */ + break; + } + } + return (err != 0 ? err : dlen - left); +} + +/* + * Opens the random number generator devices if not already open. + * Always returns the opened fd of the device, or error. + */ +int +pkcs11_open_random(void) +{ + RAND_LOCK(&random_mutex); + if (random_fd < 0) + random_fd = OPEN(RANDOM_DEVICE, O_RDONLY); + RAND_UNLOCK(&random_mutex); + return (random_fd); +} + +int +pkcs11_open_urandom(void) +{ + RAND_LOCK(&urandom_mutex); + if (urandom_fd < 0) + urandom_fd = OPEN(URANDOM_DEVICE, O_RDONLY); + RAND_UNLOCK(&urandom_mutex); + return (urandom_fd); +} + +/* + * Close the random number generator devices if already open. + */ +void +pkcs11_close_random(void) +{ + if (random_fd < 0) + return; + RAND_LOCK(&random_mutex); + (void) close(random_fd); + random_fd = -1; + RAND_UNLOCK(&random_mutex); +} + +void +pkcs11_close_urandom(void) +{ + if (urandom_fd < 0) + return; + RAND_LOCK(&urandom_mutex); + (void) close(urandom_fd); + urandom_fd = -1; + RAND_UNLOCK(&urandom_mutex); +} /* * Put the requested amount of random data into a preallocated buffer. @@ -40,18 +154,47 @@ int pkcs11_random_data(void *dbuf, size_t dlen) { - int fd; - if (dbuf == NULL || dlen == 0) return (0); /* Read random data directly from /dev/urandom */ - if ((fd = open(RANDOM_DEVICE, O_RDONLY)) != -1) { - if (read(fd, dbuf, dlen) == dlen) { - (void) close(fd); - return (0); + if (pkcs11_open_urandom() < 0) + return (-1); + + if (READ(urandom_fd, dbuf, dlen) == dlen) + return (0); + return (-1); +} + +/* + * Same as pkcs11_random_data but ensures non zero data. + */ +int +pkcs11_nzero_random_data(void *dbuf, size_t dlen) +{ + char extrarand[32]; + size_t bytesleft = 0; + size_t i = 0; + + /* Start with some random data */ + if (pkcs11_random_data(dbuf, dlen) < 0) + return (-1); + + /* Walk through data replacing any 0 bytes with more random data */ + while (i < dlen) { + if (((char *)dbuf)[i] != 0) { + i++; + continue; } - (void) close(fd); + + if (bytesleft == 0) { + bytesleft = sizeof (extrarand); + if (pkcs11_random_data(extrarand, bytesleft) < 0) + return (-1); + } + bytesleft--; + + ((char *)dbuf)[i] = extrarand[bytesleft]; } - return (-1); + return (0); } |