Skip to content

Commit

Permalink
feat: implement mech params
Browse files Browse the repository at this point in the history
- CK_KEY_WRAP_SET_OAEP_PARAMS
- CK_GCM_PARAMS
- CK_CCM_PARAMS
- CK_GOSTR3410_DERIVE_PARAMS
- CK_GOSTR3410_KEY_WRAP_PARAMS
  • Loading branch information
microshine committed Jan 16, 2024
1 parent 8e42215 commit 9bd6a3d
Show file tree
Hide file tree
Showing 5 changed files with 1,986 additions and 1,672 deletions.
36 changes: 36 additions & 0 deletions index.d.ts
Expand Up @@ -410,6 +410,37 @@ declare module "pkcs11js" {
iteration: number;
}

interface KeyWrapSetOaepParams extends IParams {
bc: number;
x: Buffer;
}

interface GcmParams extends IParams {
iv: Buffer;
ivBits: number;
aad?: Buffer;
tagBits?: number;
}

interface CcmParams extends IParams {
dataLen: number;
nonce?: Buffer;
aad?: Buffer;
macLen?: number;
}

interface GostR3410DeriveParams extends IParams {
kdf: number;
publicData: Buffer;
ukm?: Buffer;
}

interface GostR3410KeyWrapParams extends IParams {
wrapOID: Buffer;
ukm?: Buffer;
key: Handle;
}

//#endregion

