Added PSS (first stab).
This commit is contained in:
+73
-12
@@ -83,6 +83,25 @@ CK_BBOOL is_RSA_mechanism(CK_MECHANISM_TYPE m) {
|
|||||||
return CK_FALSE;
|
return CK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_BBOOL is_PSS_mechanism(CK_MECHANISM_TYPE m) {
|
||||||
|
|
||||||
|
switch (m) {
|
||||||
|
case CKM_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA1_RSA_PKCS_PSS:
|
||||||
|
// case CKM_SHA224_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA256_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA512_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA384_RSA_PKCS_PSS:
|
||||||
|
return CK_TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CK_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not reached
|
||||||
|
return CK_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
CK_RV apply_sign_mechanism_init(op_info_t *op_info) {
|
CK_RV apply_sign_mechanism_init(op_info_t *op_info) {
|
||||||
|
|
||||||
if (op_info->type != YKCS11_SIGN)
|
if (op_info->type != YKCS11_SIGN)
|
||||||
@@ -93,31 +112,36 @@ CK_RV apply_sign_mechanism_init(op_info_t *op_info) {
|
|||||||
// No hash required for this mechanism
|
// No hash required for this mechanism
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
case CKM_RSA_PKCS_PSS: // TODO
|
case CKM_RSA_PKCS_PSS:
|
||||||
return CKR_FUNCTION_FAILED;
|
// No hash required for this mechanism
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
case CKM_RSA_X_509:
|
case CKM_RSA_X_509:
|
||||||
// No hash required for this mechanism
|
// No hash required for this mechanism
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
case CKM_SHA1_RSA_PKCS:
|
case CKM_SHA1_RSA_PKCS:
|
||||||
|
case CKM_SHA1_RSA_PKCS_PSS:
|
||||||
case CKM_ECDSA_SHA1:
|
case CKM_ECDSA_SHA1:
|
||||||
return do_md_init(YKCS11_SHA1, &op_info->op.sign.md_ctx);
|
return do_md_init(YKCS11_SHA1, &op_info->op.sign.md_ctx);
|
||||||
|
|
||||||
case CKM_SHA256_RSA_PKCS:
|
case CKM_SHA256_RSA_PKCS:
|
||||||
|
case CKM_SHA256_RSA_PKCS_PSS:
|
||||||
return do_md_init(YKCS11_SHA256, &op_info->op.sign.md_ctx);
|
return do_md_init(YKCS11_SHA256, &op_info->op.sign.md_ctx);
|
||||||
|
|
||||||
case CKM_SHA384_RSA_PKCS:
|
case CKM_SHA384_RSA_PKCS:
|
||||||
|
case CKM_SHA384_RSA_PKCS_PSS:
|
||||||
return do_md_init(YKCS11_SHA384, &op_info->op.sign.md_ctx);
|
return do_md_init(YKCS11_SHA384, &op_info->op.sign.md_ctx);
|
||||||
|
|
||||||
case CKM_SHA512_RSA_PKCS:
|
case CKM_SHA512_RSA_PKCS:
|
||||||
|
case CKM_SHA512_RSA_PKCS_PSS:
|
||||||
return do_md_init(YKCS11_SHA512, &op_info->op.sign.md_ctx);
|
return do_md_init(YKCS11_SHA512, &op_info->op.sign.md_ctx);
|
||||||
|
|
||||||
case CKM_ECDSA:
|
case CKM_ECDSA:
|
||||||
return CKR_FUNCTION_FAILED; // TODO: but no hash needed
|
return CKR_FUNCTION_FAILED; // TODO: but no hash needed
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never reached
|
// Never reached
|
||||||
@@ -132,9 +156,8 @@ CK_RV apply_sign_mechanism_update(op_info_t *op_info, CK_BYTE_PTR in, CK_ULONG i
|
|||||||
|
|
||||||
switch (op_info->mechanism.mechanism) {
|
switch (op_info->mechanism.mechanism) {
|
||||||
case CKM_RSA_PKCS:
|
case CKM_RSA_PKCS:
|
||||||
return CKR_OK;
|
|
||||||
|
|
||||||
case CKM_RSA_PKCS_PSS:
|
case CKM_RSA_PKCS_PSS:
|
||||||
|
// Mechanism not suitable for multipart signatures
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
case CKM_RSA_X_509:
|
case CKM_RSA_X_509:
|
||||||
@@ -144,6 +167,10 @@ CK_RV apply_sign_mechanism_update(op_info_t *op_info, CK_BYTE_PTR in, CK_ULONG i
|
|||||||
case CKM_SHA256_RSA_PKCS:
|
case CKM_SHA256_RSA_PKCS:
|
||||||
case CKM_SHA384_RSA_PKCS:
|
case CKM_SHA384_RSA_PKCS:
|
||||||
case CKM_SHA512_RSA_PKCS:
|
case CKM_SHA512_RSA_PKCS:
|
||||||
|
case CKM_SHA1_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA256_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA384_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA512_RSA_PKCS_PSS:
|
||||||
case CKM_ECDSA_SHA1:
|
case CKM_ECDSA_SHA1:
|
||||||
rv = do_md_update(op_info->op.sign.md_ctx, in, in_len);
|
rv = do_md_update(op_info->op.sign.md_ctx, in, in_len);
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
@@ -160,18 +187,40 @@ CK_RV apply_sign_mechanism_update(op_info_t *op_info, CK_BYTE_PTR in, CK_ULONG i
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) {
|
CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) {
|
||||||
|
|
||||||
CK_RV rv;
|
CK_RV rv;
|
||||||
|
int nid = NID_undef;
|
||||||
|
RSA *rsa;
|
||||||
|
CK_ULONG len;
|
||||||
|
|
||||||
if (op_info->type != YKCS11_SIGN)
|
if (op_info->type != YKCS11_SIGN)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
switch (op_info->mechanism.mechanism) {
|
switch (op_info->mechanism.mechanism) {
|
||||||
case CKM_RSA_PKCS_PSS:
|
case CKM_SHA1_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA256_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA384_RSA_PKCS_PSS:
|
||||||
|
case CKM_SHA512_RSA_PKCS_PSS:
|
||||||
|
// Finalize the hash
|
||||||
|
rv = do_md_finalize(op_info->op.sign.md_ctx, op_info->buf, &op_info->buf_len, &nid);
|
||||||
|
if (rv != CKR_OK)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
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 ?
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
|
||||||
case CKM_RSA_X_509:
|
case CKM_RSA_X_509:
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
@@ -179,18 +228,30 @@ CK_RV apply_sign_mechanism_finalize(op_info_t *op_info) {
|
|||||||
case CKM_SHA256_RSA_PKCS:
|
case CKM_SHA256_RSA_PKCS:
|
||||||
case CKM_SHA384_RSA_PKCS:
|
case CKM_SHA384_RSA_PKCS:
|
||||||
case CKM_SHA512_RSA_PKCS:
|
case CKM_SHA512_RSA_PKCS:
|
||||||
case CKM_ECDSA_SHA1:
|
// Finalize the hash add digest info
|
||||||
// Finalize the hash if needed and add digest info
|
rv = do_md_finalize(op_info->op.sign.md_ctx, op_info->buf, &op_info->buf_len, &nid);
|
||||||
rv = do_md_finalize(op_info->op.sign.md_ctx, CK_TRUE, op_info->buf, &op_info->buf_len);
|
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
fprintf(stderr, "The hashed value is %lu long and looks like\n", op_info->buf_len);
|
fprintf(stderr, "The hashed value is %lu long and looks like\n", op_info->buf_len);
|
||||||
dump_hex(op_info->buf, op_info->buf_len, stderr, CK_TRUE);
|
dump_hex(op_info->buf, op_info->buf_len, stderr, CK_TRUE);
|
||||||
|
|
||||||
case CKM_RSA_PKCS:
|
case CKM_RSA_PKCS:
|
||||||
// And compute padding for all pkcs1 variants
|
// Add digest info if needed
|
||||||
return do_pkcs_t1(op_info->buf, op_info->buf_len, op_info->buf, sizeof(op_info->buf), op_info->op.sign.key_len);
|
if (nid != NID_undef) {
|
||||||
|
rv = do_pkcs_1_digest_info(op_info->buf, op_info->buf_len, nid, op_info->buf, &op_info->buf_len);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
fprintf(stderr, "After adding digestinfo is %lu long and looks like\n", op_info->buf_len);
|
||||||
|
dump_hex(op_info->buf, op_info->buf_len, stderr, CK_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute padding for all PKCS1 variants
|
||||||
|
len = op_info->buf_len;
|
||||||
|
op_info->buf_len = sizeof(op_info->buf);
|
||||||
|
return do_pkcs_1_t1(op_info->buf, len, op_info->buf, &op_info->buf_len, op_info->op.sign.key_len);
|
||||||
|
|
||||||
|
case CKM_ECDSA_SHA1: // TODO:
|
||||||
case CKM_ECDSA:
|
case CKM_ECDSA:
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
CK_RV check_sign_mechanism(const ykcs11_session_t *s, CK_MECHANISM_PTR m);
|
CK_RV check_sign_mechanism(const ykcs11_session_t *s, CK_MECHANISM_PTR m);
|
||||||
CK_BBOOL is_RSA_mechanism(CK_MECHANISM_TYPE m);
|
CK_BBOOL is_RSA_mechanism(CK_MECHANISM_TYPE m);
|
||||||
|
CK_BBOOL is_PSS_mechanism(CK_MECHANISM_TYPE m);
|
||||||
|
|
||||||
CK_RV apply_sign_mechanism_init(op_info_t *op_info);
|
CK_RV apply_sign_mechanism_init(op_info_t *op_info);
|
||||||
CK_RV apply_sign_mechanism_update(op_info_t *op_info, CK_BYTE_PTR in, CK_ULONG in_len);
|
CK_RV apply_sign_mechanism_update(op_info_t *op_info, CK_BYTE_PTR in, CK_ULONG in_len);
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ typedef struct { // TODO: enough to use the public key for the parameters?
|
|||||||
} piv_pvtk_obj_t;
|
} piv_pvtk_obj_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EVP_PKEY *data;
|
EVP_PKEY *data; // TODO: make custo type for this and X509
|
||||||
} piv_pubk_obj_t;
|
} piv_pubk_obj_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
+8
-1
@@ -653,7 +653,14 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
|
|||||||
fprintf(stderr, "END DATE TODO\n"); // Default empty
|
fprintf(stderr, "END DATE TODO\n"); // Default empty
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
/*case CKA_MODULUS:*/
|
case CKA_MODULUS:
|
||||||
|
fprintf(stderr, "MODULUS\n");
|
||||||
|
len = sizeof(b_tmp);
|
||||||
|
if (get_public_key(pubkey_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
data = b_tmp;
|
||||||
|
break;
|
||||||
|
|
||||||
case CKA_EC_POINT:
|
case CKA_EC_POINT:
|
||||||
// We're trying to get the key length, get the ec point of the PUBLIC key
|
// We're trying to get the key length, get the ec point of the PUBLIC key
|
||||||
// TODO: or just give an error and explicitly fetch the pubk len when needed
|
// TODO: or just give an error and explicitly fetch the pubk len when needed
|
||||||
|
|||||||
@@ -18,5 +18,6 @@ typedef enum {
|
|||||||
} hash_t;
|
} hash_t;
|
||||||
|
|
||||||
typedef EVP_MD_CTX ykcs11_md_ctx_t;
|
typedef EVP_MD_CTX ykcs11_md_ctx_t;
|
||||||
|
//typedef EVP_PKEY ykcs11_evp_pkey_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+87
-14
@@ -89,8 +89,10 @@ CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key) {
|
|||||||
CK_RV do_get_public_key(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) {
|
||||||
|
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
EC_KEY *eck;
|
EC_KEY *eck;
|
||||||
const EC_GROUP *ecg; // Alternatice solution is to get i2d_PUBKEY and manually offset
|
const EC_GROUP *ecg; // Alternative solution is to get i2d_PUBKEY and manually offset
|
||||||
const EC_POINT *ecp;
|
const EC_POINT *ecp;
|
||||||
point_conversion_form_t pcf = POINT_CONVERSION_UNCOMPRESSED;
|
point_conversion_form_t pcf = POINT_CONVERSION_UNCOMPRESSED;
|
||||||
|
|
||||||
@@ -99,7 +101,23 @@ CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len) {
|
|||||||
case EVP_PKEY_RSA2:
|
case EVP_PKEY_RSA2:
|
||||||
|
|
||||||
rsa = EVP_PKEY_get1_RSA(key);
|
rsa = EVP_PKEY_get1_RSA(key);
|
||||||
return CKR_FUNCTION_FAILED; // TODO;
|
|
||||||
|
if (RSA_size(rsa) > *len)
|
||||||
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
p = data;
|
||||||
|
|
||||||
|
if ((*len = i2d_RSAPublicKey(rsa, &p)) == 0)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
// TODO: this is the correct thing to do so that we strip out the exponent
|
||||||
|
// OTOH we also need a function to get the exponent out with CKA_PUBLIC_EXPONENT
|
||||||
|
/*BN_bn2bin(rsa->n, data);
|
||||||
|
*len = 256;*/
|
||||||
|
|
||||||
|
fprintf(stderr, "Public key is: \n");
|
||||||
|
dump_hex(data, *len, stderr, CK_TRUE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
@@ -119,6 +137,20 @@ 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)
|
||||||
|
return CKR_ARGUMENTS_BAD;
|
||||||
|
|
||||||
|
if ((*key = d2i_RSAPublicKey(NULL, &p, len)) == NULL)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
CK_RV free_key(EVP_PKEY *key) {
|
CK_RV free_key(EVP_PKEY *key) {
|
||||||
|
|
||||||
EVP_PKEY_free(key);
|
EVP_PKEY_free(key);
|
||||||
@@ -127,16 +159,52 @@ CK_RV free_key(EVP_PKEY *key) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV do_pkcs_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len) {
|
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) {
|
||||||
|
key_len /= 8;
|
||||||
fprintf(stderr, "Apply padding to %lu bytes and get %lu\n", in_len, key_len);
|
fprintf(stderr, "Apply padding to %lu bytes and get %lu\n", in_len, key_len);
|
||||||
|
|
||||||
// TODO: rand must be seeded first (should be automatic)
|
// TODO: rand must be seeded first (should be automatic)
|
||||||
if (out_len < key_len)
|
if (*out_len < key_len)
|
||||||
CKR_BUFFER_TOO_SMALL;
|
CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
if (RSA_padding_add_PKCS1_type_1(out, key_len, in, in_len) == 0)
|
if (RSA_padding_add_PKCS1_type_1(out, key_len, in, in_len) == 0)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
*out_len = key_len;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
unsigned int len;
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
rv = prepare_rsa_signature(in, in_len, out, &len, nid);
|
||||||
|
if (!rv)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
*out_len = len;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
// TODO: rand must be seeded first (should be automatic)
|
||||||
|
if (*out_len < RSA_size(key))
|
||||||
|
CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
fprintf(stderr, "Apply PSS padding to %lu bytes and get %d\n", in_len, RSA_size(key));
|
||||||
|
|
||||||
|
if (RSA_padding_add_PKCS1_PSS(key, em, in, EVP_get_digestbynid(nid), -2) == 0)
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
*out_len = RSA_size(key);
|
||||||
|
printf("hello!!!!!!!\n");
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +245,7 @@ CK_RV do_md_init(hash_t hash, ykcs11_md_ctx_t **ctx) {
|
|||||||
|
|
||||||
// The OpenSSL function above never fail
|
// The OpenSSL function above never fail
|
||||||
if (EVP_DigestInit_ex(*ctx, md, NULL) == 0) {
|
if (EVP_DigestInit_ex(*ctx, md, NULL) == 0) {
|
||||||
EVP_MD_CTX_destroy(*ctx);
|
EVP_MD_CTX_destroy((EVP_MD_CTX *)*ctx);
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,27 +254,32 @@ CK_RV do_md_init(hash_t hash, ykcs11_md_ctx_t **ctx) {
|
|||||||
|
|
||||||
CK_RV do_md_update(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR in, CK_ULONG in_len) {
|
CK_RV do_md_update(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR in, CK_ULONG in_len) {
|
||||||
|
|
||||||
return EVP_DigestUpdate(ctx, in, in_len) == 1 ? CKR_OK : CKR_FUNCTION_FAILED;
|
if (EVP_DigestUpdate(ctx, in, in_len) != 1) {
|
||||||
|
EVP_MD_CTX_destroy(ctx);
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV do_md_finalize(ykcs11_md_ctx_t *ctx, CK_BBOOL di, CK_BYTE_PTR out, CK_ULONG_PTR out_len) {
|
CK_RV do_md_finalize(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR out, CK_ULONG_PTR out_len, int *nid) {
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
bool rv2;
|
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
// Keep track of the md type if requested
|
||||||
|
if (nid != NULL)
|
||||||
|
*nid = EVP_MD_CTX_type(ctx);
|
||||||
|
|
||||||
// Finalize digest and store result
|
// Finalize digest and store result
|
||||||
rv = EVP_DigestFinal_ex(ctx, out, (unsigned int *)out_len);
|
rv = EVP_DigestFinal_ex(ctx, out, &len);
|
||||||
// Check wheter digest info is required
|
|
||||||
if (di == CK_TRUE)
|
|
||||||
rv2 = prepare_rsa_signature(out, *out_len, out, &len, EVP_MD_CTX_type(ctx));
|
|
||||||
|
|
||||||
// Destroy the md context
|
// Destroy the md context
|
||||||
EVP_MD_CTX_destroy(ctx);
|
EVP_MD_CTX_destroy(ctx);
|
||||||
|
|
||||||
// Error if either of the previous calls failed
|
// Error if the previous call failed
|
||||||
if (rv != 1 || !rv2)
|
if (rv != 1)
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
*out_len = len;
|
*out_len = len;
|
||||||
|
|||||||
@@ -16,12 +16,17 @@ CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key);
|
|||||||
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
||||||
CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key);
|
CK_ULONG do_get_rsa_modulus_length(EVP_PKEY *key);
|
||||||
CK_RV do_get_public_key(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_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key);
|
||||||
CK_RV free_key(EVP_PKEY *key);
|
CK_RV free_key(EVP_PKEY *key);
|
||||||
|
|
||||||
CK_RV do_pkcs_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG out_len, CK_ULONG key_len);
|
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);
|
||||||
|
|
||||||
|
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_md_init(hash_t hash, ykcs11_md_ctx_t **ctx);
|
CK_RV do_md_init(hash_t hash, ykcs11_md_ctx_t **ctx);
|
||||||
CK_RV do_md_update(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR in, CK_ULONG in_len);
|
CK_RV do_md_update(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR in, CK_ULONG in_len);
|
||||||
CK_RV do_md_finalize(ykcs11_md_ctx_t *ctx, CK_BBOOL di, CK_BYTE_PTR out, CK_ULONG_PTR out_len);
|
CK_RV do_md_finalize(ykcs11_md_ctx_t *ctx, CK_BYTE_PTR out, CK_ULONG_PTR out_len, int *nid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+29
-7
@@ -1215,7 +1215,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
CK_ATTRIBUTE template[] = {
|
CK_ATTRIBUTE template[] = {
|
||||||
{CKA_KEY_TYPE, &type, sizeof(type)},
|
{CKA_KEY_TYPE, &type, sizeof(type)},
|
||||||
{CKA_MODULUS_BITS, &key_len, sizeof(key_len)},
|
{CKA_MODULUS_BITS, &key_len, sizeof(key_len)},
|
||||||
{CKA_EC_POINT, buf, sizeof(buf)}
|
{CKA_MODULUS, NULL, 0},
|
||||||
|
{CKA_EC_POINT, buf, sizeof(buf)},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (piv_state == NULL) {
|
if (piv_state == NULL) {
|
||||||
@@ -1267,17 +1268,36 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
else
|
else
|
||||||
op_info.op.sign.algo = YKPIV_ALGO_RSA2048;
|
op_info.op.sign.algo = YKPIV_ALGO_RSA2048;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
if (op_info.op.sign.key == NULL)
|
||||||
|
return CKR_HOST_MEMORY;
|
||||||
|
|
||||||
|
template[2].pValue = op_info.op.sign.key;
|
||||||
|
template[2].ulValueLen = key_len;
|
||||||
|
|
||||||
|
if (get_attribute(&session, hKey, template + 2) != CKR_OK) {
|
||||||
|
DBG(("Unable to get public key"));
|
||||||
|
return CKR_KEY_HANDLE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
op_info.op.sign.key = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// ECDSA key
|
// ECDSA key
|
||||||
if (get_attribute(&session, hKey, template + 2) != CKR_OK) {
|
if (get_attribute(&session, hKey, template + 3) != CKR_OK) {
|
||||||
DBG(("Unable to get key length"));
|
DBG(("Unable to get key length"));
|
||||||
return CKR_KEY_HANDLE_INVALID;
|
return CKR_KEY_HANDLE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The buffer contains an uncompressed point of the form 04, x, y
|
// The buffer contains an uncompressed point of the form 04, x, y
|
||||||
// TODO: is this a fine representation for an EC public key?
|
// TODO: is this a fine representation for an EC public key?
|
||||||
op_info.op.sign.key_len = ((template[2].ulValueLen - 1) / 2) * 8;
|
op_info.op.sign.key_len = ((template[3].ulValueLen - 1) / 2) * 8;
|
||||||
|
|
||||||
if (op_info.op.sign.key_len == 256)
|
if (op_info.op.sign.key_len == 256)
|
||||||
op_info.op.sign.algo = YKPIV_ALGO_ECCP256;
|
op_info.op.sign.algo = YKPIV_ALGO_ECCP256;
|
||||||
@@ -1289,8 +1309,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
|
|
||||||
DBG(("Key length is %lu bit", op_info.op.sign.key_len));
|
DBG(("Key length is %lu bit", op_info.op.sign.key_len));
|
||||||
|
|
||||||
op_info.op.sign.key = piv_2_ykpiv(hKey);
|
op_info.op.sign.key_id = piv_2_ykpiv(hKey);
|
||||||
if (op_info.op.sign.key == 0) {
|
if (op_info.op.sign.key_id == 0) {
|
||||||
DBG(("Incorrect key %lu", hKey));
|
DBG(("Incorrect key %lu", hKey));
|
||||||
return CKR_KEY_HANDLE_INVALID;
|
return CKR_KEY_HANDLE_INVALID;
|
||||||
}
|
}
|
||||||
@@ -1305,6 +1325,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_SignInit)(
|
|||||||
|
|
||||||
op_info.type = YKCS11_SIGN;
|
op_info.type = YKCS11_SIGN;
|
||||||
|
|
||||||
|
// TODO: check mechanism parameters and key length and key supported parameters
|
||||||
|
|
||||||
if (apply_sign_mechanism_init(&op_info) != CKR_OK) {
|
if (apply_sign_mechanism_init(&op_info) != CKR_OK) {
|
||||||
DBG(("Unable to initialize signing operation"));
|
DBG(("Unable to initialize signing operation"));
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
@@ -1347,8 +1369,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
}
|
}
|
||||||
//dump_hex(buf, 256, stderr, CK_TRUE);
|
//dump_hex(buf, 256, stderr, CK_TRUE);
|
||||||
//*pulSignatureLen = 256;
|
//*pulSignatureLen = 256;
|
||||||
DBG(("Using key %lx", op_info.op.sign.key)); // TODO: test what happens if there is no key on the card
|
DBG(("Using key %lx", op_info.op.sign.key_id)); // TODO: test what happens if there is no key on the card
|
||||||
if ((r = ykpiv_sign_data(piv_state, op_info.buf, ulDataLen, pSignature, pulSignatureLen, op_info.op.sign.algo, op_info.op.sign.key)) != YKPIV_OK) {
|
if ((r = ykpiv_sign_data(piv_state, op_info.buf, ulDataLen, pSignature, pulSignatureLen, op_info.op.sign.algo, op_info.op.sign.key_id)) != YKPIV_OK) {
|
||||||
DBG(("Sign error, %s", ykpiv_strerror(r)));
|
DBG(("Sign error, %s", ykpiv_strerror(r)));
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -37,10 +37,11 @@ typedef enum {
|
|||||||
} ykcs11_op_type_t;
|
} ykcs11_op_type_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ykcs11_md_ctx_t *md_ctx;
|
ykcs11_md_ctx_t *md_ctx; // Digest context
|
||||||
CK_BYTE algo;
|
CK_BYTE_PTR key; // Raw public key (needed for PSS)
|
||||||
CK_ULONG key;
|
CK_BYTE algo; // Algo for ykpiv
|
||||||
CK_ULONG key_len;
|
CK_ULONG key_id; // Key id for ykpiv
|
||||||
|
CK_ULONG key_len; // Length in bits
|
||||||
} sign_info_t;
|
} sign_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ static const CK_BYTE_PTR token_serial = "1234";
|
|||||||
static const CK_MECHANISM_TYPE token_mechanisms[] = { // KEEP ALIGNED WITH token_mechanism_infos
|
static const CK_MECHANISM_TYPE token_mechanisms[] = { // KEEP ALIGNED WITH token_mechanism_infos
|
||||||
CKM_RSA_PKCS_KEY_PAIR_GEN,
|
CKM_RSA_PKCS_KEY_PAIR_GEN,
|
||||||
CKM_RSA_PKCS,
|
CKM_RSA_PKCS,
|
||||||
// CKM_RSA_PKCS_PSS,
|
CKM_RSA_PKCS_PSS,
|
||||||
CKM_RSA_X_509,
|
CKM_RSA_X_509,
|
||||||
CKM_SHA1_RSA_PKCS,
|
CKM_SHA1_RSA_PKCS,
|
||||||
CKM_SHA256_RSA_PKCS,
|
CKM_SHA256_RSA_PKCS,
|
||||||
// CKM_SHA384_RSA_PKCS,
|
CKM_SHA384_RSA_PKCS,
|
||||||
CKM_SHA512_RSA_PKCS,
|
CKM_SHA512_RSA_PKCS,
|
||||||
CKM_SHA1_RSA_PKCS_PSS,
|
CKM_SHA1_RSA_PKCS_PSS,
|
||||||
CKM_SHA256_RSA_PKCS_PSS,
|
CKM_SHA256_RSA_PKCS_PSS,
|
||||||
// CKM_SHA384_RSA_PKCS_PSS,
|
CKM_SHA384_RSA_PKCS_PSS,
|
||||||
CKM_SHA512_RSA_PKCS_PSS,
|
CKM_SHA512_RSA_PKCS_PSS,
|
||||||
CKM_EC_KEY_PAIR_GEN,
|
CKM_EC_KEY_PAIR_GEN,
|
||||||
//CKM_ECDSA_KEY_PAIR_GEN, Same as CKM_EC_KEY_PAIR_GEN, deprecated in 2.11
|
//CKM_ECDSA_KEY_PAIR_GEN, Same as CKM_EC_KEY_PAIR_GEN, deprecated in 2.11
|
||||||
@@ -42,15 +42,15 @@ static const CK_ULONG token_mechanisms_num = sizeof(token_mechanisms) / sizeof(C
|
|||||||
static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH token_mechanisms
|
static const CK_MECHANISM_INFO token_mechanism_infos[] = { // KEEP ALIGNED WITH token_mechanisms
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_RSA_PKCS_KEY_PAIR_GEN
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_RSA_PKCS_KEY_PAIR_GEN
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_PKCS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_PKCS
|
||||||
//{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_RSA_PKCS_PSS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_RSA_PKCS_PSS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_X_509
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_DECRYPT | CKF_SIGN}, // CKM_RSA_X_509
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS
|
||||||
//{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA384_RSA_PKCS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA384_RSA_PKCS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS_PSS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA1_RSA_PKCS_PSS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS_PSS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA256_RSA_PKCS_PSS
|
||||||
//{, , }, // CKM_SHA384_RSA_PKCS_PSS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA384_RSA_PKCS_PSS
|
||||||
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS_PSS
|
{MIN_RSA_KEY_SIZE, MAX_RSA_KEY_SIZE, CKF_HW | CKF_SIGN}, // CKM_SHA512_RSA_PKCS_PSS
|
||||||
{MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_EC_KEY_PAIR_GEN
|
{MIN_ECC_KEY_SIZE, MAX_ECC_KEY_SIZE, CKF_HW | CKF_GENERATE_KEY_PAIR}, // CKM_EC_KEY_PAIR_GEN
|
||||||
//{, , }, // CKM_ECDSA_KEY_PAIR_GEN Same as CKM_EC_KEY_PAIR_GEN deprecated in 2.11
|
//{, , }, // CKM_ECDSA_KEY_PAIR_GEN Same as CKM_EC_KEY_PAIR_GEN deprecated in 2.11
|
||||||
|
|||||||
Reference in New Issue
Block a user