From: Kent Yoder <[email protected]>

---
 usr/lib/pkcs11/common/h_extern.h        |   12 +-
 usr/lib/pkcs11/tpm_stdll/h_extern.h     |   12 +-
 usr/lib/pkcs11/tpm_stdll/tpm_specific.c |  313 +++++++++++++++++++++++++++++--
 3 files changed, 310 insertions(+), 27 deletions(-)

diff --git a/usr/lib/pkcs11/common/h_extern.h b/usr/lib/pkcs11/common/h_extern.h
index c774a69..ce0fd40 100755
--- a/usr/lib/pkcs11/common/h_extern.h
+++ b/usr/lib/pkcs11/common/h_extern.h
@@ -2390,20 +2390,20 @@ extern token_spec_t token_specific;
 
 /* Debug logging */
 #ifdef DEBUG
-#define LogDebug(fmt, ...)      LogMessage(stdout, "LOG_DEBUG", STDLL_NAME, 
fmt, ##__VA_ARGS__)
-#define LogDebug1(data)         LogMessage1(stdout, "LOG_DEBUG", STDLL_NAME, 
data)
+#define LogDebug(fmt, ...)      LogMessage(stderr, "LOG_DEBUG", STDLL_NAME, 
fmt, ##__VA_ARGS__)
+#define LogDebug1(data)         LogMessage1(stderr, "LOG_DEBUG", STDLL_NAME, 
data)
 
 /* Error logging */
 #define LogError(fmt, ...)      LogMessage(stderr, "LOG_ERR", STDLL_NAME, 
"ERROR: " fmt, ##__VA_ARGS__)
 #define LogError1(data)         LogMessage1(stderr, "LOG_ERR", STDLL_NAME, 
"ERROR: " data)
 
 /* Warn logging */
-#define LogWarn(fmt, ...)       LogMessage(stdout, "LOG_WARNING", STDLL_NAME, 
"WARNING: " fmt, ##__VA_ARGS__)
-#define LogWarn1(data)          LogMessage1(stdout, "LOG_WARNING", STDLL_NAME, 
"WARNING: " data)
+#define LogWarn(fmt, ...)       LogMessage(stderr, "LOG_WARNING", STDLL_NAME, 
"WARNING: " fmt, ##__VA_ARGS__)
+#define LogWarn1(data)          LogMessage1(stderr, "LOG_WARNING", STDLL_NAME, 
"WARNING: " data)
 
 /* Info Logging */
-#define LogInfo(fmt, ...)       LogMessage(stdout, "LOG_INFO", STDLL_NAME, 
fmt, ##__VA_ARGS__)
-#define LogInfo1(data)          LogMessage1(stdout, "LOG_INFO", STDLL_NAME, 
data)
+#define LogInfo(fmt, ...)       LogMessage(stderr, "LOG_INFO", STDLL_NAME, 
fmt, ##__VA_ARGS__)
+#define LogInfo1(data)          LogMessage1(stderr, "LOG_INFO", STDLL_NAME, 
data)
 
 #define st_err_log(num, ...)    LogMessage(stderr, "ERROR", STDLL_NAME, "%s", 
err_msg[num].msg)
 #else
diff --git a/usr/lib/pkcs11/tpm_stdll/h_extern.h 
b/usr/lib/pkcs11/tpm_stdll/h_extern.h
index 00a260a..81b567a 100644
--- a/usr/lib/pkcs11/tpm_stdll/h_extern.h
+++ b/usr/lib/pkcs11/tpm_stdll/h_extern.h
@@ -2003,20 +2003,20 @@ extern token_spec_t token_specific;
 
 /* Debug logging */
 #ifdef DEBUG
-#define LogDebug(fmt, ...)      LogMessage(stdout, "LOG_DEBUG", APPID, fmt, 
##__VA_ARGS__)
-#define LogDebug1(data)         LogMessage1(stdout, "LOG_DEBUG", APPID, data)
+#define LogDebug(fmt, ...)      LogMessage(stderr, "LOG_DEBUG", APPID, fmt, 
##__VA_ARGS__)
+#define LogDebug1(data)         LogMessage1(stderr, "LOG_DEBUG", APPID, data)
 
 /* Error logging */
 #define LogError(fmt, ...)      LogMessage(stderr, "LOG_ERR", APPID, "ERROR: " 
