Fix CKM_RSA_X_509 encrypt_decrypt(). Improve the code for CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP. For these alogs, only CKM_SHA_1 is supported.

This commit is contained in:
alegon01 2019-02-05 11:35:42 +01:00
parent d25fbe3cec
commit 9aa413bd7e
1 changed files with 71 additions and 43 deletions

View File

@ -5251,16 +5251,29 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE privKeyObject) CK_OBJECT_HANDLE privKeyObject)
{ {
EVP_PKEY *pkey; EVP_PKEY *pkey;
unsigned char orig_data[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'}; unsigned char orig_data[512] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'};
unsigned char encrypted[512], data[512]; unsigned char encrypted[512], data[512];
CK_MECHANISM mech; CK_MECHANISM mech;
CK_ULONG encrypted_len, data_len; CK_ULONG encrypted_len, data_len;
int failed; int failed;
CK_RV rv; CK_RV rv;
int pad;
CK_MECHANISM_TYPE hash_alg = CKM_SHA_1;
CK_RSA_PKCS_OAEP_PARAMS oaep_params; CK_RSA_PKCS_OAEP_PARAMS oaep_params;
printf(" %s: ", p11_mechanism_to_name(mech_type)); printf(" %s: ", p11_mechanism_to_name(mech_type));
if ((mech_type == CKM_RSA_PKCS) || (mech_type == CKM_RSA_PKCS_OAEP)) {
if (opt_hash_alg == 0) {
hash_alg = CKM_SHA_1;
} else if (opt_hash_alg != CKM_SHA_1) {
printf("Only CKM_SHA_1 supported\n");
return 0;
} else {
hash_alg = opt_hash_alg;
}
}
pkey = get_public_key(session, privKeyObject); pkey = get_public_key(session, privKeyObject);
if (pkey == NULL) if (pkey == NULL)
return 0; return 0;
@ -5270,52 +5283,71 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
EVP_PKEY_free(pkey); EVP_PKEY_free(pkey);
return 0; return 0;
} }
if (mech_type == CKM_RSA_PKCS_OAEP) { size_t in_len;
EVP_PKEY_CTX *ctx; CK_ULONG mod_len = (get_private_key_length(session, privKeyObject) + 7) / 8;
ctx = EVP_PKEY_CTX_new(pkey, NULL); switch (mech_type) {
if (!ctx) { case CKM_RSA_PKCS:
EVP_PKEY_free(pkey); pad = RSA_PKCS1_PADDING;
printf("EVP_PKEY_CTX_new failed, returning\n"); /* Limit the input length to <= mod_len-11 */
return 0; in_len = mod_len-11;
} break;
if (EVP_PKEY_encrypt_init(ctx) <= 0) { case CKM_RSA_PKCS_OAEP: {
EVP_PKEY_CTX_free(ctx); pad = RSA_PKCS1_OAEP_PADDING;
EVP_PKEY_free(pkey); /* Limit the input length to <= mod_len-2-2*hlen */
printf("EVP_PKEY_encrypt_init failed, returning\n"); size_t len = 2+2*hash_length(hash_alg);
if (len >= mod_len) {
printf("Incompatible mechanism and key size\n");
return 0; return 0;
} }
in_len = mod_len-len;
break;
}
case CKM_RSA_X_509:
pad = RSA_NO_PADDING;
/* Limit the input length to the modulus length */
in_len = mod_len;
break;
default:
printf("Unsupported mechanism, returning\n");
return 0;
}
if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) { EVP_PKEY_CTX *ctx;
EVP_PKEY_CTX_free(ctx); ctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_free(pkey); if (!ctx) {
printf("set OAEP padding failed, returning\n"); EVP_PKEY_free(pkey);
return 0; printf("EVP_PKEY_CTX_new failed, returning\n");
} return 0;
size_t outlen = sizeof(encrypted); }
if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, orig_data, sizeof(orig_data)) <= 0) { if (EVP_PKEY_encrypt_init(ctx) <= 0) {
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
printf("Encryption failed, returning\n");
return 0;
}
EVP_PKEY_CTX_free(ctx); EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey); EVP_PKEY_free(pkey);
encrypted_len = outlen; printf("EVP_PKEY_encrypt_init failed, returning\n");
return 0;
} else {
encrypted_len = EVP_PKEY_encrypt_old(encrypted, orig_data, sizeof(orig_data), pkey);
EVP_PKEY_free(pkey);
if (((int) encrypted_len) <= 0) {
printf("Encryption failed, returning\n");
return 0;
}
} }
if (EVP_PKEY_CTX_set_rsa_padding(ctx, pad) <= 0) {
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
printf("set OAEP padding failed, returning\n");
return 0;
}
size_t out_len = sizeof(encrypted);
if (EVP_PKEY_encrypt(ctx, encrypted, &out_len, orig_data, in_len) <= 0) {
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
printf("Encryption failed, returning\n");
return 0;
}
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
encrypted_len = out_len;
/* set "default" MGF and hash algorithms. We can overwrite MGF later */ /* set "default" MGF and hash algorithms. We can overwrite MGF later */
switch (mech_type) { switch (mech_type) {
case CKM_RSA_PKCS_OAEP: case CKM_RSA_PKCS_OAEP:
oaep_params.hashAlg = opt_hash_alg; oaep_params.hashAlg = hash_alg;
switch (opt_hash_alg) { switch (oaep_params.hashAlg) {
case CKM_SHA224: case CKM_SHA224:
oaep_params.mgf = CKG_MGF1_SHA224; oaep_params.mgf = CKG_MGF1_SHA224;
break; break;
@ -5379,18 +5411,14 @@ static int encrypt_decrypt(CK_SESSION_HANDLE session,
if (rv != CKR_OK) if (rv != CKR_OK)
p11_fatal("C_Decrypt", rv); p11_fatal("C_Decrypt", rv);
if (mech_type == CKM_RSA_X_509) failed = data_len != in_len || memcmp(orig_data, data, data_len);
failed = (data[0] != 0) || (data[1] != 2) || (data_len <= sizeof(orig_data) - 2) ||
memcmp(orig_data, data + data_len - sizeof(orig_data), sizeof(orig_data));
else
failed = data_len != sizeof(orig_data) || memcmp(orig_data, data, data_len);
if (failed) { if (failed) {
CK_ULONG n; CK_ULONG n;
printf("resulting cleartext doesn't match input\n"); printf("resulting cleartext doesn't match input\n");
printf(" Original:"); printf(" Original:");
for (n = 0; n < sizeof(orig_data); n++) for (n = 0; n < in_len; n++)
printf(" %02x", orig_data[n]); printf(" %02x", orig_data[n]);
printf("\n"); printf("\n");
printf(" Decrypted:"); printf(" Decrypted:");