interface KeyPair {
Expand Down Expand Up @@ -2036,6 +2067,11 @@ declare module "pkcs11js" {
const CK_PARAMS_SKIPJACK_PRIVATE_WRAP: number;
const CK_PARAMS_SKIPJACK_RELAYX: number;
const CK_PARAMS_PBE: number;
const CK_PARAMS_KEY_WRAP_SET_OAEP: number;
const CK_PARAMS_GCM: number;
const CK_PARAMS_CCM: number;
const CK_PARAM_GOSTR3410_DERIVE: number;
const CK_PARAM_GOSTR3410_KEY_WRAP: number;
//#endregion

//#region User types
Expand Down
6 changes: 6 additions & 0 deletions src/common.h
Expand Up @@ -7,6 +7,7 @@
#include <vector>
#include <node_api.h>
#include <cstdarg>
#include <string>

#ifdef _WIN32
// Use Windows-specific definitions
Expand Down Expand Up @@ -66,6 +67,11 @@ typedef CK_NSS_C_INITIALIZE_ARGS *CK_NSS_C_INITIALIZE_ARGS_PTR;
#define CK_PARAMS_SKIPJACK_PRIVATE_WRAP 21
#define CK_PARAMS_SKIPJACK_RELAYX 22
#define CK_PARAMS_PBE 23
#define CK_PARAMS_KEY_WRAP_SET_OAEP 24
#define CK_PARAMS_GCM 25
#define CK_PARAMS_CCM 26
#define CK_PARAM_GOSTR3410_DERIVE 27
#define CK_PARAM_GOSTR3410_KEY_WRAP 28

/**
* @brief Retrieves the name of the error code.
Expand Down
5 changes: 5 additions & 0 deletions src/const.cpp
Expand Up @@ -168,6 +168,11 @@ void set_ckp(napi_env env, napi_value exports)
SET_CONST(CK_PARAMS_SKIPJACK_PRIVATE_WRAP);
SET_CONST(CK_PARAMS_SKIPJACK_RELAYX);
SET_CONST(CK_PARAMS_PBE);
SET_CONST(CK_PARAMS_KEY_WRAP_SET_OAEP);
SET_CONST(CK_PARAMS_GCM);
SET_CONST(CK_PARAMS_CCM);
SET_CONST(CK_PARAM_GOSTR3410_DERIVE);
SET_CONST(CK_PARAM_GOSTR3410_KEY_WRAP);
}

/**
Expand Down
250 changes: 249 additions & 1 deletion src/params.cpp
Expand Up @@ -163,6 +163,76 @@ bool read_property_ulong(napi_env env, napi_value object, const char *property,
} \
}

/**
* @brief Reads a byte property from a given JavaScript object.
*
* @param env The N-API environment.
* @param object The JavaScript object to read the property from.
* @param property The name of the property to read.
* @param value A pointer to store the read value.
* @return Returns true if the property was successfully read, false otherwise.
*/
bool read_property_byte(napi_env env, napi_value object, const char *property, CK_BYTE_PTR value)
{
// Get the property value
napi_value propertyValue;
napi_get_named_property(env, object, property, &propertyValue);

// Check that the property value is a Number
napi_valuetype propertyValueType;
napi_typeof(env, propertyValue, &propertyValueType);
if (propertyValueType != napi_number)
{
return false;
}

// Read the property value and write it to the single byte
uint32_t uintValue;
napi_get_value_uint32(env, propertyValue, (uint32_t *)&uintValue);
if (uintValue > 255)
{
return false;
}
*value = (CK_BYTE)uintValue;

return true;
}

/**
* @brief Macro for reading a required byte property from a given JavaScript object.
*
* Creates a variable with the name of the property and reads the property value into it.
*
* @param property The name of the property to read.
* @param target The JavaScript object to read the property from.
* @param paramType The type of the mechanism parameter.
*/
#define READ_BYTE_REQUIRED(property, target, paramType) \
CK_BYTE property; \
if (!read_property_byte(env, target, #property, &property)) \
{ \
THROW_PROPERTY_TYPE(#property, #paramType, "Number"); \
}

/**
* @brief Macro for reading an optional byte property from a given JavaScript object.
*
* Creates a variable with the name of the property and reads the property value into it
*
* @param property The name of the property to read.
* @param target The JavaScript object to read the property from.
* @param paramType The type of the mechanism parameter.
*/
#define READ_BYTE_OPTIONAL(property, target, paramType) \
CK_BYTE property = 0; \
if (has_property(env, target, #property)) \
{ \
if (!read_property_byte(env, target, #property, &property)) \
{ \
THROW_PROPERTY_TYPE(#property, #paramType, "Number"); \
} \
}

/**
* @brief Reads a byte array property from a given JavaScript object.
*
Expand Down Expand Up @@ -281,6 +351,48 @@ bool read_property_handle(napi_env env, napi_value object, const char *property,
} \
}

bool read_property_string(napi_env env, napi_value object, const char *property, std::string *value)
{
// Get the property value
napi_value propertyValue;
napi_get_named_property(env, object, property, &propertyValue);

// Check that the property value is a String
napi_valuetype propertyValueType;
napi_typeof(env, propertyValue, &propertyValueType);
if (propertyValueType != napi_string)
{
return false;
}

// Read the property value
size_t stringLength;
napi_get_value_string_utf8(env, propertyValue, nullptr, 0, &stringLength);
char *stringValue = (char *)malloc(stringLength + 1);
napi_get_value_string_utf8(env, propertyValue, stringValue, stringLength + 1, &stringLength);
*value = std::string(stringValue);
free(stringValue);

return true;
}

#define READ_STRING_REQUIRED(property, target, paramType) \
std::string property; \
if (!read_property_string(env, target, #property, &property)) \
{ \
THROW_PROPERTY_TYPE(#property, #paramType, "String"); \
}

#define READ_STRING_OPTIONAL(property, target, paramType) \
std::string property; \
if (has_property(env, target, #property)) \
{ \
if (!read_property_string(env, target, #property, &property)) \
{ \
THROW_PROPERTY_TYPE(#property, #paramType, "String"); \
} \
}

/**
* Reads CK_RSA_PKCS_OAEP_PARAMS from a given JavaScript object.
*
Expand Down Expand Up @@ -962,4 +1074,140 @@ bool get_params_pbe(
mechanism->ulParameterLen = sizeof(CK_PBE_PARAMS);

return true;
}
}

// Reads CK_KEY_WRAP_SET_OAEP_PARAMS from a given JavaScript object.
bool get_params_key_wrap_set_oaep(
napi_env env,
napi_value mechanismParameter,
CK_MECHANISM_PTR mechanism)
{
CK_KEY_WRAP_SET_OAEP_PARAMS_PTR params = CK_KEY_WRAP_SET_OAEP_PARAMS_PTR(malloc(sizeof(CK_KEY_WRAP_SET_OAEP_PARAMS)));

// Read the mechanism parameters
READ_BYTE_OPTIONAL(bc, mechanismParameter, CK_KEY_WRAP_SET_OAEP_PARAMS);
READ_BYTES_OPTIONAL(x, mechanismParameter, CK_KEY_WRAP_SET_OAEP_PARAMS);

// Create the mechanism parameters structure
params->bBC = bc;
params->pX = x;
params->ulXLen = xLength;

// Set the mechanism parameters
mechanism->pParameter = params;
mechanism->ulParameterLen = sizeof(CK_KEY_WRAP_SET_OAEP_PARAMS);

return true;
}

// Reads CK_GCM_PARAMS from a given JavaScript object.
bool get_params_gcm(
napi_env env,
napi_value mechanismParameter,
CK_MECHANISM_PTR mechanism)
{
CK_GCM_PARAMS_PTR params = CK_GCM_PARAMS_PTR(malloc(sizeof(CK_GCM_PARAMS)));

// Read the mechanism parameters
READ_BYTES_REQUIRED(iv, mechanismParameter, CK_GCM_PARAMS);
READ_ULONG_REQUIRED(ivBits, mechanismParameter, CK_GCM_PARAMS);
READ_BYTES_OPTIONAL(aad, mechanismParameter, CK_GCM_PARAMS);
READ_ULONG_OPTIONAL(tagBits, mechanismParameter, CK_GCM_PARAMS);

// Create the mechanism parameters structure
params->pIv = iv;
params->ulIvLen = ivLength;
params->ulIvBits = ivBits;
params->pAAD = aad;
params->ulAADLen = aadLength;
params->ulTagBits = tagBits;

// Set the mechanism parameters
mechanism->pParameter = params;
mechanism->ulParameterLen = sizeof(CK_GCM_PARAMS);

return true;
}

// Reads CK_CCM_PARAMS from a given JavaScript object.
bool get_params_ccm(
napi_env env,
napi_value mechanismParameter,
CK_MECHANISM_PTR mechanism)
{
CK_CCM_PARAMS_PTR params = CK_CCM_PARAMS_PTR(malloc(sizeof(CK_CCM_PARAMS)));

// Read the mechanism parameters
READ_ULONG_REQUIRED(dataLength, mechanismParameter, CK_CCM_PARAMS);
READ_BYTES_OPTIONAL(nonce, mechanismParameter, CK_CCM_PARAMS);
READ_BYTES_OPTIONAL(aad, mechanismParameter, CK_CCM_PARAMS);
READ_ULONG_OPTIONAL(macLength, mechanismParameter, CK_CCM_PARAMS);

// Create the mechanism parameters structure
params->ulDataLen = dataLength;
params->pNonce = nonce;
params->ulNonceLen = nonceLength;
params->pAAD = aad;
params->ulAADLen = aadLength;
params->ulMACLen = macLength;

// Set the mechanism parameters
mechanism->pParameter = params;
mechanism->ulParameterLen = sizeof(CK_CCM_PARAMS);

return true;
}

// Reads CK_GOSTR3410_DERIVE_PARAMS from a given JavaScript object.
bool get_params_gost_r3410_derive(
napi_env env,
napi_value mechanismParameter,
CK_MECHANISM_PTR mechanism)
{
CK_GOSTR3410_DERIVE_PARAMS_PTR params = CK_GOSTR3410_DERIVE_PARAMS_PTR(malloc(sizeof(CK_GOSTR3410_DERIVE_PARAMS)));

// Read the mechanism parameters
READ_ULONG_REQUIRED(kdf, mechanismParameter, CK_GOSTR3410_DERIVE_PARAMS);
READ_BYTES_REQUIRED(publicData, mechanismParameter, CK_GOSTR3410_DERIVE_PARAMS);
READ_BYTES_OPTIONAL(ukm, mechanismParameter, CK_GOSTR3410_DERIVE_PARAMS);

// Create the mechanism parameters structure
params->kdf = kdf;
params->pPublicData = publicData;
params->ulPublicDataLen = publicDataLength;
params->pUKM = ukm;
params->ulUKMLen = ukmLength;

// Set the mechanism parameters
mechanism->pParameter = params;
mechanism->ulParameterLen = sizeof(CK_GOSTR3410_DERIVE_PARAMS);

return true;
}

// Reads CK_GOSTR3410_KEY_WRAP_PARAMS from a given JavaScript object.
bool get_params_gost_r3410_key_wrap(
napi_env env,
napi_value mechanismParameter,
CK_MECHANISM_PTR mechanism)
{
CK_GOSTR3410_KEY_WRAP_PARAMS_PTR params = CK_GOSTR3410_KEY_WRAP_PARAMS_PTR(malloc(sizeof(CK_GOSTR3410_KEY_WRAP_PARAMS)));

// Read the mechanism parameters
READ_BYTES_REQUIRED(wrapOID, mechanismParameter, CK_GOSTR3410_KEY_WRAP_PARAMS);
READ_BYTES_OPTIONAL(ukm, mechanismParameter, CK_GOSTR3410_KEY_WRAP_PARAMS);
READ_HANDLE_REQUIRED(key, mechanismParameter, CK_GOSTR3410_KEY_WRAP_PARAMS);

// Create the mechanism parameters structure
params->pWrapOID = wrapOID;
params->ulWrapOIDLen = wrapOIDLength;
params->pUKM = ukm;
params->ulUKMLen = ukmLength;
params->hKey = key;

// Set the mechanism parameters
mechanism->pParameter = params;
mechanism->ulParameterLen = sizeof(CK_GOSTR3410_KEY_WRAP_PARAMS);

return true;
}

0 comments on commit 9bd6a3d

Please sign in to comment.