fmt, ##__VA_ARGS__)
 #define LogError1(data)         LogMessage1(stderr, "LOG_ERR", APPID, "ERROR: 
" data)
 
 /* Warn logging */
-#define LogWarn(fmt, ...)       LogMessage(stdout, "LOG_WARNING", APPID, 
"WARNING: " fmt, ##__VA_ARGS__)
-#define LogWarn1(data)          LogMessage1(stdout, "LOG_WARNING", APPID, 
"WARNING: " data)
+#define LogWarn(fmt, ...)       LogMessage(stderr, "LOG_WARNING", APPID, 
"WARNING: " fmt, ##__VA_ARGS__)
+#define LogWarn1(data)          LogMessage1(stderr, "LOG_WARNING", APPID, 
"WARNING: " data)
 
 /* Info Logging */
-#define LogInfo(fmt, ...)       LogMessage(stdout, "LOG_INFO", APPID, fmt, 
##__VA_ARGS__)
-#define LogInfo1(data)          LogMessage1(stdout, "LOG_INFO", APPID, data)
+#define LogInfo(fmt, ...)       LogMessage(stderr, "LOG_INFO", APPID, fmt, 
##__VA_ARGS__)
+#define LogInfo1(data)          LogMessage1(stderr, "LOG_INFO", APPID, data)
 
 #define st_err_log(...)                LogMessage(stderr, "ST MSG", APPID, 
"whammy")
 #else
diff --git a/usr/lib/pkcs11/tpm_stdll/tpm_specific.c 
b/usr/lib/pkcs11/tpm_stdll/tpm_specific.c
index d5708c3..cc13299 100644
--- a/usr/lib/pkcs11/tpm_stdll/tpm_specific.c
+++ b/usr/lib/pkcs11/tpm_stdll/tpm_specific.c
@@ -34,6 +34,7 @@
 #include <pthread.h>
 #include <string.h>
 #include <stdlib.h>
+#include <limits.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2338,7 +2339,7 @@ token_unwrap_auth_data(CK_BYTE *encAuthData, CK_ULONG 
encAuthDataLen, TSS_HKEY h
 
        return CKR_OK;
 }
-
+#if 0
 // convert from the local PKCS11 template representation to
 // the underlying requirement
 // returns the pointer to the local key representation
@@ -2364,7 +2365,7 @@ rsa_convert_public_key(OBJECT *key_obj)
 
        return ret;
 }
-
+#endif
 CK_RV
 token_specific_rsa_generate_keypair( TEMPLATE  * publ_tmpl,
                TEMPLATE  * priv_tmpl )
@@ -2598,6 +2599,288 @@ token_rsa_load_key( OBJECT * key_obj, TSS_HKEY * phKey )
        return CKR_OK;
 }
 
