Skip to content

Commit

Permalink
AES Ciphers and key management using EVP_SKEY
Browse files Browse the repository at this point in the history
Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 committed Jan 21, 2025
1 parent 0c31b4e commit 68b59b9
Show file tree
Hide file tree
Showing 12 changed files with 1,415 additions and 2 deletions.
689 changes: 689 additions & 0 deletions src/cipher.c

Large diffs are not rendered by default.

96 changes: 96 additions & 0 deletions src/cipher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* Copyright (C) 2024 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

#ifndef _CIPHER_H
#define _CIPHER_H

#define MODE_modes_mask 0x00FF
#define MODE_flags_mask 0xFF00

#define MODE_flag_aead 0x0100
#define MODE_flag_custom_iv 0x0200
#define MODE_flag_cts 0x0400
#define MODE_flag_tls1_mb 0x0800
#define MODE_flag_rand_key 0x1000

#define MODE_ecb 0x01
#define MODE_cbc 0x02
#define MODE_ofb 0x04
#define MODE_cfb 0x08
#define MODE_cfb1 MODE_cfb
#define MODE_cfb8 MODE_cfb
#define MODE_ctr 0x10
#define MODE_cts MODE_flag_cts | MODE_cbc

#define DISPATCH_CIPHER_FN(alg, name) \
DECL_DISPATCH_FUNC(cipher, p11prov_##alg, name)

#define DISPATCH_TABLE_CIPHER_FN(cipher, size, mode, mechanism) \
static void *p11prov_##cipher##size##mode##_newctx(void *provctx) \
{ \
return p11prov_cipher_newctx(provctx, size, mechanism); \
} \
static int p11prov_##cipher##size##mode##_get_params(OSSL_PARAM params[]) \
{ \
return p11prov_##cipher##_get_params(params, size, MODE_##mode, \
mechanism); \
} \
const OSSL_DISPATCH p11prov_##cipher##size##mode##_cipher_functions[] = { \
{ OSSL_FUNC_CIPHER_NEWCTX, \
(void (*)(void))p11prov_##cipher##size##mode##_newctx }, \
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))p11prov_cipher_freectx }, \
{ OSSL_FUNC_CIPHER_DUPCTX, \
(void (*)(void))p11prov_##cipher##_dupctx }, \
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, \
(void (*)(void))p11prov_cipher_encrypt_init }, \
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, \
(void (*)(void))p11prov_cipher_decrypt_init }, \
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))p11prov_cipher_update }, \
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))p11prov_cipher_final }, \
{ OSSL_FUNC_CIPHER_CIPHER, \
(void (*)(void))p11prov_##cipher##_cipher }, \
{ OSSL_FUNC_CIPHER_GET_PARAMS, \
(void (*)(void))p11prov_##cipher##size##mode##_get_params }, \
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
(void (*)(void))p11prov_##cipher##_get_ctx_params }, \
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
(void (*)(void))p11prov_##cipher##_set_ctx_params }, \
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
(void (*)(void))p11prov_cipher_gettable_params }, \
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
(void (*)(void))p11prov_##cipher##_gettable_ctx_params }, \
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
(void (*)(void))p11prov_##cipher##_settable_ctx_params }, \
{ OSSL_FUNC_CIPHER_ENCRYPT_SKEY_INIT, \
(void (*)(void))p11prov_cipher_encrypt_skey_init }, \
{ OSSL_FUNC_CIPHER_DECRYPT_SKEY_INIT, \
(void (*)(void))p11prov_cipher_decrypt_skey_init }, \
OSSL_DISPATCH_END \
};

extern const OSSL_DISPATCH p11prov_aes128ecb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192ecb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256ecb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128cbc_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192cbc_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256cbc_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128ofb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192ofb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256ofb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb1_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb1_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb1_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb8_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb8_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb8_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128ctr_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192ctr_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256ctr_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes128cts_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes192cts_cipher_functions[];
extern const OSSL_DISPATCH p11prov_aes256cts_cipher_functions[];

#endif /* _CIPHER_H */
4 changes: 3 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
pkcs11_provider_sources = [
'asymmetric_cipher.c',
'cipher.c',
'debug.c',
'encoder.c',
'decoder.c',
'digests.c',
'encoder.c',
'exchange.c',
'kdf.c',
'keymgmt.c',
Expand All @@ -14,6 +15,7 @@ pkcs11_provider_sources = [
'random.c',
'session.c',
'signature.c',
'skeymgmt.c',
'slot.c',
'store.c',
'tls.c',
Expand Down
121 changes: 121 additions & 0 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -4011,6 +4011,127 @@ CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type,
}
}

