|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* This program is provided under the terms of the Common Public License,
|
|
Packit |
8681c6 |
* version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
|
|
Packit |
8681c6 |
* software constitutes recipient's acceptance of CPL-1.0 terms which can be
|
|
Packit |
8681c6 |
* found in the file LICENSE file or at
|
|
Packit |
8681c6 |
* https://opensource.org/licenses/cpl1.0.php
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/************************************************************************
|
|
Packit |
8681c6 |
* *
|
|
Packit |
8681c6 |
* Copyright: Corrent Corporation (c) 2000-2003 *
|
|
Packit |
8681c6 |
* *
|
|
Packit |
8681c6 |
* Filename: mech_dh.c *
|
|
Packit |
8681c6 |
* Created By: Kapil Sood *
|
|
Packit |
8681c6 |
* Created On: Jan 18, 2003 *
|
|
Packit |
8681c6 |
* Description: This is the file implementing Diffie-Hellman *
|
|
Packit |
8681c6 |
* key pair generation and shared key derivation *
|
|
Packit |
8681c6 |
* operations. *
|
|
Packit |
8681c6 |
* *
|
|
Packit |
8681c6 |
************************************************************************/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// File: mech_dh.c
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Mechanisms for DH
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Routines contained within:
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <string.h> // for memcmp() et al
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
#include <sys/syslog.h>
|
|
Packit |
8681c6 |
#include <stdio.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "pkcs11types.h"
|
|
Packit |
8681c6 |
#include "defs.h"
|
|
Packit |
8681c6 |
#include "host_defs.h"
|
|
Packit |
8681c6 |
#include "h_extern.h"
|
|
Packit |
8681c6 |
#include "tok_spec_struct.h"
|
|
Packit |
8681c6 |
#include "trace.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#ifndef NODH
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV dh_pkcs_derive(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
SESSION *sess,
|
|
Packit |
8681c6 |
CK_MECHANISM *mech,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE base_key,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *pTemplate,
|
|
Packit |
8681c6 |
CK_ULONG ulCount, CK_OBJECT_HANDLE *handle)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_ULONG i, keyclass = 0, keytype = 0;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr;
|
|
Packit |
8681c6 |
OBJECT *temp_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_BYTE secret_key_value[256];
|
|
Packit |
8681c6 |
CK_ULONG secret_key_value_len = 256;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Prelim checking of sess, mech, pTemplate, and ulCount was
|
|
Packit |
8681c6 |
// done in the calling function (key_mgr_derive_key).
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Perform DH checking of parameters
|
|
Packit |
8681c6 |
// Check the existance of the public-value in mechanism
|
|
Packit Service |
8aa27d |
if (mech->pParameter == NULL || mech->ulParameterLen == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID));
|
|
Packit |
8681c6 |
return (CKR_MECHANISM_PARAM_INVALID);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Check valid object handle pointer of derived key
|
|
Packit |
8681c6 |
if (handle == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_KEY_HANDLE_INVALID));
|
|
Packit |
8681c6 |
return CKR_KEY_HANDLE_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Extract the object class and keytype from the supplied template.
|
|
Packit |
8681c6 |
for (i = 0; i < ulCount; i++) {
|
|
Packit |
8681c6 |
if (pTemplate[i].type == CKA_CLASS) {
|
|
Packit |
8681c6 |
keyclass = *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
|
|
Packit |
8681c6 |
if (keyclass != CKO_SECRET_KEY) {
|
|
Packit |
8681c6 |
TRACE_ERROR("This operation requires a secret key.\n");
|
|
Packit |
8681c6 |
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (pTemplate[i].type == CKA_KEY_TYPE)
|
|
Packit |
8681c6 |
keytype = *(CK_ULONG *) pTemplate[i].pValue;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Extract public-key from mechanism parameters. base-key contains the
|
|
Packit |
8681c6 |
// private key, prime, and base. The return value will be in the handle.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = ckm_dh_pkcs_derive(tokdata, mech->pParameter, mech->ulParameterLen,
|
|
Packit |
8681c6 |
base_key, secret_key_value, &secret_key_value_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Build the attribute from the vales that were returned back
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_VALUE, secret_key_value, secret_key_value_len,
|
|
Packit |
8681c6 |
&new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Failed to build the new attribute.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Create the object that will be passed back as a handle. This will
|
|
Packit |
8681c6 |
// contain the new (computed) value of the attribute.
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_skel(tokdata, sess,
|
|
Packit |
8681c6 |
pTemplate, ulCount,
|
|
Packit |
8681c6 |
MODE_KEYGEN, keyclass, keytype, &temp_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Object Mgr create skeleton failed.\n");
|
|
Packit |
8681c6 |
free(new_attr);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Update the template in the object with the new attribute
|
|
Packit |
8681c6 |
template_update_attribute(temp_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// at this point, the derived key is fully constructed...assign an
|
|
Packit |
8681c6 |
// object handle and store the key
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, sess, temp_obj, handle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Object Mgr create final failed.\n");
|
|
Packit |
8681c6 |
object_free(temp_obj);
|
|
Packit |
8681c6 |
temp_obj = NULL;
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// mechanisms
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV ckm_dh_pkcs_derive(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
CK_VOID_PTR other_pubkey,
|
|
Packit |
8681c6 |
CK_ULONG other_pubkey_len,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE base_key,
|
|
Packit |
8681c6 |
CK_BYTE *secret_value, CK_ULONG *secret_value_len)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_BYTE p[256];
|
|
Packit |
8681c6 |
CK_ULONG p_len;
|
|
Packit |
8681c6 |
CK_BYTE x[256];
|
|
Packit |
8681c6 |
CK_ULONG x_len;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *temp_attr;
|
|
Packit |
8681c6 |
OBJECT *base_key_obj = NULL;
|
|
Packit |
8681c6 |
CK_BYTE *p_other_pubkey;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, base_key, &base_key_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to acquire key from specified handle");
|
|
Packit |
8681c6 |
if (rc == CKR_OBJECT_HANDLE_INVALID)
|
|
Packit |
8681c6 |
return CKR_KEY_HANDLE_INVALID;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Extract secret (x) from base_key
|
|
Packit |
8681c6 |
rc = template_attribute_find(base_key_obj->template, CKA_VALUE, &temp_attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Could not find CKA_VALUE in the template\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
memset(x, 0, sizeof(x));
|
|
Packit |
8681c6 |
x_len = temp_attr->ulValueLen;
|
|
Packit |
8681c6 |
memcpy(x, (CK_BYTE *) temp_attr->pValue, x_len);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Extract prime (p) from base_key
|
|
Packit |
8681c6 |
rc = template_attribute_find(base_key_obj->template, CKA_PRIME, &temp_attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Could not find CKA_PRIME in the template\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
memset(p, 0, sizeof(p));
|
|
Packit |
8681c6 |
p_len = temp_attr->ulValueLen;
|
|
Packit |
8681c6 |
memcpy(p, (CK_BYTE *) temp_attr->pValue, p_len);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
p_other_pubkey = (CK_BYTE *) other_pubkey;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Perform: z = other_pubkey^x mod p
|
|
Packit |
8681c6 |
rc = token_specific.t_dh_pkcs_derive(tokdata, secret_value,
|
|
Packit |
8681c6 |
secret_value_len, p_other_pubkey,
|
|
Packit |
8681c6 |
other_pubkey_len, x, x_len, p, p_len);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
TRACE_DEVEL("Token specific dh pkcs derive failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
object_put(tokdata, base_key_obj, TRUE);
|
|
Packit |
8681c6 |
base_key_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV ckm_dh_pkcs_key_pair_gen(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_specific.t_dh_pkcs_key_pair_gen(tokdata, publ_tmpl, priv_tmpl);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
TRACE_DEVEL("Token specific dh pkcs key pair gen failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#endif
|