+/* Convert from the local PKCS11 template representation to the underlying 
requirement
+ * returns the pointer to the local key representation */
+void *
+rsa_convert_public_key( OBJECT    * key_obj )
+{
+       CK_BBOOL           rc;
+       CK_ATTRIBUTE      * modulus = NULL;
+       CK_ATTRIBUTE      * pub_exp = NULL;
+
+       RSA *rsa;
+       BIGNUM *bn_mod, *bn_exp;
+
+       rc  = template_attribute_find( key_obj->template, CKA_MODULUS,         
&modulus );
+       rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, 
&pub_exp );
+
+       if (rc == FALSE) {
+               return NULL;
+       }
+
+       // Create an RSA key struct to return
+       rsa = RSA_new();
+       if (rsa == NULL)
+               return NULL;
+       RSA_blinding_off(rsa);
+
+       // Create and init BIGNUM structs to stick in the RSA struct
+       bn_mod = BN_new();
+       bn_exp = BN_new();
+
+       if (bn_exp == NULL || bn_mod == NULL) {
+               if (bn_mod) free(bn_mod);
+               if (bn_exp) free(bn_exp);
+               RSA_free(rsa);
+               return NULL;
+       }
+
+       // Convert from strings to BIGNUMs and stick them in the RSA struct
+       BN_bin2bn((unsigned char *)modulus->pValue, modulus->ulValueLen, 
bn_mod);
+       rsa->n = bn_mod;
+       BN_bin2bn((unsigned char *)pub_exp->pValue, pub_exp->ulValueLen, 
bn_exp);
+       rsa->e = bn_exp;
+
+       return (void *)rsa;
+}
+
+void *
+rsa_convert_private_key(OBJECT *key_obj)
+{
+       CK_ATTRIBUTE      * attr     = NULL;
+       CK_ATTRIBUTE      * modulus  = NULL;
+       CK_ATTRIBUTE      * priv_exp = NULL;
+       CK_ATTRIBUTE      * prime1   = NULL;
+       CK_ATTRIBUTE      * prime2   = NULL;
+       CK_ATTRIBUTE      * exp1     = NULL;
+       CK_ATTRIBUTE      * exp2     = NULL;
+       CK_ATTRIBUTE      * coeff    = NULL;
+       CK_BBOOL          rc;
+
+       RSA *rsa;
+       BIGNUM *bn_mod, *bn_priv_exp, *bn_p1, *bn_p2, *bn_e1, *bn_e2, *bn_cf;
+
+
+       rc  = template_attribute_find( key_obj->template, CKA_MODULUS,          
&modulus );
+       rc &= template_attribute_find( key_obj->template, CKA_PRIVATE_EXPONENT, 
&priv_exp );
+       rc &= template_attribute_find( key_obj->template, CKA_PRIME_1,          
&prime1 );
+       rc &= template_attribute_find( key_obj->template, CKA_PRIME_2,          
&prime2 );
+       rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_1,       
&exp1 );
+       rc &= template_attribute_find( key_obj->template, CKA_EXPONENT_2,       
&exp2 );
+       rc &= template_attribute_find( key_obj->template, CKA_COEFFICIENT,      
&coeff );
+
+       if ( !prime2 && !modulus ){
+               return NULL;
+       }
+
+       // Create and init all the RSA and BIGNUM structs we need.
+       rsa = RSA_new();
+       if (rsa == NULL)
+               return NULL;
+       RSA_blinding_off(rsa);
+
+       bn_mod = BN_new();
+       bn_priv_exp = BN_new();
+       bn_p1 = BN_new();
+       bn_p2 = BN_new();
+       bn_e1 = BN_new();
+       bn_e2 = BN_new();
+       bn_cf = BN_new();
+
+       if ((bn_cf == NULL) || (bn_e2 == NULL) || (bn_e1 == NULL) ||
+           (bn_p2 == NULL) || (bn_p1 == NULL) || (bn_priv_exp == NULL) ||
+           (bn_mod == NULL))
+       {
+               if (rsa)         RSA_free(rsa);
+               if (bn_mod)      BN_free(bn_mod);
+               if (bn_priv_exp) BN_free(bn_priv_exp);
+               if (bn_p1)       BN_free(bn_p1);
+               if (bn_p2)       BN_free(bn_p2);
+               if (bn_e1)       BN_free(bn_e1);
+               if (bn_e2)       BN_free(bn_e2);
+               if (bn_cf)       BN_free(bn_cf);
+               return NULL;
+       }
+
+       // CRT key?
+       if ( prime1){
+               if (!prime2 || !exp1 ||!exp2 || !coeff) {
+                       return NULL;
+               }
+               // Even though this is CRT key, OpenSSL requires the
+               // modulus and exponents filled in or encrypt and decrypt will
+               // not work
+               BN_bin2bn((unsigned char *)modulus->pValue, 
modulus->ulValueLen, bn_mod);
+               rsa->n = bn_mod;
+               BN_bin2bn((unsigned char *)priv_exp->pValue, 
priv_exp->ulValueLen, bn_priv_exp);
+               rsa->d = bn_priv_exp;
+               BN_bin2bn((unsigned char *)prime1->pValue, prime1->ulValueLen, 
bn_p1);
+               rsa->p = bn_p1;
+               BN_bin2bn((unsigned char *)prime2->pValue, prime2->ulValueLen, 
bn_p2);
+               rsa->q = bn_p2;
+               BN_bin2bn((unsigned char *)exp1->pValue, exp1->ulValueLen, 
bn_e1);
+               rsa->dmp1 = bn_e1;
+               BN_bin2bn((unsigned char *)exp2->pValue, exp2->ulValueLen, 
bn_e2);
+               rsa->dmq1 = bn_e2;
+               BN_bin2bn((unsigned char *)coeff->pValue, coeff->ulValueLen, 
bn_cf);
+               rsa->iqmp = bn_cf;
+
+               return rsa;
+       } else {   // must be a non-CRT key
+               if (!priv_exp) {
+                       return NULL;
+               }
+               BN_bin2bn((unsigned char *)modulus->pValue, 
modulus->ulValueLen, bn_mod);
+               rsa->n = bn_mod;
+               BN_bin2bn((unsigned char *)priv_exp->pValue, 
priv_exp->ulValueLen, bn_priv_exp);
+               rsa->d = bn_priv_exp;
+       }
+       return (void *)rsa;
+}
+
+CK_RV
+token_rsa_sw_encrypt(CK_BYTE   * in_data,
+                    CK_ULONG    in_data_len,
+                    CK_BYTE   * out_data,
+                    CK_ULONG  * out_data_len,
+                    OBJECT    * key_obj )
+{
+       CK_RV   rc;
+       RSA     *rsa;
+
+       // Convert the local representation to an OpenSSL representation
+       if ((rsa = (RSA *)rsa_convert_public_key(key_obj)) == NULL) {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               return CKR_HOST_MEMORY;
+       }
+
+       // Do an RSA public encryption
+       rc = RSA_public_encrypt(in_data_len, in_data, out_data, rsa, 
RSA_PKCS1_PADDING);
+
+       if (rc != 0) {
+               *out_data_len = rc;
+               rc = CKR_OK;
+       } else {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               DEBUG_openssl_print_errors();
+               rc = CKR_FUNCTION_FAILED;
+       }
+
+       RSA_free(rsa);
+       return rc;
+}
+
+CK_RV
+token_rsa_sw_decrypt(CK_BYTE   * in_data,
+                    CK_ULONG    in_data_len,
+                    CK_BYTE   * out_data,
+                    CK_ULONG  * out_data_len,
+                    OBJECT    * key_obj)
+{
+       CK_RV   rv;
+       int     rc;
+       RSA     *rsa;
+
+       // Convert the local key representation to an RSA key representaion
+       if ((rsa = (RSA *)rsa_convert_private_key(key_obj)) == NULL) {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               return CKR_HOST_MEMORY;
+       }
+
+       // Do the private decryption
+       rc = RSA_private_decrypt(in_data_len, in_data, out_data, rsa, 
RSA_PKCS1_PADDING);
+
+       if (rc > 0) {
+               *out_data_len = rc;
+               rv = CKR_OK;
+       } else {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               DEBUG_openssl_print_errors();
+               rv = CKR_FUNCTION_FAILED;
+       }
+
+       RSA_free(rsa);
+       return rv;
+}
+
+CK_RV
+token_rsa_sw_sign(CK_BYTE   * in_data,
+                 CK_ULONG    in_data_len,
+                 CK_BYTE   * out_data,
+                 CK_ULONG  * out_data_len,
+                 OBJECT    * key_obj)
+{
+       CK_RV   rv;
+       RSA     *rsa;
+       int     nid = 0, in_len, rc;
+
+       if (in_data_len > UINT_MAX || *out_data_len > UINT_MAX) {
+               in_len = UINT_MAX;
+       } else {
+               in_len = in_data_len;
+       }
+
+       // Convert the local key representation to an RSA key representaion
+       if ((rsa = (RSA *)rsa_convert_private_key(key_obj)) == NULL) {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               DEBUG_openssl_print_errors();
+               return CKR_HOST_MEMORY;
+       }
+
+       rc = RSA_private_encrypt(in_len, in_data, out_data, rsa, 
RSA_PKCS1_PADDING);
+
+       if (rc > *out_data_len) {
+               rv = CKR_BUFFER_TOO_SMALL;
+       } else if (rc != -1) {
+               *out_data_len = rc;
+               rv = CKR_OK;
+       } else {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               DEBUG_openssl_print_errors();
+               rv = CKR_FUNCTION_FAILED;
+       }
+
+       RSA_free(rsa);
+       return rv;
+}
+
+CK_RV
+token_rsa_sw_verify(CK_BYTE   * in_data,
+                   CK_ULONG    in_data_len,
+                   CK_BYTE   * sig,
+                   CK_ULONG    sig_len,
+                   OBJECT    * key_obj)
+{
+       CK_RV   rc;
+       RSA     *rsa;
+       int     nid = 0, in_len, out_len;
+       char    tmp[256];
+
+       if (in_data_len > UINT_MAX || sig_len > UINT_MAX) {
+               in_len = out_len = UINT_MAX;
+       } else {
+               in_len = in_data_len;
+               out_len = sig_len;
+       }
+
+
+       // Convert the local key representation to an RSA key representaion
+       if ((rsa = (RSA *)rsa_convert_public_key(key_obj)) == NULL) {
+               st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
+               return CKR_HOST_MEMORY;
+       }
+
+       rc = RSA_public_decrypt(out_len, sig, tmp, rsa, RSA_PKCS1_PADDING);
+       if (rc == in_len && !memcmp(tmp, in_data, in_len)) {
+               rc = CKR_OK;
+       } else {
+               rc = CKR_SIGNATURE_INVALID;
+       }
+
+       RSA_free(rsa);
+       return rc;
+}
+
 CK_RV
 token_specific_rsa_decrypt( CK_BYTE   * in_data,
                CK_ULONG    in_data_len,
@@ -2613,8 +2896,8 @@ token_specific_rsa_decrypt( CK_BYTE   * in_data,
        BYTE            *buf = NULL;
 
        if ((rc = token_rsa_load_key(key_obj, &hKey))) {
-               LogError("token_rsa_load_key failed. rc=0x%lx", rc);
-               return rc;
+               LogDebug("Not a TPM-based key. Falling back to software");
+               return token_rsa_sw_decrypt(in_data, in_data_len, out_data, 
out_data_len, key_obj);
        }
 
        /* push the data into the encrypted data object */
@@ -2663,8 +2946,8 @@ token_specific_rsa_verify( CK_BYTE   * in_data,
        CK_RV           rc;
 
        if ((rc = token_rsa_load_key(key_obj, &hKey))) {
-               LogError("token_rsa_load_key failed. rc=0x%lx", rc);
-               return rc;
+               LogDebug("Not a TPM-based key. Falling back to software");
+               return token_rsa_sw_verify(in_data, in_data_len, sig, sig_len, 
key_obj);
        }
 
        /* Create the hash object we'll use to sign */
@@ -2697,11 +2980,11 @@ token_specific_rsa_verify( CK_BYTE   * in_data,
 }
 
 CK_RV
-token_specific_rsa_sign( CK_BYTE   * in_data,
-               CK_ULONG    in_data_len,
-               CK_BYTE   * out_data,
-               CK_ULONG  * out_data_len,
-               OBJECT    * key_obj )
+token_specific_rsa_sign(CK_BYTE   * in_data,
+                       CK_ULONG    in_data_len,
+                       CK_BYTE   * out_data,
+                       CK_ULONG  * out_data_len,
+                       OBJECT    * key_obj )
 {
        TSS_RESULT      result;
        TSS_HHASH       hHash;
@@ -2711,8 +2994,8 @@ token_specific_rsa_sign( CK_BYTE   * in_data,
        CK_RV           rc;
 
        if ((rc = token_rsa_load_key(key_obj, &hKey))) {
-               LogError("token_rsa_load_key failed. rc=0x%lx", rc);
-               return rc;
+               LogDebug("Not a TPM-based key. Falling back to software");
+               return token_rsa_sw_sign(in_data, in_data_len, out_data, 
out_data_len, key_obj);
        }
 
        /* Create the hash object we'll use to sign */
@@ -2763,8 +3046,8 @@ token_specific_rsa_encrypt( CK_BYTE   * in_data,
        CK_RV           rc;
 
        if ((rc = token_rsa_load_key(key_obj, &hKey))) {
-               LogError("token_rsa_load_key failed. rc=0x%lx", rc);
-               return rc;
+               LogDebug("Not a TPM-based key. Falling back to software");
+               return token_rsa_sw_encrypt(in_data, in_data_len, out_data, 
out_data_len, key_obj);
        }
 
        if ((result = Tspi_Context_CreateObject(tspContext, 
TSS_OBJECT_TYPE_ENCDATA,
-- 
1.7.4.rc1


------------------------------------------------------------------------------
Gaining the trust of online customers is vital for the success of any company
that requires sensitive data to be transmitted over the Web.   Learn how to 
best implement a security strategy that keeps consumers' information secure 
and instills the confidence they need to proceed with transactions.
http://p.sf.net/sfu/oracle-sfdevnl 
_______________________________________________
Opencryptoki-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech

Reply via email to