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 16, 2025
1 parent e391e1f commit eef86ed
Show file tree
Hide file tree
Showing 9 changed files with 698 additions and 1 deletion.
415 changes: 415 additions & 0 deletions src/cipher.c

Large diffs are not rendered by default.

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

#ifndef _CIPHER_H
#define _CIPHER_H

#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, mechanism); \
} \
static const OSSL_PARAM *p11prov_##cipher##size##mode##_gettable_params(\
void *provctx) \
{ \
return p11prov_aes_gettable_params(provctx, size, mechanism); \
} \
const OSSL_DISPATCH ossl_##cipher##size##mode##_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##size##mode##_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_functions[];
extern const OSSL_DISPATCH p11prov_aes192ecb_functions[];
extern const OSSL_DISPATCH p11prov_aes256ecb_functions[];
extern const OSSL_DISPATCH p11prov_aes128cbc_functions[];
extern const OSSL_DISPATCH p11prov_aes192cbc_functions[];
extern const OSSL_DISPATCH p11prov_aes256cbc_functions[];
extern const OSSL_DISPATCH p11prov_aes128ofb_functions[];
extern const OSSL_DISPATCH p11prov_aes192ofb_functions[];
extern const OSSL_DISPATCH p11prov_aes256ofb_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb1_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb1_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb1_functions[];
extern const OSSL_DISPATCH p11prov_aes128cfb8_functions[];
extern const OSSL_DISPATCH p11prov_aes192cfb8_functions[];
extern const OSSL_DISPATCH p11prov_aes256cfb8_functions[];
extern const OSSL_DISPATCH p11prov_aes128ctr_functions[];
extern const OSSL_DISPATCH p11prov_aes192ctr_functions[];
extern const OSSL_DISPATCH p11prov_aes256ctr_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
116 changes: 116 additions & 0 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -3957,6 +3957,122 @@ CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type,
}
}

static CK_RV p11prov_store_aes_key(P11PROV_CTX *provctx, P11PROV_OBJ **ret,
unsigned char *secret, size_t secretlen)
{
CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
CK_KEY_TYPE key_type = CKK_AES;
CK_BBOOL val_true = CK_TRUE;
CK_BBOOL val_false = CK_FALSE;
CK_ATTRIBUTE tmpl[8] = {
{ CKA_CLASS, &key_class, sizeof(key_class) },
{ CKA_KEY_TYPE, &key_type, sizeof(key_type) },
{ CKA_TOKEN, &val_false, sizeof(val_false) },
{ CKA_ENCRYPT, &val_true, sizeof(val_true) },
{ CKA_DECRYPT, &val_true, sizeof(val_true) },
{ CKA_WRAP, &val_true, sizeof(val_true) },
{ CKA_UNWRAP, &val_true, sizeof(val_true) },
{ CKA_VALUE, (void *)secret, secretlen },
};
int tsize = sizeof(tmpl) / sizeof(CK_ATTRIBUTE);
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;

P11PROV_debug("keys: create secret key (secret:%p[%zu])",
secret, secretlen);

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 OSSL_PARAM params[])
{
P11PROV_OBJ *obj = NULL;
const OSSL_PARAM *p;
unsigned char *key;
size_t keylen;
CK_RV rv = CKR_KEY_INDIGESTIBLE;

p = OSSL_PARAM_locate_const(params, OSSL_SKEY_PARAM_RAW_BYTES);
if (p) {
int ret = OSSL_PARAM_get_octet_string_ptr(p, (const void **)&key,
&keylen);
if (ret != RET_OSSL_OK) {
P11PROV_raise(ctx, rv, "Invalid data");
goto done;
}
} else {
/* Not a digestible secret key */
P11PROV_raise(ctx, rv, "Raw Bytes param unavailable");
goto done;
}

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

switch (type) {
case CKK_AES:
rv = p11prov_store_aes_key(ctx, &obj, key, keylen);
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;
}

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len)
Expand Down
2 changes: 2 additions & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ 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 OSSL_PARAM params[]);

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
Expand Down
10 changes: 10 additions & 0 deletions src/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct p11prov_ctx {
OSSL_ALGORITHM *op_decoder;
OSSL_ALGORITHM *op_keymgmt;
OSSL_ALGORITHM *op_store;
OSSL_ALGORITHM *op_skeymgmt;

pthread_rwlock_t quirk_lock;
struct quirk *quirks;
Expand Down Expand Up @@ -544,6 +545,7 @@ static void p11prov_ctx_free(P11PROV_CTX *ctx)
OPENSSL_free(ctx->op_decoder);
OPENSSL_free(ctx->op_keymgmt);
OPENSSL_free(ctx->op_store);
OPENSSL_free(ctx->op_skeymgmt);

OSSL_LIB_CTX_free(ctx->libctx);
ctx->libctx = NULL;
Expand Down Expand Up @@ -1099,6 +1101,7 @@ static CK_RV static_operations_init(P11PROV_CTX *ctx)
int decoder_idx = 0;
int store_idx = 0;
int keymgmt_idx = 0;
int skeymgmt_idx = 0;
const char *prop = get_default_properties(ctx);

/* encoder */
Expand Down Expand Up @@ -1195,6 +1198,9 @@ static CK_RV static_operations_init(P11PROV_CTX *ctx)
ADD_ALGO_EXT(ED448, keymgmt, prop, p11prov_ed448_keymgmt_functions);
TERM_ALGO(keymgmt);

/* skeymgmt */
ADD_ALGO(AES, aes, skeymgmt, prop);

return CKR_OK;
}