#if SKEY_SUPPORT

static CK_RV p11prov_store_aes_key(P11PROV_CTX *provctx, P11PROV_OBJ **ret,
const unsigned char *secret,
size_t secretlen, char *label,
CK_FLAGS usage, bool session_key)
{
CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
CK_KEY_TYPE key_type = CKK_AES;
CK_SLOT_ID slot = CK_UNAVAILABLE_INFORMATION;
P11PROV_SLOTS_CTX *slots = NULL;
P11PROV_SESSION *session = NULL;
CK_OBJECT_HANDLE key_handle;
P11PROV_OBJ *obj;
CK_RV rv;
CK_ATTRIBUTE tmpl[12] = {
{ CKA_CLASS, &key_class, sizeof(key_class) },
{ CKA_KEY_TYPE, &key_type, sizeof(key_type) },
{ CKA_VALUE, (void *)secret, secretlen },
{ 0 },
};
size_t tmax = sizeof(tmpl) / sizeof(CK_ATTRIBUTE);
size_t tsize = 3;

P11PROV_debug("Creating secret key (%p[%zu]), token: %b, flags: %x", secret,
secretlen, !session_key, usage);

/* CKA_TOKEN */
if (session_key) {
p11prov_set_attr_bool(&tmpl[tsize++], CKA_TOKEN, false);
} else {
p11prov_set_attr_bool(&tmpl[tsize++], CKA_TOKEN, true);
}

if (usage) {
rv = p11prov_usage_to_template(tmpl, &tsize, tmax, usage);
if (rv != CKR_OK) {
P11PROV_raise(provctx, rv, "Failed to set key usage");
return CKR_GENERAL_ERROR;
}
} else {
rv = CKR_ARGUMENTS_BAD;
P11PROV_raise(provctx, rv, "No key usage specified");
return CKR_GENERAL_ERROR;
}

slots = p11prov_ctx_get_slots(provctx);
if (!slots) {
rv = CKR_GENERAL_ERROR;
goto done;
}

slot = p11prov_get_default_slot(slots);
if (slot == CK_UNAVAILABLE_INFORMATION) {
rv = CKR_GENERAL_ERROR;
goto done;
}

rv = p11prov_take_login_session(provctx, slot, &session);
if (rv != CKR_OK) {
goto done;
}

rv = p11prov_CreateObject(provctx, p11prov_session_handle(session), tmpl,
tsize, &key_handle);
if (rv != CKR_OK) {
goto done;
}

obj = p11prov_obj_new(provctx, slot, key_handle, key_class);
if (obj == NULL) {
rv = CKR_HOST_MEMORY;
goto done;
}
obj->data.key.type = key_type;
obj->data.key.bit_size = secretlen * 8;
obj->data.key.size = secretlen;

*ret = obj;
rv = CKR_OK;

done:
p11prov_return_session(session);
return rv;
}

P11PROV_OBJ *p11prov_obj_import_secret_key(P11PROV_CTX *ctx, CK_KEY_TYPE type,
const unsigned char *key,
size_t keylen)
{
CK_RV rv = CKR_KEY_INDIGESTIBLE;
P11PROV_OBJ *obj = NULL;
CK_FLAGS usage = CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY
| CKF_WRAP | CKF_UNWRAP | CKF_DECRYPT;

/* TODO: cache find, see other key types */

switch (type) {
case CKK_AES:
rv = p11prov_store_aes_key(ctx, &obj, key, keylen, NULL, usage, true);
if (rv != CKR_OK) {
P11PROV_raise(ctx, rv, "Failed to import");
goto done;
}
break;

default:
P11PROV_raise(ctx, rv, "Unsupported key type: %08lx", type);
goto done;
}

done:
if (rv != CKR_OK) {
p11prov_obj_free(obj);
obj = NULL;
}
return obj;
}

#endif /* SKEY_SUPPORT */

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len)
Expand Down
4 changes: 4 additions & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ int p11prov_obj_key_cmp(P11PROV_OBJ *obj1, P11PROV_OBJ *obj2, CK_KEY_TYPE type,
CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type,
CK_OBJECT_CLASS class, const OSSL_PARAM params[]);

P11PROV_OBJ *p11prov_obj_import_secret_key(P11PROV_CTX *ctx, CK_KEY_TYPE type,
const unsigned char *key,
size_t keylen);

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len);
Expand Down
Loading

0 comments on commit 68b59b9

Please sign in to comment.