1
votes

I'm trying to perform ECDH using a Thales Connect HSM. Part of that requires a DeriveKey operation which in turn requires importing a template key (which holds an ACL that will be attached to the result of the DeriveKey operation).

Import of the template key fails in spite of trying all the methods I could find in the API documentation - I get Status_InvalidParameter as the response. Hoping someone has used the API for something similar (trying to open a support channel with Thales in parallel).

// Generate nested ACL
M_ACL nestedAcl;
memset(&nestedAcl, 0, sizeof(M_ACL));
nestedAcl.n_groups = 1;

M_PermissionGroup nestedAclPermGroup;
memset(&nestedAclPermGroup, 0, sizeof(M_PermissionGroup));
nestedAclPermGroup.n_actions = 1;
nestedAclPermGroup.flags = 0x0;
nestedAclPermGroup.n_limits = 0;
nestedAclPermGroup.certifier = NULL;

M_Action nestedAclAction0;
memset(&nestedAclAction0, 0, sizeof(M_Action));
nestedAclAction0.type = Act_OpPermissions;
nestedAclAction0.details.oppermissions.perms =
              Act_OpPermissions_Details_perms_Encrypt;

nestedAclPermGroup.actions = &nestedAclAction0;
nestedAcl.groups = &nestedAclPermGroup;

M_ByteBlock nestedAclBytes;

ret = NFastApp_MarshalACL(app, *connection, worldInfo, &nestedAcl, &nestedAclBytes);
if (ret != Status_OK)
{
   printf("Failed to create nested ACL: ret = %d \n", ret);
}

// Import template key
M_Command importTemplateKeyCmd;
M_Reply importTemplateKeyReply;
importTemplateKeyCmd.cmd = Cmd_Import;
importTemplateKeyCmd.args.import.data.type = KeyType_DKTemplate;
importTemplateKeyCmd.args.import.data.data.dktemplate.nested_acl = nestedAclBytes;

char appdataTemplateKey[] = "02020202";
memset(&appdataTemplateKey, 0, sizeof(M_AppData));
memcpy(importTemplateKeyCmd.args.import.appdata.bytes, appdataTemplateKey, strlen(appdataTemplateKey) < 64 ? strlen(appdataTemplateKey) : 63);

// Generate the import command ACL
NFKM_MakeACLParams templateKeyAclParams;
memset(&templateKeyAclParams, 0, sizeof(templateKeyAclParams));
templateKeyAclParams.f = 0x0;
templateKeyAclParams.op_base = Act_DeriveKey;
templateKeyAclParams.timelimit = 0;

M_ACL* templateKeyAcl;
templateKeyAcl = malloc(sizeof(M_ACL));
templateKeyAcl->n_groups = 1;
/*
M_PermissionGroup* templateKeyAclPermissionGroup;
templateKeyAclPermissionGroup = malloc(sizeof(M_PermissionGroup));
templateKeyAclPermissionGroup->flags = 0x0;
templateKeyAclPermissionGroup->n_limits = 0;
templateKeyAclPermissionGroup->n_actions = 1;
templateKeyAclPermissionGroup->certifier = NULL;

M_Action* templateKeyAction;
templateKeyAction = malloc(sizeof(M_Action));
templateKeyAction->type = Act_DeriveKey;
templateKeyAction->details.derivekey.flags = 0x0;
templateKeyAction->details.derivekey.role = DeriveRole_TemplateKey;
templateKeyAction->details.derivekey.mech = Mech_Any;
templateKeyAction->details.derivekey.n_otherkeys = 0;

templateKeyAclPermissionGroup->actions = templateKeyAction;

templateKeyAcl->groups = templateKeyAclPermissionGroup;
*/
// NF_MarshalFast_ACL(*connection, templateKeyAcl);

NFKM_MkACLHandle mkAclHandle;
mkAclHandle = malloc(sizeof(mkAclHandle));
NFKM_mkacl_create(app, *connection, &mkAclHandle, 0);
NFKM_mkacl_pgroup(mkAclHandle, 0x0, NULL);
NFKM_mkacl_derivekey(mkAclHandle, 0x0, DeriveRole_TemplateKey, DeriveMech_Any);
NFKM_mkacl_setacl(mkAclHandle, templateKeyAcl);
importTemplateKeyCmd.args.import.acl = *templateKeyAcl;

ret = (M_Status)NFastApp_Transact(*connection, 0, &importTemplateKeyCmd, &importTemplateKeyReply, 0);
if (ret != Status_OK)
{
   printf("Failed to import template key: %d (%d)\n", ret, importTemplateKeyReply.status);
}
1
Always include a runtime environment in the tags! Your question will be more visible and the automated syntax highlighting can do its work. This is pretty vendor specific, so it may be tricky to get an answer here. Did you contact Thales?Maarten Bodewes
It indeed was a shot in the dark since the question revolves entirely around how to use the API. I have contacted Thales without a response yet.sce

1 Answers

0
votes

The approach that ended up working (suggested by Thales) was to break up the operation into two parts - do a CMD_Decrypt with Mech_ECDHKeyExchange to derive the shared secret and then a CMD_Hash on the resultant x-coordinate to derive the key.