Expand All @@ -1212,6 +1218,7 @@ static const char *p11prov_block_ops_names[OSSL_OP__HIGHEST + 1] = {
[OSSL_OP_ENCODER] = "encoder",
[OSSL_OP_DECODER] = "decoder",
[OSSL_OP_STORE] = "store",
[OSSL_OP_SKEYMGMT] = "skeymgmt",
};

static const OSSL_ALGORITHM *
Expand Down Expand Up @@ -1262,6 +1269,9 @@ p11prov_query_operation(void *provctx, int operation_id, int *no_cache)
case OSSL_OP_STORE:
*no_cache = 0;
return ctx->op_store;
case OSSL_OP_SKEYMGMT:
*no_cache = 0;
return ctx->op_keymgmt;
}
*no_cache = 0;
return NULL;
Expand Down
4 changes: 4 additions & 0 deletions src/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
#define P11PROV_DESCS_DER "DER decoder implementation in PKCS11 provider"
#define P11PROV_NAMES_URI "pkcs11"
#define P11PROV_DESCS_URI "PKCS11 URI Store"
#define P11PROV_NAMES_AES "AES"
#define P11PROV_DESCS_AES "PKCS11 AES Implementation"

#define P11PROV_PARAM_URI "pkcs11_uri"
#define P11PROV_PARAM_KEY_USAGE "pkcs11_key_usage"
Expand Down Expand Up @@ -154,9 +156,11 @@ int p11prov_pop_error_to_mark(P11PROV_CTX *ctx);
#include "interface.h"
#include "objects.h"
#include "keymgmt.h"
#include "skeymgmt.h"
#include "store.h"
#include "signature.h"
#include "asymmetric_cipher.h"
#include "cipher.h"
#include "exchange.h"
#include "kdf.h"
#include "encoder.h"
Expand Down
54 changes: 54 additions & 0 deletions src/skeymgmt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* Copyright (C) 2024 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

#include "provider.h"
#include "platform/endian.h"
#include <string.h>

DISPATCH_SKEYMGMT_FN(aes, free);
DISPATCH_SKEYMGMT_FN(aes, import);
DISPATCH_SKEYMGMT_FN(aes, export);

static void p11prov_aes_free(void *key)
{
P11PROV_debug("aes free %p", key);
p11prov_obj_free((P11PROV_OBJ *)key);
}

static void *p11prov_aes_import(void *provctx, int selection,
const OSSL_PARAM params[])
{
P11PROV_CTX *ctx = (P11PROV_CTX *)provctx;

P11PROV_debug("aes import");

if (!ctx) {
return NULL;
}

if (!(selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY)) {
/* TODO: check for hack import uri */
return NULL;
}

return p11prov_obj_import_secret_key(ctx, CKK_AES, params);
}

static int p11prov_aes_export(void *keydata, int selection,
OSSL_CALLBACK *param_cb, void *cbarg)
{
P11PROV_OBJ *key = (P11PROV_OBJ *)keydata;

P11PROV_raise(p11prov_obj_get_prov_ctx(key),
CKR_KEY_FUNCTION_NOT_PERMITTED,
"Not exportable");

return RET_OSSL_ERR;
}

const OSSL_DISPATCH p11prov_aes_skeymgmt_functions[] = {
DISPATCH_SKEYMGMT_ELEM(aes, FREE, free),
DISPATCH_SKEYMGMT_ELEM(aes, IMPORT, import),
DISPATCH_SKEYMGMT_ELEM(aes, EXPORT, export),
{ 0, NULL },
};
17 changes: 17 additions & 0 deletions src/skeymgmt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Copyright (C) 2024 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

#ifndef _SKEYMGMT_H
#define _SKEYMGMT_H

/* keymgmt */
#define DISPATCH_SKEYMGMT_FN(type, name) \
DECL_DISPATCH_FUNC(skeymgmt, p11prov_##type, name)
#define DISPATCH_SKEYMGMT_ELEM(type, NAME, name) \
{ \
OSSL_FUNC_SKEYMGMT_##NAME, (void (*)(void))p11prov_##type##_##name \
}
extern const OSSL_DISPATCH p11prov_aes_skeymgmt_functions[];

#endif /* _SKEYMGMT_H */

0 comments on commit eef86ed

Please sign in to comment.