From 847b0b426731a3e61b0477a42f5836e5041b5e7a Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Sun, 26 Mar 2017 19:13:07 +0200 Subject: [PATCH 1/2] fix PSS signing support --- ykcs11/mechanisms.c | 11 ++--------- ykcs11/openssl_utils.c | 12 +++++------- ykcs11/ykcs11.c | 24 ++++++++++++++++++++---- ykcs11/ykcs11.h | 2 +- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/ykcs11/mechanisms.c b/ykcs11/mechanisms.c index 59d5971..a143bf9 100644 --- a/ykcs11/mechanisms.c +++ b/ykcs11/mechanisms.c @@ -262,7 +262,6 @@ CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) { CK_RV rv; int nid = NID_undef; - RSA *rsa; CK_ULONG len; if (op_info->type != YKCS11_SIGN) @@ -282,14 +281,8 @@ CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) { case CKM_RSA_PKCS_PSS: // Compute padding for all PSS variants // TODO: digestinfo/paraminfo ? - - rv = do_encode_rsa_public_key(op_info->op.sign.key, op_info->op.sign.key_len, &rsa); - if (rv != CKR_OK) - return CKR_FUNCTION_FAILED; - - rv = do_pkcs_pss(rsa, op_info->buf, op_info->buf_len, nid, op_info->buf, &op_info->buf_len); - - // TODO: does rsa have to be free'd ? + rv = do_pkcs_pss(op_info->op.sign.key, op_info->buf, op_info->buf_len, nid, op_info->buf, &op_info->buf_len); + RSA_free(op_info->op.sign.key); return rv; diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index 2ee92e6..2495e5b 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -557,16 +557,13 @@ CK_RV do_pkcs_1_digest_info(CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PT CK_RV do_pkcs_pss(RSA *key, CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PTR out, CK_ULONG_PTR out_len) { - unsigned char em[512]; // Max for this is ceil((|key_len_bits| - 1) / 8) + unsigned char em[RSA_size(key)]; OpenSSL_add_all_digests(); + DBG("Apply PSS padding to %lu bytes and get %d", in_len, RSA_size(key)); + // TODO: rand must be seeded first (should be automatic) - if (*out_len < (CK_ULONG)RSA_size(key)) - return CKR_BUFFER_TOO_SMALL; - - DBG("Apply PSS padding to %lu bytes and get %d\n", in_len, RSA_size(key)); - if (out != in) memcpy(out, in, in_len); @@ -576,7 +573,8 @@ CK_RV do_pkcs_pss(RSA *key, CK_BYTE_PTR in, CK_ULONG in_len, int nid, return CKR_FUNCTION_FAILED; } - *out_len = (CK_ULONG) RSA_size(key); + memcpy(out, em, sizeof(em)); + *out_len = (CK_ULONG) sizeof(em); EVP_cleanup(); diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 942c8c0..337fbae 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -1687,11 +1687,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)( { CK_KEY_TYPE type = 0; CK_ULONG key_len = 0; + CK_BYTE exp[3]; CK_BYTE buf[1024]; CK_ATTRIBUTE template[] = { {CKA_KEY_TYPE, &type, sizeof(type)}, {CKA_MODULUS_BITS, &key_len, sizeof(key_len)}, {CKA_MODULUS, NULL, 0}, + {CKA_PUBLIC_EXPONENT, exp, sizeof(exp)}, {CKA_EC_POINT, buf, sizeof(buf)}, }; @@ -1754,18 +1756,32 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)( // Also store the raw public key if the mechanism is PSS if (is_PSS_mechanism(pMechanism->mechanism)) { - op_info.op.sign.key = malloc(key_len); + op_info.op.sign.key = RSA_new(); if (op_info.op.sign.key == NULL) return CKR_HOST_MEMORY; - template[2].pValue = op_info.op.sign.key; - template[2].ulValueLen = key_len; + template[2].pValue = buf; + template[2].ulValueLen = (key_len + 7) / 8 ; if (get_attribute(&session, hKey, template + 2) != CKR_OK) { DBG("Unable to get public key"); return CKR_KEY_HANDLE_INVALID; } + op_info.op.sign.key->n = BN_bin2bn(buf, (key_len + 7) / 8, NULL); + if(op_info.op.sign.key->n == NULL) { + DBG("Failed to parse public key modulus."); + return CKR_KEY_HANDLE_INVALID; + } + if (get_attribute(&session, hKey, template + 3) != CKR_OK) { + DBG("Unable to get public exponent"); + return CKR_KEY_HANDLE_INVALID; + } + op_info.op.sign.key->e = BN_bin2bn(exp, sizeof(exp), NULL); + if(op_info.op.sign.key->e == NULL) { + DBG("Failed to parse public key exponent."); + return CKR_KEY_HANDLE_INVALID; + } } else { op_info.op.sign.key = NULL; @@ -1774,7 +1790,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)( } else { // ECDSA key - if (get_attribute(&session, hKey, template + 3) != CKR_OK) { + if (get_attribute(&session, hKey, template + 4) != CKR_OK) { DBG("Unable to get key length"); return CKR_KEY_HANDLE_INVALID; } diff --git a/ykcs11/ykcs11.h b/ykcs11/ykcs11.h index 755e50b..98d7237 100644 --- a/ykcs11/ykcs11.h +++ b/ykcs11/ykcs11.h @@ -75,7 +75,7 @@ typedef struct { typedef struct { ykcs11_md_ctx_t *md_ctx; // Digest context - CK_BYTE_PTR key; // Raw public key (needed for PSS) + RSA *key; // Raw public key (needed for PSS) CK_BYTE algo; // Algo for ykpiv // TODO: infer this from the key length? CK_ULONG key_id; // Key id for ykpiv // TODO: make this a BYTE and store the id {0, 1, 2, 3} CK_ULONG key_len; // Length in bits From 03849d9722b38ef782084479d4ad443a1dc8d3a1 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 29 Mar 2017 23:01:17 +0100 Subject: [PATCH 2/2] alias RSA type, call openssl functions only in openssl_utils.c --- ykcs11/mechanisms.c | 2 +- ykcs11/openssl_types.h | 2 ++ ykcs11/openssl_utils.c | 28 +++++++++++++++++++--------- ykcs11/openssl_utils.h | 4 +++- ykcs11/ykcs11.c | 17 ++++------------- ykcs11/ykcs11.h | 2 +- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/ykcs11/mechanisms.c b/ykcs11/mechanisms.c index a143bf9..1fc6339 100644 --- a/ykcs11/mechanisms.c +++ b/ykcs11/mechanisms.c @@ -282,7 +282,7 @@ CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) { // Compute padding for all PSS variants // TODO: digestinfo/paraminfo ? rv = do_pkcs_pss(op_info->op.sign.key, op_info->buf, op_info->buf_len, nid, op_info->buf, &op_info->buf_len); - RSA_free(op_info->op.sign.key); + do_free_rsa_public_key(op_info->op.sign.key); return rv; diff --git a/ykcs11/openssl_types.h b/ykcs11/openssl_types.h index 883e6e6..307f746 100644 --- a/ykcs11/openssl_types.h +++ b/ykcs11/openssl_types.h @@ -50,4 +50,6 @@ typedef enum { typedef EVP_MD_CTX ykcs11_md_ctx_t; //typedef EVP_PKEY ykcs11_evp_pkey_t; +typedef RSA ykcs11_rsa_key_t; + #endif diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index 2495e5b..4ceb704 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -467,18 +467,28 @@ CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) { } -CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key) { - - const unsigned char *p = data; - - if (data == NULL) +CK_RV do_encode_rsa_public_key(ykcs11_rsa_key_t **key, CK_BYTE_PTR modulus, + CK_ULONG mlen, CK_BYTE_PTR exponent, CK_ULONG elen) { + ykcs11_rsa_key_t *k; + if (modulus == NULL || exponent == NULL) return CKR_ARGUMENTS_BAD; - if ((*key = d2i_RSAPublicKey(NULL, &p, (long) len)) == NULL) + if ((k = RSA_new()) == NULL) + return CKR_HOST_MEMORY; + + if ((k->n = BN_bin2bn(modulus, mlen, NULL)) == NULL) return CKR_FUNCTION_FAILED; - return CKR_OK; + if ((k->e = BN_bin2bn(exponent, elen, NULL)) == NULL) + return CKR_FUNCTION_FAILED; + *key = k; + return CKR_OK; +} + +CK_RV do_free_rsa_public_key(ykcs11_rsa_key_t *key) { + RSA_free(key); + return CKR_OK; } CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) { @@ -555,8 +565,8 @@ CK_RV do_pkcs_1_digest_info(CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PT } -CK_RV do_pkcs_pss(RSA *key, CK_BYTE_PTR in, CK_ULONG in_len, int nid, - CK_BYTE_PTR out, CK_ULONG_PTR out_len) { +CK_RV do_pkcs_pss(ykcs11_rsa_key_t *key, CK_BYTE_PTR in, CK_ULONG in_len, + int nid, CK_BYTE_PTR out, CK_ULONG_PTR out_len) { unsigned char em[RSA_size(key)]; OpenSSL_add_all_digests(); diff --git a/ykcs11/openssl_utils.h b/ykcs11/openssl_utils.h index 34497ae..08f2e0d 100644 --- a/ykcs11/openssl_utils.h +++ b/ykcs11/openssl_utils.h @@ -53,11 +53,13 @@ CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key); CK_RV do_get_public_exponent(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len); CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len); CK_RV do_get_modulus(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len); -CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key); CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len); CK_RV do_delete_pubk(EVP_PKEY **key); //CK_RV free_key(EVP_PKEY *key); +CK_RV do_encode_rsa_public_key(ykcs11_rsa_key_t **key, CK_BYTE_PTR modulus, CK_ULONG mlen, CK_BYTE_PTR exponent, CK_ULONG elen); +CK_RV do_free_rsa_public_key(ykcs11_rsa_key_t *key); + CK_RV do_pkcs_1_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len, CK_ULONG key_len); CK_RV do_pkcs_1_digest_info(CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PTR out, CK_ULONG_PTR out_len); diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 337fbae..8374ec6 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -38,6 +38,7 @@ #include "utils.h" #include "mechanisms.h" #include "openssl_types.h" +#include "openssl_utils.h" #include "debug.h" #include @@ -1756,10 +1757,6 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)( // Also store the raw public key if the mechanism is PSS if (is_PSS_mechanism(pMechanism->mechanism)) { - op_info.op.sign.key = RSA_new(); - if (op_info.op.sign.key == NULL) - return CKR_HOST_MEMORY; - template[2].pValue = buf; template[2].ulValueLen = (key_len + 7) / 8 ; @@ -1767,20 +1764,14 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)( DBG("Unable to get public key"); return CKR_KEY_HANDLE_INVALID; } - op_info.op.sign.key->n = BN_bin2bn(buf, (key_len + 7) / 8, NULL); - if(op_info.op.sign.key->n == NULL) { - DBG("Failed to parse public key modulus."); - return CKR_KEY_HANDLE_INVALID; - } if (get_attribute(&session, hKey, template + 3) != CKR_OK) { DBG("Unable to get public exponent"); return CKR_KEY_HANDLE_INVALID; } - op_info.op.sign.key->e = BN_bin2bn(exp, sizeof(exp), NULL); - if(op_info.op.sign.key->e == NULL) { - DBG("Failed to parse public key exponent."); - return CKR_KEY_HANDLE_INVALID; + + if (do_encode_rsa_public_key(&op_info.op.sign.key, buf, (key_len + 7) / 8, exp, sizeof(exp)) != CKR_OK) { + return CKR_FUNCTION_FAILED; } } else { diff --git a/ykcs11/ykcs11.h b/ykcs11/ykcs11.h index 98d7237..b0c5cfa 100644 --- a/ykcs11/ykcs11.h +++ b/ykcs11/ykcs11.h @@ -75,7 +75,7 @@ typedef struct { typedef struct { ykcs11_md_ctx_t *md_ctx; // Digest context - RSA *key; // Raw public key (needed for PSS) + ykcs11_rsa_key_t *key; // Raw public key (needed for PSS) CK_BYTE algo; // Algo for ykpiv // TODO: infer this from the key length? CK_ULONG key_id; // Key id for ykpiv // TODO: make this a BYTE and store the id {0, 1, 2, 3} CK_ULONG key_len; // Length in bits