81c778e
broke the PKCS#11 hcrypto backend broke for many cases as it did not support cipherstate resetting. (Prior to81c778e
, which was to fix #194, the PKCS#11 backend did not support cipherstate chaining across invocations.) hcrypto backends that maintain cipherstate independently of the hcrypto context IV field need to set EVP_CIPH_ALWAYS_CALL_INIT to avoid the two diverging. Their init function should support resetting the cipherstate independently of key scheduling.
This commit is contained in:
@@ -87,7 +87,6 @@ p11_cleanup(EVP_CIPHER_CTX *ctx);
|
|||||||
struct pkcs11_cipher_ctx {
|
struct pkcs11_cipher_ctx {
|
||||||
CK_SESSION_HANDLE hSession;
|
CK_SESSION_HANDLE hSession;
|
||||||
CK_OBJECT_HANDLE hSecret;
|
CK_OBJECT_HANDLE hSecret;
|
||||||
int cipher_init_done;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pkcs11_md_ctx {
|
struct pkcs11_md_ctx {
|
||||||
@@ -279,20 +278,43 @@ p11_key_init(EVP_CIPHER_CTX *ctx,
|
|||||||
{ CKA_VALUE, (void *)key, ctx->key_len },
|
{ CKA_VALUE, (void *)key, ctx->key_len },
|
||||||
{ op, &bTrue, sizeof(bTrue) }
|
{ op, &bTrue, sizeof(bTrue) }
|
||||||
};
|
};
|
||||||
|
CK_MECHANISM mechanism = {
|
||||||
|
mechanismType,
|
||||||
|
ctx->cipher->iv_len ? ctx->iv : NULL,
|
||||||
|
ctx->cipher->iv_len
|
||||||
|
};
|
||||||
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
||||||
p11ctx->cipher_init_done = 0;
|
|
||||||
|
|
||||||
|
rv = CKR_OK;
|
||||||
|
|
||||||
|
if (p11ctx->hSession != CK_INVALID_HANDLE && key != NULL)
|
||||||
|
p11_cleanup(ctx); /* refresh session with new key */
|
||||||
|
|
||||||
|
if (p11ctx->hSession == CK_INVALID_HANDLE) {
|
||||||
rv = p11_session_init(mechanismType, &p11ctx->hSession);
|
rv = p11_session_init(mechanismType, &p11ctx->hSession);
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key != NULL) {
|
||||||
assert(p11_module != NULL);
|
assert(p11_module != NULL);
|
||||||
|
assert(p11ctx->hSecret == CK_INVALID_HANDLE);
|
||||||
|
|
||||||
rv = p11_module->C_CreateObject(p11ctx->hSession, attributes,
|
rv = p11_module->C_CreateObject(p11ctx->hSession, attributes,
|
||||||
sizeof(attributes) / sizeof(attributes[0]),
|
sizeof(attributes) / sizeof(attributes[0]),
|
||||||
&p11ctx->hSecret);
|
&p11ctx->hSecret);
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p11ctx->hSecret != CK_INVALID_HANDLE) {
|
||||||
|
if (op == CKA_ENCRYPT)
|
||||||
|
rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
||||||
|
else
|
||||||
|
rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (rv != CKR_OK)
|
if (rv != CKR_OK)
|
||||||
@@ -308,37 +330,17 @@ p11_do_cipher(EVP_CIPHER_CTX *ctx,
|
|||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
||||||
CK_RV rv = CKR_OK;
|
CK_RV rv;
|
||||||
CK_ULONG ulCipherTextLen = size;
|
CK_ULONG ulCipherTextLen = size;
|
||||||
CK_MECHANISM_TYPE mechanismType = (CK_MECHANISM_TYPE)ctx->cipher->app_data;
|
|
||||||
CK_MECHANISM mechanism = {
|
|
||||||
mechanismType,
|
|
||||||
ctx->cipher->iv_len ? ctx->iv : NULL,
|
|
||||||
ctx->cipher->iv_len
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(p11_module != NULL);
|
assert(p11_module != NULL);
|
||||||
/* The EVP layer only ever calls us with complete cipher blocks */
|
|
||||||
assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER ||
|
assert(EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_STREAM_CIPHER ||
|
||||||
(size % ctx->cipher->block_size) == 0);
|
(size % ctx->cipher->block_size) == 0);
|
||||||
|
|
||||||
if (ctx->encrypt) {
|
if (ctx->encrypt)
|
||||||
if (!p11ctx->cipher_init_done) {
|
|
||||||
rv = p11_module->C_EncryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
|
||||||
if (rv == CKR_OK)
|
|
||||||
p11ctx->cipher_init_done = 1;
|
|
||||||
}
|
|
||||||
if (rv == CKR_OK)
|
|
||||||
rv = p11_module->C_EncryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
|
rv = p11_module->C_EncryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
|
||||||
} else {
|
else
|
||||||
if (!p11ctx->cipher_init_done) {
|
|
||||||
rv = p11_module->C_DecryptInit(p11ctx->hSession, &mechanism, p11ctx->hSecret);
|
|
||||||
if (rv == CKR_OK)
|
|
||||||
p11ctx->cipher_init_done = 1;
|
|
||||||
}
|
|
||||||
if (rv == CKR_OK)
|
|
||||||
rv = p11_module->C_DecryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
|
rv = p11_module->C_DecryptUpdate(p11ctx->hSession, (unsigned char *)in, size, out, &ulCipherTextLen);
|
||||||
}
|
|
||||||
|
|
||||||
return rv == CKR_OK;
|
return rv == CKR_OK;
|
||||||
}
|
}
|
||||||
@@ -348,8 +350,6 @@ p11_cleanup(EVP_CIPHER_CTX *ctx)
|
|||||||
{
|
{
|
||||||
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
struct pkcs11_cipher_ctx *p11ctx = (struct pkcs11_cipher_ctx *)ctx->cipher_data;
|
||||||
|
|
||||||
assert(p11_module != NULL);
|
|
||||||
|
|
||||||
if (p11ctx->hSecret != CK_INVALID_HANDLE) {
|
if (p11ctx->hSecret != CK_INVALID_HANDLE) {
|
||||||
p11_module->C_DestroyObject(p11ctx->hSession, p11ctx->hSecret);
|
p11_module->C_DestroyObject(p11ctx->hSession, p11ctx->hSecret);
|
||||||
p11ctx->hSecret = CK_INVALID_HANDLE;
|
p11ctx->hSecret = CK_INVALID_HANDLE;
|
||||||
@@ -433,7 +433,7 @@ p11_md_cleanup(EVP_MD_CTX *ctx)
|
|||||||
block_size, \
|
block_size, \
|
||||||
key_len, \
|
key_len, \
|
||||||
iv_len, \
|
iv_len, \
|
||||||
flags, \
|
(flags) | EVP_CIPH_ALWAYS_CALL_INIT, \
|
||||||
p11_key_init, \
|
p11_key_init, \
|
||||||
p11_do_cipher, \
|
p11_do_cipher, \
|
||||||
p11_cleanup, \
|
p11_cleanup, \
|
||||||
|
@@ -164,7 +164,7 @@ struct hc_CIPHER {
|
|||||||
#define hc_EVP_CTRL_INIT 0x0
|
#define hc_EVP_CTRL_INIT 0x0
|
||||||
|
|
||||||
#define hc_EVP_CIPH_VARIABLE_LENGTH 0x008 /* variable key length */
|
#define hc_EVP_CIPH_VARIABLE_LENGTH 0x008 /* variable key length */
|
||||||
#define hc_EVP_CIPH_ALWAYS_CALL_INIT 0x020
|
#define hc_EVP_CIPH_ALWAYS_CALL_INIT 0x020 /* backend maintains own cipherstate */
|
||||||
#define hc_EVP_CIPH_RAND_KEY 0x200
|
#define hc_EVP_CIPH_RAND_KEY 0x200
|
||||||
|
|
||||||
int (*init)(EVP_CIPHER_CTX*,const unsigned char*,const unsigned char*,int);
|
int (*init)(EVP_CIPHER_CTX*,const unsigned char*,const unsigned char*,int);
|
||||||
|
Reference in New Issue
Block a user