Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 221 additions & 33 deletions src/crypto.c

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -19044,6 +19044,129 @@ int WP11_KDF_Derive(WP11_Session* session, CK_HKDF_PARAMS_PTR params,

#endif

/* Call with the object lock held when the key is on the token. */
static int wp11_Concat_KeyState(WP11_Object* key)
{
int ret = 0;

if (key->objClass != CKO_SECRET_KEY || key->data.symmKey == NULL)
ret = BAD_FUNC_ARG;
#ifndef WOLFPKCS11_NO_STORE
else if (key->encoded || key->undecoded)
ret = BAD_STATE_E;
#endif
#ifdef WOLFSSL_STM32U5_DHUK
else if (key->dhukIvLen > 0)
ret = NOT_AVAILABLE_E;
#endif

return ret;
}

/**
* Get the length of a secret key's value for concatenation.
*
* @param key [in] Secret key object.
* @param len [out] Length of the key value in bytes.
* @return BAD_FUNC_ARG when the object is not a secret key.
* BAD_STATE_E when the key value is not decoded.
* NOT_AVAILABLE_E when the key value is wrapped by hardware.
* 0 on success.
*/
int WP11_Concat_KeyLen(WP11_Object* key, word32* len)
{
int ret;

if (key == NULL || len == NULL)
return BAD_FUNC_ARG;

if (key->onToken)
WP11_Lock_LockRO(key->lock);
ret = wp11_Concat_KeyState(key);
if (ret == 0)
*len = key->data.symmKey->len;
if (key->onToken)
WP11_Lock_UnlockRO(key->lock);

return ret;
}

/* Append up to outLen leading bytes of a secret key's value to out. */
static int wp11_Concat_Key(WP11_Object* key, byte* out, word32 outLen,
word32* used)
{
int ret;
word32 len;

if (key->onToken)
WP11_Lock_LockRO(key->lock);
ret = wp11_Concat_KeyState(key);
if (ret == 0) {
len = key->data.symmKey->len;
if (len > outLen)
len = outLen;
if (len > 0)
XMEMCPY(out, key->data.symmKey->data, len);
*used += len;
}
if (key->onToken)
WP11_Lock_UnlockRO(key->lock);

return ret;
}

/**
* Concatenate a secret key's value with another key's value or with data.
*
* @param base [in] Base secret key object.
* @param other [in] Key appended to the base key. NULL to use data.
* @param data [in] Data to concatenate with the base key.
* @param dataLen [in] Length of data in bytes.
* @param dataFirst [in] Data goes before the base key value when set.
* @param out [out] Buffer to hold the leading outLen bytes.
* @param outLen [in] Number of bytes to output.
* @return BAD_FUNC_ARG when an object is not a secret key or the
* concatenation is shorter than outLen.
* BAD_STATE_E when a key value is not decoded.
* NOT_AVAILABLE_E when a key value is wrapped by hardware.
* 0 on success.
*/
int WP11_Concat_Derive(WP11_Object* base, WP11_Object* other,
const byte* data, word32 dataLen, int dataFirst,
byte* out, word32 outLen)
{
int ret;
word32 used = 0;
word32 len;

if (base == NULL || out == NULL ||
(other == NULL && data == NULL && dataLen > 0))
return BAD_FUNC_ARG;

if (other == NULL && dataFirst) {
len = (dataLen < outLen) ? dataLen : outLen;
if (len > 0)
XMEMCPY(out, data, len);
used = len;
}
ret = wp11_Concat_Key(base, out + used, outLen - used, &used);
if (ret == 0 && other != NULL) {
ret = wp11_Concat_Key(other, out + used, outLen - used, &used);
}
else if (ret == 0 && !dataFirst) {
len = outLen - used;
if (dataLen < len)
len = dataLen;
if (len > 0)
XMEMCPY(out + used, data, len);
used += len;
}

if (ret == 0 && used != outLen)
ret = BAD_FUNC_ARG;
return ret;
}

#ifndef NO_DH
/**
* Generate an DH key pair.
Expand Down
11 changes: 11 additions & 0 deletions src/slot.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,9 @@ static CK_MECHANISM_TYPE mechanismList[] = {
CKM_TLS_MAC,
#endif
CKM_GENERIC_SECRET_KEY_GEN,
CKM_CONCATENATE_BASE_AND_KEY,
CKM_CONCATENATE_BASE_AND_DATA,
CKM_CONCATENATE_DATA_AND_BASE,
#ifndef NO_HMAC
CKM_PKCS5_PBKD2
#endif
Expand Down Expand Up @@ -909,6 +912,9 @@ static CK_MECHANISM_INFO sha3MechInfo = {
static CK_MECHANISM_INFO genSecKeyGenMechInfo = {
8, WP11_MAX_SYM_KEY_SZ * 8, CKF_GENERATE
};
static CK_MECHANISM_INFO concatMechInfo = {
8, WP11_MAX_SYM_KEY_SZ * 8, CKF_DERIVE
};

#ifndef NO_HMAC
static CK_MECHANISM_INFO pkcs5Pbkdf2MechInfo = {
Expand Down Expand Up @@ -1293,6 +1299,11 @@ CK_RV C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
XMEMCPY(pInfo, &genSecKeyGenMechInfo,
sizeof(CK_MECHANISM_INFO));
break;
case CKM_CONCATENATE_BASE_AND_KEY:
case CKM_CONCATENATE_BASE_AND_DATA:
case CKM_CONCATENATE_DATA_AND_BASE:
XMEMCPY(pInfo, &concatMechInfo, sizeof(CK_MECHANISM_INFO));
break;
#ifndef NO_HMAC
case CKM_PKCS5_PBKD2:
XMEMCPY(pInfo, &pkcs5Pbkdf2MechInfo,
Expand Down
98 changes: 98 additions & 0 deletions tests/pkcs11str.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,88 @@ static CK_RV find_mlkem_pub_key(CK_SESSION_HANDLE session,
}
#endif /* WOLFPKCS11_MLKEM */

#ifndef WOLFPKCS11_NO_STORE
static unsigned char concatKeyId[] = "123concatkey";

static CK_RV create_concat_key(CK_SESSION_HANDLE session)
{
CK_RV ret;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_BBOOL ckFalse = CK_FALSE;
unsigned char value[16] = { 0 };
CK_OBJECT_HANDLE key;
CK_ATTRIBUTE tmpl[] = {
{ CKA_CLASS, &keyClass, sizeof(keyClass) },
{ CKA_KEY_TYPE, &genericKeyType, sizeof(genericKeyType) },
{ CKA_TOKEN, &ckTrue, sizeof(ckTrue) },
{ CKA_PRIVATE, &ckFalse, sizeof(ckFalse) },
{ CKA_DERIVE, &ckTrue, sizeof(ckTrue) },
{ CKA_ID, concatKeyId, sizeof(concatKeyId) - 1 },
{ CKA_VALUE, value, sizeof(value) },
};

ret = funcList->C_CreateObject(session, tmpl,
sizeof(tmpl) / sizeof(*tmpl), &key);
CHECK_CKR(ret, "Create public secret key");

return ret;
}

static CK_RV concat_before_login(void)
{
CK_RV ret;
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
CK_BBOOL ckFalse = CK_FALSE;
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE key = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE derived = CK_INVALID_HANDLE;
CK_ULONG count = 0;
unsigned char data[4] = { 0xd0, 0xd1, 0xd2, 0xd3 };
CK_KEY_DERIVATION_STRING_DATA params = { data, sizeof(data) };
CK_MECHANISM mech = { CKM_CONCATENATE_BASE_AND_DATA, &params,
sizeof(params) };
CK_ATTRIBUTE findTmpl[] = {
{ CKA_CLASS, &keyClass, sizeof(keyClass) },
{ CKA_ID, concatKeyId, sizeof(concatKeyId) - 1 },
};
CK_ULONG valueLen = 16 + sizeof(data);
CK_ATTRIBUTE tmpl[] = {
{ CKA_CLASS, &keyClass, sizeof(keyClass) },
{ CKA_KEY_TYPE, &genericKeyType, sizeof(genericKeyType) },
{ CKA_PRIVATE, &ckFalse, sizeof(ckFalse) },
{ CKA_VALUE_LEN, &valueLen, sizeof(valueLen) },
};

ret = funcList->C_OpenSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, NULL, &session);
CHECK_CKR(ret, "Open session before login");
if (ret == CKR_OK) {
ret = funcList->C_FindObjectsInit(session, findTmpl,
sizeof(findTmpl) / sizeof(*findTmpl));
CHECK_CKR(ret, "Find public secret key init");
}
if (ret == CKR_OK) {
ret = funcList->C_FindObjects(session, &key, 1, &count);
CHECK_CKR(ret, "Find public secret key");
funcList->C_FindObjectsFinal(session);
}
if (ret == CKR_OK && count != 1) {
ret = -1;
CHECK_CKR(ret, "Find public secret key count");
}
if (ret == CKR_OK) {
ret = funcList->C_DeriveKey(session, &mech, key, tmpl,
sizeof(tmpl) / sizeof(*tmpl), &derived);
CHECK_CKR_FAIL(ret, CKR_USER_NOT_LOGGED_IN,
"Concatenate undecoded key before login");
}
if (session != CK_INVALID_HANDLE)
funcList->C_CloseSession(session);

return ret;
}
#endif

static CK_RV pkcs11_test(int slotId, int setPin, int closeDl)
{
CK_RV ret;
Expand Down Expand Up @@ -1131,6 +1213,15 @@ static CK_RV pkcs11_test(int slotId, int setPin, int closeDl)
printf("Done\n");
}
}
#endif
#ifndef WOLFPKCS11_NO_STORE
if (ret == CKR_OK && userPinLen != 0) {
printf("Create public secret key ... ");
ret = create_concat_key(session);
if (ret == CKR_OK) {
printf("Done\n");
}
}
#endif
pkcs11_close_session(session);
}
Expand All @@ -1155,6 +1246,13 @@ static CK_RV pkcs11_test(int slotId, int setPin, int closeDl)
printf("Done\n");
}
}
if (ret == CKR_OK && userPinLen != 0) {
printf("Concatenate before login ... ");
ret = concat_before_login();
if (ret == CKR_OK) {
printf("Done\n");
}
}
#endif
if (ret == CKR_OK) {
inited = 1;
Expand Down
Loading
Loading