|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* COPYRIGHT (c) International Business Machines Corp. 2005-2017
|
|
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 |
* tpm_specific.c
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Feb 10, 2005
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Author: Kent Yoder <yoder1@us.ibm.com>
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Encryption routines are based on ../soft_stdll/soft_specific.c.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#define _GNU_SOURCE
|
|
Packit |
8681c6 |
#include <stdio.h>
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <string.h>
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <sys/types.h>
|
|
Packit |
8681c6 |
#include <sys/stat.h>
|
|
Packit |
8681c6 |
#include <fcntl.h>
|
|
Packit |
8681c6 |
#include <unistd.h>
|
|
Packit |
8681c6 |
#include <errno.h>
|
|
Packit |
8681c6 |
#include <pwd.h>
|
|
Packit |
8681c6 |
#include <syslog.h>
|
|
Packit |
8681c6 |
#include <grp.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <openssl/des.h>
|
|
Packit |
8681c6 |
#include <openssl/rand.h>
|
|
Packit |
8681c6 |
#include <openssl/rsa.h>
|
|
Packit |
8681c6 |
#include <openssl/aes.h>
|
|
Packit |
8681c6 |
#include <openssl/evp.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <tss/platform.h>
|
|
Packit |
8681c6 |
#include <tss/tss_defines.h>
|
|
Packit |
8681c6 |
#include <tss/tss_typedef.h>
|
|
Packit |
8681c6 |
#include <tss/tss_structs.h>
|
|
Packit |
8681c6 |
#include <tss/tss_error.h>
|
|
Packit |
8681c6 |
#include <tss/tspi.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "pkcs11types.h"
|
|
Packit |
8681c6 |
#include "stdll.h"
|
|
Packit |
8681c6 |
#include "defs.h"
|
|
Packit |
8681c6 |
#include "host_defs.h"
|
|
Packit |
8681c6 |
#include "h_extern.h"
|
|
Packit |
8681c6 |
#include "tok_specific.h"
|
|
Packit |
8681c6 |
#include "tok_spec_struct.h"
|
|
Packit |
8681c6 |
#include "tok_struct.h"
|
|
Packit |
8681c6 |
#include "trace.h"
|
|
Packit |
8681c6 |
#include "ock_syslog.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "tpm_specific.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "../api/apiproto.h"
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
typedef struct {
|
|
Packit |
8681c6 |
CK_BYTE master_key_private[MK_SIZE];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* The context we'll use globally to connect to the TSP */
|
|
Packit |
8681c6 |
TSS_HCONTEXT tspContext;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* TSP key handles */
|
|
Packit |
8681c6 |
TSS_HKEY hSRK;
|
|
Packit |
8681c6 |
TSS_HKEY hPublicRootKey;
|
|
Packit |
8681c6 |
TSS_HKEY hPublicLeafKey;
|
|
Packit |
8681c6 |
TSS_HKEY hPrivateRootKey;
|
|
Packit |
8681c6 |
TSS_HKEY hPrivateLeafKey;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* TSP policy handles */
|
|
Packit |
8681c6 |
TSS_HPOLICY hDefaultPolicy;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* PKCS#11 key handles */
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckPublicRootKey;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckPublicLeafKey;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckPrivateRootKey;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckPrivateLeafKey;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int not_initialized;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_BYTE current_user_pin_sha[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
CK_BYTE current_so_pin_sha[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
} tpm_private_data_t;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT util_set_public_modulus(TSS_HCONTEXT tspContext, TSS_HKEY,
|
|
Packit |
8681c6 |
unsigned long, unsigned char *);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
const char manuf[] = "IBM";
|
|
Packit |
8681c6 |
const char model[] = "TPM";
|
|
Packit |
8681c6 |
const char descr[] = "IBM TPM v1.1 token";
|
|
Packit |
8681c6 |
const char label[] = "tpmtok";
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
static const MECH_LIST_ELEMENT tpm_mech_list[] = {
|
|
Packit |
8681c6 |
{CKM_RSA_PKCS_KEY_PAIR_GEN, {512, 2048, CKF_GENERATE_KEY_PAIR}},
|
|
Packit |
8681c6 |
{CKM_DES_KEY_GEN, {0, 0, CKF_GENERATE}},
|
|
Packit |
8681c6 |
{CKM_DES3_KEY_GEN, {0, 0, CKF_GENERATE}},
|
|
Packit |
8681c6 |
{CKM_RSA_PKCS, {512, 2048, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP |
|
|
Packit |
8681c6 |
CKF_UNWRAP | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER |
|
|
Packit |
8681c6 |
CKF_VERIFY_RECOVER}},
|
|
Packit |
8681c6 |
{CKM_MD5_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_SHA1_RSA_PKCS, {512, 2048, CKF_HW | CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_DES_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_DES_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_DES_CBC_PAD,
|
|
Packit |
8681c6 |
{0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_DES3_ECB, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_DES3_CBC, {0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_DES3_CBC_PAD,
|
|
Packit |
8681c6 |
{0, 0, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_SHA_1, {0, 0, CKF_DIGEST}},
|
|
Packit |
8681c6 |
{CKM_SHA_1_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_SHA_1_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_MD5, {0, 0, CKF_DIGEST}},
|
|
Packit |
8681c6 |
{CKM_MD5_HMAC, {0, 0, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_MD5_HMAC_GENERAL, {0, 0, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}},
|
|
Packit |
8681c6 |
{CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}},
|
|
Packit |
8681c6 |
{CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}},
|
|
Packit |
8681c6 |
{CKM_SSL3_MD5_MAC, {384, 384, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_SSL3_SHA1_MAC, {384, 384, CKF_SIGN | CKF_VERIFY}},
|
|
Packit |
8681c6 |
{CKM_AES_KEY_GEN, {16, 32, CKF_GENERATE}},
|
|
Packit |
8681c6 |
{CKM_AES_ECB, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_AES_CBC, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}},
|
|
Packit |
8681c6 |
{CKM_AES_CBC_PAD, {16, 32, CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP |
|
|
Packit |
8681c6 |
CKF_UNWRAP}},
|
|
Packit |
8681c6 |
};
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
static const CK_ULONG tpm_mech_list_len =
|
|
Packit |
8681c6 |
(sizeof(tpm_mech_list) / sizeof(MECH_LIST_ELEMENT));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
static void clear_internal_structures(STDLL_TokData_t * tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tpm_data->hSRK = NULL_HKEY;
|
|
Packit |
8681c6 |
tpm_data->hPrivateLeafKey = NULL_HKEY;
|
|
Packit |
8681c6 |
tpm_data->hPublicLeafKey = NULL_HKEY;
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(tpm_data->master_key_private, 0, MK_SIZE);
|
|
Packit |
8681c6 |
memset(tpm_data->current_so_pin_sha, 0, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
memset(tpm_data->current_user_pin_sha, 0, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rng(STDLL_TokData_t * tokdata, CK_BYTE * output,
|
|
Packit |
8681c6 |
CK_ULONG bytes)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT rc;
|
|
Packit |
8681c6 |
TSS_HTPM hTPM;
|
|
Packit |
8681c6 |
BYTE *random_bytes = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = Tspi_Context_GetTpmObject(tpm_data->tspContext, &hTPM);
|
|
Packit |
8681c6 |
if (rc) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_GetTpmObject: %x\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = Tspi_TPM_GetRandom(hTPM, bytes, &random_bytes);
|
|
Packit |
8681c6 |
if (rc) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_TPM_GetRandom failed. rc=0x%x\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(output, random_bytes, bytes);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, random_bytes);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_init(STDLL_TokData_t * tokdata, CK_SLOT_ID SlotNumber,
|
|
Packit |
8681c6 |
char *conf_name)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
char path_buf[PATH_MAX], fname[PATH_MAX];
|
|
Packit |
8681c6 |
struct stat statbuf;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(conf_name);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TRACE_INFO("tpm %s slot=%lu running\n", __func__, SlotNumber);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->mech_list = (MECH_LIST_ELEMENT *)tpm_mech_list;
|
|
Packit |
8681c6 |
tokdata->mech_list_len = tpm_mech_list_len;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// if the user specific directory doesn't exist, create it
|
|
Packit Service |
8aa27d |
if (get_pk_dir(tokdata, fname, PATH_MAX) == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("pk_dir buffer overflow\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
if (stat(fname, &statbuf) < 0) {
|
|
Packit Service |
8aa27d |
if (mkdir(fname, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("mkdir(%s): %s\n", fname, strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// now create userdir/TOK_OBJ if it doesn't exist
|
|
Packit Service |
8aa27d |
if (ock_snprintf(path_buf, PATH_MAX, "%s/%s", fname, PK_LITE_OBJ_DIR) != 0) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("userdir/TOK_OBJ path name overflow\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit |
8681c6 |
if (stat(path_buf, &statbuf) < 0) {
|
|
Packit |
8681c6 |
if (mkdir(path_buf, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
|
|
Packit |
8681c6 |
TRACE_ERROR("mkdir(%s): %s\n", path_buf, strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tpm_data = (tpm_private_data_t *)calloc(1, sizeof(tpm_private_data_t));
|
|
Packit |
8681c6 |
tokdata->private_data = tpm_data;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tpm_data->tspContext = NULL_HCONTEXT;
|
|
Packit |
8681c6 |
clear_internal_structures(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_Create(&tpm_data->tspContext);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_Create failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_Connect(tpm_data->tspContext, NULL);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_Connect failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_GetDefaultPolicy(tpm_data->tspContext,
|
|
Packit |
8681c6 |
&tpm_data->hDefaultPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_GetDefaultPolicy failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
OpenSSL_add_all_algorithms();
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_find_key(STDLL_TokData_t * tokdata, int key_type,
|
|
Packit |
8681c6 |
CK_OBJECT_CLASS class, CK_OBJECT_HANDLE * handle)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_BYTE *key_id = util_create_id(key_type);
|
|
Packit |
8681c6 |
CK_RV rc = CKR_OK;
|
|
Packit |
8681c6 |
CK_BBOOL true = TRUE;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE tmpl[] = {
|
|
Packit |
8681c6 |
{CKA_ID, key_id, strlen((char *) key_id)},
|
|
Packit |
8681c6 |
{CKA_CLASS, &class, sizeof(class)},
|
|
Packit |
8681c6 |
{CKA_HIDDEN, &true, sizeof(CK_BBOOL)}
|
|
Packit |
8681c6 |
};
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE hObj;
|
|
Packit |
8681c6 |
CK_ULONG ulObjCount;
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* init the dummy session state to something that will find any object on
|
|
Packit |
8681c6 |
* the token */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_init(tokdata, &dummy_sess, tmpl, 3);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* pulled from SC_FindObjects */
|
|
Packit |
8681c6 |
ulObjCount = MIN(1, (dummy_sess.find_count - dummy_sess.find_idx));
|
|
Packit |
8681c6 |
memcpy(&hObj, dummy_sess.find_list + dummy_sess.find_idx,
|
|
Packit |
8681c6 |
ulObjCount * sizeof(CK_OBJECT_HANDLE));
|
|
Packit |
8681c6 |
dummy_sess.find_idx += ulObjCount;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (ulObjCount > 1) {
|
|
Packit |
8681c6 |
TRACE_INFO("More than one matching key found in the store!\n");
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_FOUND;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else if (ulObjCount < 1) {
|
|
Packit |
8681c6 |
TRACE_INFO("key with ID=\"%s\" not found in the store!\n", key_id);
|
|
Packit |
8681c6 |
rc = CKR_KEY_NOT_FOUND;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*handle = hObj;
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
object_mgr_find_final(&dummy_sess);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_get_key_blob(STDLL_TokData_t * tokdata, CK_OBJECT_HANDLE ckKey,
|
|
Packit |
8681c6 |
CK_ULONG * blob_size, CK_BYTE ** ret_blob)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc = CKR_OK;
|
|
Packit |
8681c6 |
CK_BYTE_PTR blob = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE tmpl[] = {
|
|
Packit |
8681c6 |
{CKA_IBM_OPAQUE, NULL_PTR, 0}
|
|
Packit |
8681c6 |
};
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set up dummy session */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RO_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find object the first time to return the size of the buffer needed */
|
|
Packit |
8681c6 |
rc = object_mgr_get_attribute_values(tokdata, &dummy_sess, ckKey, tmpl, 1);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_get_attribute_values failed:rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
blob = malloc(tmpl[0].ulValueLen);
|
|
Packit |
8681c6 |
if (blob == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("malloc %ld bytes failed.\n", tmpl[0].ulValueLen);
|
|
Packit |
8681c6 |
rc = CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tmpl[0].pValue = blob;
|
|
Packit |
8681c6 |
/* find object the 2nd time to fill the buffer with data */
|
|
Packit |
8681c6 |
rc = object_mgr_get_attribute_values(tokdata, &dummy_sess, ckKey, tmpl, 1);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_get_attribute_values failed:rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*ret_blob = blob;
|
|
Packit |
8681c6 |
*blob_size = tmpl[0].ulValueLen;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_wrap_sw_key(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
int size_n, unsigned char *n, int size_p,
|
|
Packit |
8681c6 |
unsigned char *p, TSS_HKEY hParentKey,
|
|
Packit |
8681c6 |
TSS_FLAG initFlags, TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy;
|
|
Packit |
8681c6 |
TSS_BOOL get_srk_pub_key = TRUE;
|
|
Packit |
8681c6 |
UINT32 key_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
key_size = util_get_keysize_flag(size_n * 8);
|
|
Packit |
8681c6 |
if (initFlags == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid key size.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create the TSS key object */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_RSAKEY,
|
|
Packit |
8681c6 |
TSS_KEY_MIGRATABLE | initFlags |
|
|
Packit |
8681c6 |
key_size, phKey);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed: rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = util_set_public_modulus(tpm_data->tspContext, *phKey, size_n, n);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("util_set_public_modulus failed:rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set the private key data in the TSS object */
|
|
Packit |
8681c6 |
result = Tspi_SetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY, size_p, p);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed: rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* if the parent wrapping key is the SRK, we need to manually pull
|
|
Packit |
8681c6 |
* out the SRK's pub key, which is not stored in persistent storage
|
|
Packit |
8681c6 |
* for privacy reasons */
|
|
Packit |
8681c6 |
if (hParentKey == tpm_data->hSRK && get_srk_pub_key == TRUE) {
|
|
Packit |
8681c6 |
UINT32 pubKeySize;
|
|
Packit |
8681c6 |
BYTE *pubKey;
|
|
Packit |
8681c6 |
result = Tspi_Key_GetPubKey(hParentKey, &pubKeySize, &pubKey);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
if (result == TPM_E_INVALID_KEYHANDLE) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_WARNING,
|
|
Packit |
8681c6 |
"Warning: Your TPM is not configured to allow "
|
|
Packit |
8681c6 |
"reading the public SRK by anyone but the owner. "
|
|
Packit |
8681c6 |
"Use tpm_restrictsrk -a to allow reading the public "
|
|
Packit |
8681c6 |
"SRK");
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "Tspi_Key_GetPubKey failed: rc=0x%x",
|
|
Packit |
8681c6 |
result);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, pubKey);
|
|
Packit |
8681c6 |
get_srk_pub_key = FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_MIGRATION, &hPolicy);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
|
|
Packit |
8681c6 |
result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
|
|
Packit |
8681c6 |
TSS_ES_RSAESPKCSV15);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
|
|
Packit |
8681c6 |
TSS_SS_RSASSAPKCS1V15_DER);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_WrapKey(*phKey, hParentKey, NULL_HPCRS);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_WrapKey failed: rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Create a TPM key blob for an imported key. This function is only called when
|
|
Packit |
8681c6 |
* a key is in active use, so any failure should trickle through.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Note: The passed Object ckObject must not hold a lock, this function might
|
|
Packit |
8681c6 |
* need to acquire a WRITE lock on the object!
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
CK_RV token_wrap_key_object(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckObject, TSS_HKEY hParentKey,
|
|
Packit |
8681c6 |
TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc = CKR_OK;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL, *new_attr, *prime_attr;
|
|
Packit |
8681c6 |
CK_ULONG class, key_type;
|
|
Packit |
8681c6 |
CK_BBOOL found;
|
|
Packit |
8681c6 |
OBJECT *obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_FLAG initFlags = 0;
|
|
Packit |
8681c6 |
BYTE *rgbBlob;
|
|
Packit |
8681c6 |
UINT32 ulBlobLen;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, ckObject, &obj, WRITE_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_find_in_map1 failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* if the object isn't a key, fail */
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template, CKA_KEY_TYPE, &attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
key_type = *((CK_ULONG *) attr->pValue);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (key_type != CKK_RSA) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Bad key type!\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template, CKA_CLASS, &attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_CLASS) failed.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
class = *((CK_ULONG *) attr->pValue);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (class == CKO_PRIVATE_KEY) {
|
|
Packit |
8681c6 |
/* In order to create a full TSS key blob using a PKCS#11 private key
|
|
Packit |
8681c6 |
* object, we need one of the two primes, the modulus and the private
|
|
Packit |
8681c6 |
* exponent and we need the public exponent to be correct */
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* check the least likely attribute to exist first, the primes */
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template,
|
|
Packit |
8681c6 |
CKA_PRIME_1, &prime_attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template,
|
|
Packit |
8681c6 |
CKA_PRIME_2, &prime_attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Couldn't find prime1 or prime2 of"
|
|
Packit |
8681c6 |
" key object to wrap\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Make sure the public exponent is usable */
|
|
Packit |
8681c6 |
if ((util_check_public_exponent(obj->template))) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid public exponent\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* get the modulus */
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template, CKA_MODULUS, &attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Couldn't find a required attribute of "
|
|
Packit |
8681c6 |
"key object\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* make sure the key size is usable */
|
|
Packit |
8681c6 |
initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
|
|
Packit |
8681c6 |
if (initFlags == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid key size.\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* generate the software based key */
|
|
Packit |
8681c6 |
rc = token_wrap_sw_key(tokdata, (int) attr->ulValueLen, attr->pValue,
|
|
Packit |
8681c6 |
(int) prime_attr->ulValueLen,
|
|
Packit |
8681c6 |
prime_attr->pValue,
|
|
Packit |
8681c6 |
hParentKey,
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION,
|
|
Packit |
8681c6 |
phKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lu\n", rc);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else if (class == CKO_PUBLIC_KEY) {
|
|
Packit |
8681c6 |
/* Make sure the public exponent is usable */
|
|
Packit |
8681c6 |
if ((util_check_public_exponent(obj->template))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Invalid public exponent\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the modulus to put into the TSS key object */
|
|
Packit |
8681c6 |
found = template_attribute_find(obj->template, CKA_MODULUS, &attr);
|
|
Packit |
8681c6 |
if (found == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Couldn't find a required attribute of "
|
|
Packit |
8681c6 |
"key object\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* make sure the key size is usable */
|
|
Packit |
8681c6 |
initFlags = util_get_keysize_flag(attr->ulValueLen * 8);
|
|
Packit |
8681c6 |
if (initFlags == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid key size.\n");
|
|
Packit |
8681c6 |
rc = CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
initFlags |=
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_LEGACY | TSS_KEY_MIGRATABLE | TSS_KEY_NO_AUTHORIZATION;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_RSAKEY,
|
|
Packit |
8681c6 |
initFlags, phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. " "rc=0x%x\n",
|
|
Packit |
8681c6 |
result);
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = util_set_public_modulus(tpm_data->tspContext, *phKey,
|
|
Packit |
8681c6 |
attr->ulValueLen, attr->pValue);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("util_set_public_modulus failed: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
TRACE_ERROR("Bad key class!\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the entire key blob to put into the PKCS#11 object */
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(*phKey, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYBLOB_BLOB,
|
|
Packit |
8681c6 |
&ulBlobLen, &rgbBlob);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* insert the key blob into the object */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_atribute failed\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(obj->template, new_attr);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* if this is a token object, save it with the new attribute so that we
|
|
Packit |
8681c6 |
* don't have to go down this path again */
|
|
Packit |
8681c6 |
if (!object_is_session_object(obj)) {
|
|
Packit |
8681c6 |
rc = XProcLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to get process lock.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = save_token_object(tokdata, obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
rc = XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to release process lock.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
object_put(tokdata, obj, TRUE);
|
|
Packit |
8681c6 |
obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* load a key in the TSS hierarchy from its CK_OBJECT_HANDLE
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Note: The passed Object ckKey must not hold a lock, this function might
|
|
Packit |
8681c6 |
* need to acquire a READ or WRITE lock on the object!
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
CK_RV token_load_key(STDLL_TokData_t * tokdata, CK_OBJECT_HANDLE ckKey,
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey, CK_CHAR_PTR passHash,
|
|
Packit |
8681c6 |
TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy;
|
|
Packit |
8681c6 |
CK_BYTE *blob = NULL;
|
|
Packit |
8681c6 |
CK_ULONG ulBlobSize = 0;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_get_key_blob(tokdata, ckKey, &ulBlobSize, &blob;;
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
if (rc != CKR_ATTRIBUTE_TYPE_INVALID) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_get_key_blob failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
/* the key blob wasn't found, so check for a modulus
|
|
Packit |
8681c6 |
* to load */
|
|
Packit |
8681c6 |
TRACE_DEVEL("key blob not found, checking for modulus\n");
|
|
Packit |
8681c6 |
rc = token_wrap_key_object(tokdata, ckKey, hParentKey, phKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_key_object failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (blob != NULL) {
|
|
Packit |
8681c6 |
/* load the key inside the TSS */
|
|
Packit |
8681c6 |
result = Tspi_Context_LoadKeyByBlob(tpm_data->tspContext,
|
|
Packit |
8681c6 |
hParentKey,
|
|
Packit |
8681c6 |
ulBlobSize, blob, phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_LoadKeyByBlob: 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#if 0
|
|
Packit |
8681c6 |
if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetPolicyObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (passHash == NULL) {
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE, passHash);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret: 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
free(blob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT token_load_srk(STDLL_TokData_t * tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_UUID SRK_UUID = TSS_UUID_SRK;
|
|
Packit |
8681c6 |
struct srk_info srk;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tpm_data->hSRK != NULL_HKEY)
|
|
Packit |
8681c6 |
return TSS_SUCCESS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* load the SRK */
|
|
Packit |
8681c6 |
result = Tspi_Context_LoadKeyByUUID(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_PS_TYPE_SYSTEM, SRK_UUID,
|
|
Packit |
8681c6 |
&tpm_data->hSRK);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_LoadKeyByUUID failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#if 0
|
|
Packit |
8681c6 |
if ((result = Tspi_GetPolicyObject(tpm_data->hSRK, TSS_POLICY_USAGE,
|
|
Packit |
8681c6 |
&hPolicy))) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetPolicyObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hPolicy, tpm_data->hSRK);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* get the srk info */
|
|
Packit |
8681c6 |
memset(&srk, 0, sizeof(srk));
|
|
Packit |
8681c6 |
if (get_srk_info(&srk))
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, (TSS_FLAG) srk.mode,
|
|
Packit |
8681c6 |
srk.len, (BYTE *) srk.secret);
|
|
Packit |
8681c6 |
if (result)
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (srk.secret)
|
|
Packit |
8681c6 |
free(srk.secret);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT token_load_public_root_key(STDLL_TokData_t * tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
BYTE *blob;
|
|
Packit |
8681c6 |
CK_ULONG blob_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tpm_data->hPublicRootKey != NULL_HKEY)
|
|
Packit |
8681c6 |
return TSS_SUCCESS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_load_srk(tokdata);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPublicRootKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_get_key_blob(tokdata, tpm_data->ckPublicRootKey, &blob_size,
|
|
Packit |
8681c6 |
&blob;;
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_get_key_blob failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* load the Public Root Key */
|
|
Packit |
8681c6 |
result = Tspi_Context_LoadKeyByBlob(tpm_data->tspContext, tpm_data->hSRK,
|
|
Packit |
8681c6 |
blob_size, blob,
|
|
Packit |
8681c6 |
&tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_LoadKeyByBlob failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
free(blob);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
free(blob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT tss_generate_key(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
TSS_FLAG initFlags, BYTE * passHash,
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey, TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy, hMigPolicy = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_RSAKEY,
|
|
Packit |
8681c6 |
initFlags, phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#if 0
|
|
Packit |
8681c6 |
if ((result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy))) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetPolicyObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#else
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
#endif
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (passHash == NULL) {
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_NONE, 0, NULL);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
result =
|
|
Packit |
8681c6 |
Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1, 20, passHash);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (TPMTOK_TSS_KEY_MIG_TYPE(initFlags) == TSS_KEY_MIGRATABLE) {
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_MIGRATION, &hMigPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (passHash == NULL) {
|
|
Packit |
8681c6 |
result =
|
|
Packit |
8681c6 |
Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_NONE, 0,
|
|
Packit |
8681c6 |
NULL);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hMigPolicy, TSS_SECRET_MODE_SHA1, 20,
|
|
Packit |
8681c6 |
passHash);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hMigPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hMigPolicy, *phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hMigPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (TPMTOK_TSS_KEY_TYPE(initFlags) == TSS_KEY_TYPE_LEGACY) {
|
|
Packit |
8681c6 |
result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
|
|
Packit |
8681c6 |
TSS_ES_RSAESPKCSV15);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hMigPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_SetAttribUint32(*phKey, TSS_TSPATTRIB_KEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
|
|
Packit |
8681c6 |
TSS_SS_RSASSAPKCS1V15_DER);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribUint32 failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hMigPolicy);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_CreateKey(*phKey, hParentKey, 0);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_CreateKey failed with rc: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hPolicy);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hMigPolicy);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT tss_change_auth(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
TSS_HKEY hObjectToChange, TSS_HKEY hParentObject,
|
|
Packit |
8681c6 |
CK_CHAR * passHash)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed: 0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE, passHash);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed: 0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_ChangeAuth(hObjectToChange, hParentObject, hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_ChangeAuth failed: 0x%x\n", result);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_store_priv_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
|
|
Packit |
8681c6 |
int key_type, CK_OBJECT_HANDLE * ckKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr = NULL;
|
|
Packit |
8681c6 |
OBJECT *priv_key_obj = NULL;
|
|
Packit |
8681c6 |
BYTE *rgbBlob = NULL, *rgbPrivBlob = NULL;
|
|
Packit |
8681c6 |
UINT32 ulBlobLen = 0, ulPrivBlobLen = 0;
|
|
Packit |
8681c6 |
CK_BBOOL flag;
|
|
Packit |
8681c6 |
CK_BYTE *key_id = util_create_id(key_type);
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set up dummy session */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the entire key blob to put into the PKCS#11 private key object */
|
|
Packit |
8681c6 |
rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYBLOB_BLOB, &ulBlobLen, &rgbBlob);
|
|
Packit |
8681c6 |
if (rc) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the encrypted provate key to put into the object */
|
|
Packit |
8681c6 |
rc = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY,
|
|
Packit |
8681c6 |
&ulPrivBlobLen, &rgbPrivBlob);
|
|
Packit |
8681c6 |
if (rc) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create skeleton for the private key object */
|
|
Packit |
8681c6 |
rc = object_create_skel(tokdata, NULL, 0, MODE_KEYGEN,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, CKK_RSA, &priv_key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("objectr_create_skel: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPrivBlob);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the ID attribute */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ID, key_id, strlen((char *) key_id), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPrivBlob);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the key blob to the PKCS#11 object template */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPrivBlob);
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the private key blob to the PKCS#11 object template */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_MODULUS, rgbPrivBlob, ulPrivBlobLen, &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPrivBlob);
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPrivBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the HIDDEN attribute */
|
|
Packit |
8681c6 |
flag = TRUE;
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set CKA_ALWAYS_SENSITIVE to true */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ALWAYS_SENSITIVE, &flag,
|
|
Packit |
8681c6 |
sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set CKA_NEVER_EXTRACTABLE to true */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_NEVER_EXTRACTABLE,
|
|
Packit |
8681c6 |
&flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* make the object reside on the token, as if that were possible */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
flag = FALSE;
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_PRIVATE, &flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, &dummy_sess, priv_key_obj, ckKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed.\n");
|
|
Packit |
8681c6 |
object_free(priv_key_obj);
|
|
Packit |
8681c6 |
priv_key_obj = NULL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_store_pub_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
|
|
Packit |
8681c6 |
int key_type, CK_OBJECT_HANDLE * ckKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr = NULL;
|
|
Packit |
8681c6 |
OBJECT *pub_key_obj;
|
|
Packit |
8681c6 |
CK_BBOOL flag = TRUE;
|
|
Packit |
8681c6 |
CK_OBJECT_CLASS pub_class = CKO_PUBLIC_KEY;
|
|
Packit |
8681c6 |
CK_KEY_TYPE type = CKK_RSA;
|
|
Packit |
8681c6 |
CK_BYTE *key_id = util_create_id(key_type);
|
|
Packit |
8681c6 |
CK_BYTE pub_exp[] = { 1, 0, 1 }; // 65537
|
|
Packit |
8681c6 |
CK_ATTRIBUTE pub_tmpl[] = {
|
|
Packit |
8681c6 |
{CKA_CLASS, &pub_class, sizeof(pub_class)},
|
|
Packit |
8681c6 |
{CKA_KEY_TYPE, &type, sizeof(type)},
|
|
Packit |
8681c6 |
{CKA_ID, key_id, strlen((char *) key_id)},
|
|
Packit |
8681c6 |
{CKA_PUBLIC_EXPONENT, pub_exp, sizeof(pub_exp)},
|
|
Packit |
8681c6 |
{CKA_MODULUS, NULL_PTR, 0}
|
|
Packit |
8681c6 |
};
|
|
Packit |
8681c6 |
BYTE *rgbPubBlob = NULL;
|
|
Packit |
8681c6 |
UINT32 ulBlobLen = 0;
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set up dummy session */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the public key to put into the PKCS#11 public key object */
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
|
|
Packit |
8681c6 |
&ulBlobLen, &rgbPubBlob);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hKey);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pub_tmpl[4].pValue = rgbPubBlob;
|
|
Packit |
8681c6 |
pub_tmpl[4].ulValueLen = ulBlobLen;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create skeleton for the private key object */
|
|
Packit |
8681c6 |
rc = object_create_skel(tokdata, pub_tmpl, 5, MODE_CREATE,
|
|
Packit |
8681c6 |
CKO_PUBLIC_KEY, CKK_RSA, &pub_key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_create_skel: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hKey);
|
|
Packit |
8681c6 |
free(key_id);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbPubBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* make the object reside on the token, as if that were possible */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_TOKEN, &flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build attribute failed.\n");
|
|
Packit |
8681c6 |
object_free(pub_key_obj);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(pub_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set the object to be hidden */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_HIDDEN, &flag, sizeof(CK_BBOOL), &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build attribute failed.\n");
|
|
Packit |
8681c6 |
object_free(pub_key_obj);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(pub_key_obj->template, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_create_final(tokdata, &dummy_sess, pub_key_obj, ckKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_create_final failed\n");
|
|
Packit |
8681c6 |
object_free(pub_key_obj);
|
|
Packit |
8681c6 |
pub_key_obj = NULL;
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_update_private_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
|
|
Packit |
8681c6 |
int key_type)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE ckHandle;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set up dummy session */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find the private key portion of the key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, key_type, CKO_PRIVATE_KEY, &ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* destroy the private key and create a new one */
|
|
Packit |
8681c6 |
rc = object_mgr_destroy_object(tokdata, &dummy_sess, ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_store_priv_key(tokdata, hKey, key_type, &ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_priv_key failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_store_tss_key(STDLL_TokData_t * tokdata, TSS_HKEY hKey,
|
|
Packit |
8681c6 |
int key_type, CK_OBJECT_HANDLE * ckKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create a PKCS#11 pub key object for the key */
|
|
Packit |
8681c6 |
rc = token_store_pub_key(tokdata, hKey, key_type, ckKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_pub_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create a PKCS#11 private key object for the key */
|
|
Packit |
8681c6 |
rc = token_store_priv_key(tokdata, hKey, key_type, ckKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_priv_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_generate_leaf_key(STDLL_TokData_t * tokdata, int key_type,
|
|
Packit |
8681c6 |
CK_CHAR_PTR passHash, TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *ckKey;
|
|
Packit |
8681c6 |
TSS_FLAG initFlags = TSS_KEY_MIGRATABLE | TSS_KEY_TYPE_BIND |
|
|
Packit |
8681c6 |
TSS_KEY_SIZE_2048 | TSS_KEY_AUTHORIZATION;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
switch (key_type) {
|
|
Packit |
8681c6 |
case TPMTOK_PUBLIC_LEAF_KEY:
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicRootKey;
|
|
Packit |
8681c6 |
ckKey = &tpm_data->ckPublicRootKey;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case TPMTOK_PRIVATE_LEAF_KEY:
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPrivateRootKey;
|
|
Packit |
8681c6 |
ckKey = &tpm_data->ckPrivateRootKey;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
TRACE_ERROR("Unknown key type.\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = tss_generate_key(tokdata, initFlags, passHash, hParentKey, phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("tss_generate_key returned 0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_store_tss_key(tokdata, *phKey, key_type, ckKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_tss_key failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_verify_pin(STDLL_TokData_t * tokdata, TSS_HKEY hKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
UINT32 ulUnboundDataLen;
|
|
Packit |
8681c6 |
BYTE *rgbUnboundData;
|
|
Packit |
8681c6 |
char *rgbData = "CRAPPENFEST";
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
CK_RV rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Data_Bind(hEncData, hKey, strlen(rgbData), (BYTE *) rgbData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Bind returned 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* unbind the junk data to test the key's auth data */
|
|
Packit |
8681c6 |
result =
|
|
Packit |
8681c6 |
Tspi_Data_Unbind(hEncData, hKey, &ulUnboundDataLen, &rgbUnboundData);
|
|
Packit |
8681c6 |
if (result == TCPA_E_AUTHFAIL) {
|
|
Packit |
8681c6 |
rc = CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Unbind returned TCPA_AUTHFAIL\n");
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
} else if (result != TSS_SUCCESS) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_ Unbind returned 0x%x\n", result);
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = memcmp(rgbUnboundData, rgbData, ulUnboundDataLen);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbUnboundData);
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, hEncData);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_create_private_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash,
|
|
Packit |
8681c6 |
CK_BYTE * pPin)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
RSA *rsa;
|
|
Packit |
8681c6 |
unsigned int size_n, size_p;
|
|
Packit |
8681c6 |
unsigned char n[256], p[256];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* all sw generated keys are 2048 bits */
|
|
Packit Service |
8aa27d |
if ((rsa = openssl_gen_key(tokdata)) == NULL)
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* generate the software based user base key */
|
|
Packit |
8681c6 |
rc = token_wrap_sw_key(tokdata, size_n, n, size_p, p, tpm_data->hSRK,
|
|
Packit |
8681c6 |
TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE,
|
|
Packit |
8681c6 |
&tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lu\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (openssl_write_key(tokdata, rsa, TPMTOK_PRIV_ROOT_KEY_FILE, pPin)) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_write_key failed.\n");
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* store the user base key in a PKCS#11 object internally */
|
|
Packit |
8681c6 |
rc = token_store_tss_key(tokdata, tpm_data->hPrivateRootKey,
|
|
Packit |
8681c6 |
TPMTOK_PRIVATE_ROOT_KEY,
|
|
Packit |
8681c6 |
&tpm_data->ckPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_tss_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_LoadKey(tpm_data->hPrivateRootKey, tpm_data->hSRK);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* generate the private leaf key */
|
|
Packit |
8681c6 |
rc = token_generate_leaf_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
|
|
Packit |
8681c6 |
pinHash, &tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_generate_leaf_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_LoadKey(tpm_data->hPrivateLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_create_public_tree(STDLL_TokData_t * tokdata, CK_BYTE * pinHash,
|
|
Packit |
8681c6 |
CK_BYTE * pPin)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
RSA *rsa;
|
|
Packit |
8681c6 |
unsigned int size_n, size_p;
|
|
Packit |
8681c6 |
unsigned char n[256], p[256];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* all sw generated keys are 2048 bits */
|
|
Packit Service |
8aa27d |
if ((rsa = openssl_gen_key(tokdata)) == NULL)
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create the public root key */
|
|
Packit |
8681c6 |
rc = token_wrap_sw_key(tokdata, size_n, n, size_p, p, tpm_data->hSRK,
|
|
Packit |
8681c6 |
TSS_KEY_NO_AUTHORIZATION | TSS_KEY_TYPE_STORAGE,
|
|
Packit |
8681c6 |
&tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (openssl_write_key(tokdata, rsa, TPMTOK_PUB_ROOT_KEY_FILE, pPin)) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_write_key\n");
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_LoadKey(tpm_data->hPublicRootKey, tpm_data->hSRK);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_store_tss_key(tokdata, tpm_data->hPublicRootKey,
|
|
Packit |
8681c6 |
TPMTOK_PUBLIC_ROOT_KEY, &tpm_data->ckPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_tss_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create the SO's leaf key */
|
|
Packit |
8681c6 |
rc = token_generate_leaf_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
|
|
Packit |
8681c6 |
pinHash, &tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_generate_leaf_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_LoadKey(tpm_data->hPublicLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey = NULL_HKEY;
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
tpm_data->hPublicLeafKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_migrate(STDLL_TokData_t * tokdata, int key_type, CK_BYTE * pin)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
RSA *rsa;
|
|
Packit |
8681c6 |
char *backup_loc;
|
|
Packit |
8681c6 |
unsigned int size_n, size_p;
|
|
Packit |
8681c6 |
unsigned char n[256], p[256];
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HKEY *phKey;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE *ckHandle;
|
|
Packit |
8681c6 |
SESSION dummy_sess;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* set up dummy session */
|
|
Packit |
8681c6 |
memset(&dummy_sess, 0, sizeof(SESSION));
|
|
Packit |
8681c6 |
dummy_sess.session_info.state = CKS_RW_USER_FUNCTIONS;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (key_type == TPMTOK_PUBLIC_ROOT_KEY) {
|
|
Packit |
8681c6 |
backup_loc = TPMTOK_PUB_ROOT_KEY_FILE;
|
|
Packit |
8681c6 |
phKey = &tpm_data->hPublicRootKey;
|
|
Packit |
8681c6 |
ckHandle = &tpm_data->ckPublicRootKey;
|
|
Packit |
8681c6 |
} else if (key_type == TPMTOK_PRIVATE_ROOT_KEY) {
|
|
Packit |
8681c6 |
backup_loc = TPMTOK_PRIV_ROOT_KEY_FILE;
|
|
Packit |
8681c6 |
phKey = &tpm_data->hPrivateRootKey;
|
|
Packit |
8681c6 |
ckHandle = &tpm_data->ckPrivateRootKey;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid key type.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* read the backup key with the old pin */
|
|
Packit |
8681c6 |
if ((rc = openssl_read_key(tokdata, backup_loc, pin, &rsa))) {
|
|
Packit |
8681c6 |
if (rc == CKR_FILE_NOT_FOUND)
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_read_key failed\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* So, reading the backup openssl key off disk succeeded with the SOs PIN.
|
|
Packit |
8681c6 |
* We will now try to re-wrap that key with the current SRK
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
if (openssl_get_modulus_and_prime(rsa, &size_n, n, &size_p, p) != 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_get_modulus_and_prime failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_wrap_sw_key(tokdata, size_n, n, size_p, p, tpm_data->hSRK,
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_STORAGE | TSS_KEY_NO_AUTHORIZATION,
|
|
Packit |
8681c6 |
phKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_sw_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
RSA_free(rsa);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Key_LoadKey(*phKey, tpm_data->hSRK);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Key_LoadKey: 0x%x\n", result);
|
|
Packit |
8681c6 |
Tspi_Context_CloseObject(tpm_data->tspContext, *phKey);
|
|
Packit |
8681c6 |
*phKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Loading succeeded, so we need to get rid of the old PKCS#11 objects
|
|
Packit |
8681c6 |
* and store them anew.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, key_type, CKO_PUBLIC_KEY, ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_destroy_object(tokdata, &dummy_sess, *ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, key_type, CKO_PRIVATE_KEY, ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_destroy_object(tokdata, &dummy_sess, *ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_destroy_object failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_store_tss_key(tokdata, *phKey, key_type, ckHandle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_store_tss_key failed: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
static CK_RV save_masterkey_private(STDLL_TokData_t * tokdata, char *fname)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
struct stat file_stat;
|
|
Packit |
8681c6 |
int err;
|
|
Packit |
8681c6 |
FILE *fp = NULL;
|
|
Packit |
8681c6 |
struct passwd *pw = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
BYTE *encrypted_masterkey;
|
|
Packit |
8681c6 |
UINT32 encrypted_masterkey_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pw = getpwuid(getuid());
|
|
Packit |
8681c6 |
if (pw == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* if file exists, assume its been written correctly before */
|
|
Packit |
8681c6 |
err = stat(fname, &file_stat);
|
|
Packit |
8681c6 |
if (err == 0) {
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
} else if (errno != ENOENT) {
|
|
Packit |
8681c6 |
/* some error other than file doesn't exist */
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* encrypt the private masterkey using the private leaf key */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Data_Bind(hEncData, tpm_data->hPrivateLeafKey,
|
|
Packit |
8681c6 |
MK_SIZE, tpm_data->master_key_private);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
Packit |
8681c6 |
&encrypted_masterkey_size,
|
|
Packit |
8681c6 |
&encrypted_masterkey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (encrypted_masterkey_size > 256) {
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, encrypted_masterkey);
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* write the encrypted key to disk */
|
|
Packit |
8681c6 |
if ((fp = fopen(fname, "w")) == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Error opening %s for write: %s\n", fname, strerror(errno));
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, encrypted_masterkey);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
err = fwrite(encrypted_masterkey, encrypted_masterkey_size, 1, fp);
|
|
Packit |
8681c6 |
if (err == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Error writing %s: %s\n", fname, strerror(errno));
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, encrypted_masterkey);
|
|
Packit |
8681c6 |
fclose(fp);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, encrypted_masterkey);
|
|
Packit |
8681c6 |
fclose(fp);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV load_masterkey_private(STDLL_TokData_t * tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
FILE *fp = NULL;
|
|
Packit |
8681c6 |
int err;
|
|
Packit |
8681c6 |
struct stat file_stat;
|
|
Packit |
8681c6 |
CK_BYTE encrypted_masterkey[256];
|
|
Packit |
8681c6 |
char fname[PATH_MAX];
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
struct passwd *pw = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
BYTE *masterkey;
|
|
Packit |
8681c6 |
UINT32 masterkey_size, encrypted_masterkey_size = 256;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pw = getpwuid(getuid());
|
|
Packit |
8681c6 |
if (pw == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
if (ock_snprintf(fname, PATH_MAX, "%s/%s/%s", tokdata->pk_dir, pw->pw_name,
|
|
Packit Service |
8aa27d |
TPMTOK_MASTERKEY_PRIVATE) != 0) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("tpm token master key private file buffer overflow\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* if file exists, check its size */
|
|
Packit |
8681c6 |
err = stat(fname, &file_stat);
|
|
Packit |
8681c6 |
if (err == 0) {
|
|
Packit |
8681c6 |
if (file_stat.st_size != 256) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Private master key has been corrupted\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else if (errno == ENOENT) {
|
|
Packit |
8681c6 |
TRACE_INFO("Private master key doesn't exist, creating it...\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create the private master key, then save */
|
|
Packit |
8681c6 |
rc = token_specific_rng(tokdata, tpm_data->master_key_private, MK_SIZE);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rng failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
return save_masterkey_private(tokdata, fname);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
/* some error other than file doesn't exist */
|
|
Packit |
8681c6 |
TRACE_ERROR("stat of private masterkey failed: %s\n", strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//fp = fopen("/etc/pkcs11/tpm/MK_PUBLIC", "r");
|
|
Packit |
8681c6 |
if ((fp = fopen(fname, "r")) == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Error opening %s: %s\n", fname, strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (fread(encrypted_masterkey, encrypted_masterkey_size, 1, fp) == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Error reading %s: %s\n", fname, strerror(errno));
|
|
Packit |
8681c6 |
fclose(fp);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
fclose(fp);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* decrypt the private masterkey using the private leaf key */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
Packit |
8681c6 |
encrypted_masterkey_size,
|
|
Packit |
8681c6 |
encrypted_masterkey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Data_Unbind(hEncData, tpm_data->hPrivateLeafKey,
|
|
Packit |
8681c6 |
&masterkey_size, &masterkey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Unbind failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (masterkey_size != MK_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("decrypted private master key size is %u, "
|
|
Packit |
8681c6 |
"should be %u\n", masterkey_size, MK_SIZE);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, masterkey);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(tpm_data->master_key_private, masterkey, MK_SIZE);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, masterkey);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_login(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
Packit |
8681c6 |
CK_USER_TYPE userType, CK_CHAR_PTR pPin,
|
|
Packit |
8681c6 |
CK_ULONG ulPinLen)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_BYTE hash_sha[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(sess);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_load_srk(tokdata);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (userType == CKU_USER) {
|
|
Packit |
8681c6 |
/* If the public root key doesn't exist yet, the SO hasn't init'd the
|
|
Packit |
8681c6 |
* token */
|
|
Packit |
8681c6 |
result = token_load_public_root_key(tokdata);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_public_root_key failed. "
|
|
Packit |
8681c6 |
"rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_USER_PIN_NOT_INITIALIZED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the private root key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PRIVATE_ROOT_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
/* user's key chain not found, this must be the initial login */
|
|
Packit |
8681c6 |
if (memcmp(hash_sha, default_user_pin_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed and PIN != default\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tpm_data->not_initialized = 1;
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPrivateRootKey,
|
|
Packit |
8681c6 |
tpm_data->hSRK, NULL, &tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Here, we've found the private root key, but its load failed.
|
|
Packit |
8681c6 |
* This should only happen in a migration path, where we have
|
|
Packit |
8681c6 |
* the PKCS#11 key store available, but the SRK is now
|
|
Packit |
8681c6 |
* different. So, we will try to decrypt the PEM backup file
|
|
Packit |
8681c6 |
* for the private root key using the given password. If that
|
|
Packit |
8681c6 |
* succeeds, we will assume that we're in a migration path and
|
|
Packit |
8681c6 |
* re-wrap the private root key to the new SRK.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
if ((token_migrate(tokdata, TPMTOK_PRIVATE_ROOT_KEY, pPin))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_migrate. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* At this point, the public root key has been successfully read
|
|
Packit |
8681c6 |
* from backup, re-wrapped to the new SRK, loaded and the PKCS#11
|
|
Packit |
8681c6 |
* objects have been updated. Proceed with login as normal.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the user leaf key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPrivateLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey,
|
|
Packit |
8681c6 |
hash_sha, &tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_verify_pin(tokdata, tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_verify_pin failed. failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(tpm_data->current_user_pin_sha, hash_sha, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* load private data encryption key here */
|
|
Packit |
8681c6 |
rc = load_masterkey_private(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("load_masterkey_private failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
Tspi_Key_UnloadKey(tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
tpm_data->hPrivateLeafKey = NULL_HKEY;
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = XProcLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to get process lock.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = load_private_token_objects(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->global_shm->priv_loaded = TRUE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Failed to release process lock.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
/* SO path --
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
/* find, load the root key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
/* The SO hasn't set her PIN yet, compare the login pin with
|
|
Packit |
8681c6 |
* the hard-coded value */
|
|
Packit |
8681c6 |
if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed and PIN != default\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tpm_data->not_initialized = 1;
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* The SO's key hierarchy has previously been created, so load the key
|
|
Packit |
8681c6 |
* hierarchy and verify the pin using the TPM. */
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPublicRootKey,
|
|
Packit |
8681c6 |
tpm_data->hSRK, NULL, &tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Here, we've found the public root key, but its load failed.
|
|
Packit |
8681c6 |
* This should only happen in a migration path, where we have
|
|
Packit |
8681c6 |
* the PKCS#11 key store available, but the SRK is now
|
|
Packit |
8681c6 |
* different. So, we will try to decrypt the PEM backup file
|
|
Packit |
8681c6 |
* for the public root key using the given password. If that
|
|
Packit |
8681c6 |
* succeeds, we will assume that we're in a migration path and
|
|
Packit |
8681c6 |
* re-wrap the public root key to the new SRK.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
if ((token_migrate(tokdata, TPMTOK_PUBLIC_ROOT_KEY, pPin))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_migrate. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* At this point, the public root key has been successfully read
|
|
Packit |
8681c6 |
* from backup, re-wrapped to the new SRK, loaded and the PKCS#11
|
|
Packit |
8681c6 |
* objects have been updated. Proceed with login as normal.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the public leaf key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPublicLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey, hash_sha,
|
|
Packit |
8681c6 |
&tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_verify_pin(tokdata, tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_verify_pin failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(tpm_data->current_so_pin_sha, hash_sha, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_logout(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tpm_data->hPrivateLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
Tspi_Key_UnloadKey(tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
} else if (tpm_data->hPublicLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
Tspi_Key_UnloadKey(tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
clear_internal_structures(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_init_pin(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
Packit |
8681c6 |
CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
UNUSED(sess);
|
|
Packit |
8681c6 |
UNUSED(pPin);
|
|
Packit |
8681c6 |
UNUSED(ulPinLen);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Since the SO must log in before calling C_InitPIN, we will
|
|
Packit |
8681c6 |
* be able to return CKR_OK automatically here.
|
|
Packit |
8681c6 |
* This is because the USER key structure is created at the
|
|
Packit |
8681c6 |
* time of her first login, not at C_InitPIN time.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV check_pin_properties(CK_USER_TYPE userType, CK_BYTE * pinHash,
|
|
Packit |
8681c6 |
CK_ULONG ulPinLen)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
/* make sure the new PIN is different */
|
|
Packit |
8681c6 |
if (userType == CKU_USER) {
|
|
Packit |
8681c6 |
if (!memcmp(pinHash, default_user_pin_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("new PIN must not be the default\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
if (!memcmp(pinHash, default_so_pin_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("new PIN must not be the default\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (ulPinLen > MAX_PIN_LEN || ulPinLen < MIN_PIN_LEN) {
|
|
Packit |
8681c6 |
TRACE_ERROR("New PIN is out of size range\n");
|
|
Packit |
8681c6 |
return CKR_PIN_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* use this function call from set_pin only, where a not logged in public
|
|
Packit |
8681c6 |
* session can provide the user pin which must be verified. This function
|
|
Packit |
8681c6 |
* assumes that the pin has already been set once, so there's no migration
|
|
Packit |
8681c6 |
* path option or checking of the default user pin.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
CK_RV verify_user_pin(STDLL_TokData_t * tokdata, CK_BYTE * hash_sha)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the private root key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PRIVATE_ROOT_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPrivateRootKey,
|
|
Packit |
8681c6 |
tpm_data->hSRK, NULL, &tpm_data->hPrivateRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the user leaf key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PRIVATE_LEAF_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPrivateLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey, hash_sha,
|
|
Packit |
8681c6 |
&tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_verify_pin(tokdata, tpm_data->hPrivateLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_verify_pin failed. failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_set_pin(STDLL_TokData_t * tokdata, SESSION * sess,
|
|
Packit |
8681c6 |
CK_CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
|
|
Packit |
8681c6 |
CK_CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_BYTE oldpin_hash[SHA1_HASH_SIZE], newpin_hash[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
RSA *rsa_root;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!sess) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_SESSION_HANDLE_INVALID));
|
|
Packit |
8681c6 |
return CKR_SESSION_HANDLE_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = compute_sha1(tokdata, pOldPin, ulOldPinLen, oldpin_hash);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = compute_sha1(tokdata, pNewPin, ulNewPinLen, newpin_hash);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_load_srk(tokdata);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_srk failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* From the PKCS#11 2.20 spec: "C_SetPIN modifies the PIN of the user that
|
|
Packit |
8681c6 |
* is currently logged in, or the CKU_USER PIN if the session is not logged
|
|
Packit |
8681c6 |
* in."
|
|
Packit |
8681c6 |
* A non R/W session fails with CKR_SESSION_READ_ONLY.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
if (sess->session_info.state == CKS_RW_USER_FUNCTIONS ||
|
|
Packit |
8681c6 |
sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
|
|
Packit |
8681c6 |
if (tpm_data->not_initialized) {
|
|
Packit |
8681c6 |
if (memcmp(oldpin_hash, default_user_pin_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("old PIN != default for an "
|
|
Packit |
8681c6 |
"uninitialized user\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_create_private_tree(tokdata, newpin_hash, pNewPin);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("FAILED creating USER tree.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->nv_token_data->token_info.flags &=
|
|
Packit |
8681c6 |
~(CKF_USER_PIN_TO_BE_CHANGED);
|
|
Packit |
8681c6 |
tokdata->nv_token_data->token_info.flags |=
|
|
Packit |
8681c6 |
CKF_USER_PIN_INITIALIZED;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return save_token_data(tokdata, sess->session_info.slotID);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (sess->session_info.state == CKS_RW_USER_FUNCTIONS) {
|
|
Packit |
8681c6 |
/* if we're already logged in, just verify the hash */
|
|
Packit |
8681c6 |
if (memcmp(tpm_data->current_user_pin_sha, oldpin_hash,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("USER pin incorrect\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
rc = verify_user_pin(tokdata, oldpin_hash);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = check_pin_properties(CKU_USER, newpin_hash, ulNewPinLen);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* change the auth on the TSS object */
|
|
Packit |
8681c6 |
result = tss_change_auth(tokdata, tpm_data->hPrivateLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPrivateRootKey, newpin_hash);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("tss_change_auth failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* destroy the old PKCS#11 priv key object and create a new one */
|
|
Packit |
8681c6 |
rc = token_update_private_key(tokdata, tpm_data->hPrivateLeafKey,
|
|
Packit |
8681c6 |
TPMTOK_PRIVATE_LEAF_KEY);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_update_private_key failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* read the backup key with the old pin */
|
|
Packit |
8681c6 |
rc = openssl_read_key(tokdata, TPMTOK_PRIV_ROOT_KEY_FILE, pOldPin,
|
|
Packit |
8681c6 |
&rsa_root);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
if (rc == CKR_FILE_NOT_FOUND) {
|
|
Packit |
8681c6 |
/* If the user has moved his backup PEM file off site, allow a
|
|
Packit |
8681c6 |
* change auth to succeed without updating it. */
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_read_key failed\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* write it out using the new pin */
|
|
Packit |
8681c6 |
rc = openssl_write_key(tokdata, rsa_root, TPMTOK_PRIV_ROOT_KEY_FILE,
|
|
Packit |
8681c6 |
pNewPin);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
RSA_free(rsa_root);
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_write_key failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
RSA_free(rsa_root);
|
|
Packit |
8681c6 |
} else if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
|
|
Packit |
8681c6 |
if (tpm_data->not_initialized) {
|
|
Packit |
8681c6 |
if (memcmp(default_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("old PIN != default for an " "uninitialized SO\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_create_public_tree(tokdata, newpin_hash, pNewPin);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("FAILED creating SO tree.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->nv_token_data->token_info.flags &=
|
|
Packit |
8681c6 |
~(CKF_SO_PIN_TO_BE_CHANGED);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return save_token_data(tokdata, sess->session_info.slotID);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (memcmp(tpm_data->current_so_pin_sha, oldpin_hash, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("SO PIN incorrect\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = check_pin_properties(CKU_SO, newpin_hash, ulNewPinLen);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* change auth on the SO's leaf key */
|
|
Packit |
8681c6 |
result = tss_change_auth(tokdata, tpm_data->hPublicLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey, newpin_hash);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("tss_change_auth failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_update_private_key(tokdata, tpm_data->hPublicLeafKey,
|
|
Packit |
8681c6 |
TPMTOK_PUBLIC_LEAF_KEY);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_update_private_key failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* change auth on the public root key's openssl backup */
|
|
Packit |
8681c6 |
rc = openssl_read_key(tokdata, TPMTOK_PUB_ROOT_KEY_FILE, pOldPin,
|
|
Packit |
8681c6 |
&rsa_root);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
if (rc == CKR_FILE_NOT_FOUND) {
|
|
Packit |
8681c6 |
/* If the user has moved his backup PEM file off site, allow a
|
|
Packit |
8681c6 |
* change auth to succeed without updating it. */
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_read_key failed\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* write it out using the new pin */
|
|
Packit |
8681c6 |
rc = openssl_write_key(tokdata, rsa_root, TPMTOK_PUB_ROOT_KEY_FILE,
|
|
Packit |
8681c6 |
pNewPin);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
RSA_free(rsa_root);
|
|
Packit |
8681c6 |
TRACE_DEVEL("openssl_write_key failed\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
RSA_free(rsa_root);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_SESSION_READ_ONLY));
|
|
Packit |
8681c6 |
rc = CKR_SESSION_READ_ONLY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
static CK_RV delete_tpm_data(STDLL_TokData_t * tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
char *cmd = NULL;
|
|
Packit |
8681c6 |
struct passwd *pw = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pw = getpwuid(getuid());
|
|
Packit |
8681c6 |
if (pw == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("getpwuid failed: %s\n", strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// delete the TOK_OBJ data files
|
|
Packit |
8681c6 |
if (asprintf(&cmd, "%s %s/%s/%s/* > /dev/null 2>&1", DEL_CMD,
|
|
Packit |
8681c6 |
tokdata->pk_dir, pw->pw_name, PK_LITE_OBJ_DIR) < 0) {
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (system(cmd) == -1)
|
|
Packit |
8681c6 |
TRACE_ERROR("system() failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(cmd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// delete the OpenSSL backup keys
|
|
Packit |
8681c6 |
if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
|
|
Packit |
8681c6 |
tokdata->pk_dir, pw->pw_name, TPMTOK_PUB_ROOT_KEY_FILE) < 0) {
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (system(cmd) == -1)
|
|
Packit |
8681c6 |
TRACE_ERROR("system() failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(cmd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
|
|
Packit |
8681c6 |
tokdata->pk_dir, pw->pw_name, TPMTOK_PRIV_ROOT_KEY_FILE) < 0) {
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (system(cmd) == -1)
|
|
Packit |
8681c6 |
TRACE_ERROR("system() failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(cmd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// delete the masterkey
|
|
Packit |
8681c6 |
if (asprintf(&cmd, "%s %s/%s/%s > /dev/null 2>&1", DEL_CMD,
|
|
Packit |
8681c6 |
tokdata->pk_dir, pw->pw_name, TPMTOK_MASTERKEY_PRIVATE) < 0) {
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (system(cmd) == -1)
|
|
Packit |
8681c6 |
TRACE_ERROR("system() failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(cmd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* only called at token init time */
|
|
Packit |
8681c6 |
CK_RV token_specific_init_token(STDLL_TokData_t * tokdata, CK_SLOT_ID sid,
|
|
Packit |
8681c6 |
CK_CHAR_PTR pPin, CK_ULONG ulPinLen,
|
|
Packit |
8681c6 |
CK_CHAR_PTR pLabel)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_BYTE hash_sha[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = compute_sha1(tokdata, pPin, ulPinLen, hash_sha);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("compute_sha1 failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the migratable root key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PUBLIC_ROOT_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
/* The SO hasn't set her PIN yet, compare the login pin with
|
|
Packit |
8681c6 |
* the hard-coded value */
|
|
Packit |
8681c6 |
if (memcmp(default_so_pin_sha, hash_sha, SHA1_HASH_SIZE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed and PIN != default\n");
|
|
Packit |
8681c6 |
return CKR_PIN_INCORRECT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
goto done;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_srk(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_srk failed. rc = 0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* we found the root key, so check by loading the chain */
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPublicRootKey,
|
|
Packit |
8681c6 |
tpm_data->hSRK, NULL, &tpm_data->hPublicRootKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* find, load the public leaf key */
|
|
Packit |
8681c6 |
rc = token_find_key(tokdata, TPMTOK_PUBLIC_LEAF_KEY,
|
|
Packit |
8681c6 |
CKO_PRIVATE_KEY, &tpm_data->ckPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("token_find_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, tpm_data->ckPublicLeafKey,
|
|
Packit |
8681c6 |
tpm_data->hPublicRootKey, hash_sha,
|
|
Packit |
8681c6 |
&tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key(MigLeafKey) Failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_verify_pin(tokdata, tpm_data->hPublicLeafKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_verify_pin failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
done:
|
|
Packit |
8681c6 |
// Before we reconstruct all the data, we should delete the
|
|
Packit |
8681c6 |
// token objects from the filesystem.
|
|
Packit |
8681c6 |
object_mgr_destroy_token_objects(tokdata);
|
|
Packit |
8681c6 |
rc = delete_tpm_data(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// META This should be fine since the open session checking should occur at
|
|
Packit |
8681c6 |
// the API not the STDLL
|
|
Packit |
8681c6 |
load_token_data(tokdata, sid);
|
|
Packit |
8681c6 |
init_slotInfo(&tokdata->slot_info);
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->so_pin_sha, hash_sha, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
tokdata->nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED;
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->token_info.label, pLabel, 32);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// New for v2.11 - KEY
|
|
Packit |
8681c6 |
tokdata->nv_token_data->token_info.flags |= CKF_TOKEN_INITIALIZED;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = save_token_data(tokdata, sid);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("save_token_data failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_final(STDLL_TokData_t *tokdata,
|
|
Packit |
8681c6 |
CK_BBOOL in_fork_initializer)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TRACE_INFO("tpm %s running\n", __func__);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Only close the context if not in in_fork_initializer. If we close the
|
|
Packit |
8681c6 |
* context in a forked child process, this also closes the parent's context.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
if (!in_fork_initializer) {
|
|
Packit |
8681c6 |
result = Tspi_Context_Close(tpm_data->tspContext);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_Close failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
clear_internal_structures(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(tpm_data);
|
|
Packit |
8681c6 |
tokdata->private_data = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
CK_RV token_specific_des_key_gen(STDLL_TokData_t *tokdata, CK_BYTE **des_key,
|
|
Packit Service |
8aa27d |
CK_ULONG *len, CK_ULONG keysize,
|
|
Packit Service |
8aa27d |
CK_BBOOL *is_opaque)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
*des_key = malloc(keysize);
|
|
Packit Service |
8aa27d |
if (*des_key == NULL)
|
|
Packit Service |
8aa27d |
return CKR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
*len = keysize;
|
|
Packit Service |
8aa27d |
*is_opaque = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Nothing different to do for DES or TDES here as this is just
|
|
Packit |
8681c6 |
// random data... Validation handles the rest
|
|
Packit |
8681c6 |
// Only check for weak keys when DES.
|
|
Packit Service |
8aa27d |
if (keysize == (3 * DES_KEY_SIZE)) {
|
|
Packit Service |
8aa27d |
rng_generate(tokdata, *des_key, keysize);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
do {
|
|
Packit Service |
8aa27d |
rng_generate(tokdata, *des_key, keysize);
|
|
Packit Service |
8aa27d |
} while (des_check_weak_key(*des_key) == TRUE);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// we really need to validate the key for parity etc...
|
|
Packit |
8681c6 |
// we should do that here... The caller validates the single des keys
|
|
Packit |
8681c6 |
// against the known and suspected poor keys..
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_des_ecb(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
CK_ULONG rc;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
DES_key_schedule des_key2;
|
|
Packit |
8681c6 |
const_DES_cblock key_val_SSL, in_key_data;
|
|
Packit |
8681c6 |
DES_cblock out_key_data;
|
|
Packit |
8681c6 |
unsigned int i, j;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Create the key schedule
|
|
Packit |
8681c6 |
memcpy(&key_val_SSL, attr->pValue, 8);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_val_SSL, &des_key2);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// the des decrypt will only fail if the data length is not evenly divisible
|
|
Packit |
8681c6 |
// by 8
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Both the encrypt and the decrypt are done 8 bytes at a time
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
for (i = 0; i < in_data_len; i = i + 8) {
|
|
Packit |
8681c6 |
memcpy(in_key_data, in_data + i, 8);
|
|
Packit |
8681c6 |
DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
|
|
Packit |
8681c6 |
DES_ENCRYPT);
|
|
Packit |
8681c6 |
memcpy(out_data + i, out_key_data, 8);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (j = 0; j < in_data_len; j = j + 8) {
|
|
Packit |
8681c6 |
memcpy(in_key_data, in_data + j, 8);
|
|
Packit |
8681c6 |
DES_ecb_encrypt(&in_key_data, &out_key_data, &des_key2,
|
|
Packit |
8681c6 |
DES_DECRYPT);
|
|
Packit |
8681c6 |
memcpy(out_data + j, out_key_data, 8);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = EVP_des_ecb();
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
unsigned char dkey[8];
|
|
Packit Service |
8aa27d |
CK_ULONG rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, sizeof(dkey));
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
return CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, dkey, NULL, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_des_cbc(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
CK_ULONG rc;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
DES_cblock ivec;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
DES_key_schedule des_key2;
|
|
Packit |
8681c6 |
const_DES_cblock key_val_SSL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Create the key schedule
|
|
Packit |
8681c6 |
memcpy(&key_val_SSL, attr->pValue, 8);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_val_SSL, &des_key2);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(&ivec, init_v, 8);
|
|
Packit |
8681c6 |
// the des decrypt will only fail if the data length is not evenly divisible
|
|
Packit |
8681c6 |
// by 8
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
|
|
Packit |
8681c6 |
DES_ENCRYPT);
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
DES_ncbc_encrypt(in_data, out_data, in_data_len, &des_key2, &ivec,
|
|
Packit |
8681c6 |
DES_DECRYPT);
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return rc;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = EVP_des_cbc();
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
unsigned char dkey[DES_KEY_SIZE];
|
|
Packit Service |
8aa27d |
CK_ULONG rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
return CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, sizeof(dkey));
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, dkey, init_v, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_tdes_ecb(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_KEY_TYPE keytype;
|
|
Packit |
8681c6 |
CK_BYTE key_value[3 * DES_KEY_SIZE];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
unsigned int k, j;
|
|
Packit |
8681c6 |
DES_key_schedule des_key1;
|
|
Packit |
8681c6 |
DES_key_schedule des_key2;
|
|
Packit |
8681c6 |
DES_key_schedule des_key3;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
const_DES_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data;
|
|
Packit |
8681c6 |
DES_cblock out_key_data;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key type
|
|
Packit |
8681c6 |
rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (keytype == CKK_DES2) {
|
|
Packit |
8681c6 |
memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
|
|
Packit |
8681c6 |
memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// The key as passed is a 24 byte long string containing three des keys
|
|
Packit |
8681c6 |
// pick them apart and create the 3 corresponding key schedules
|
|
Packit |
8681c6 |
memcpy(&key_SSL1, key_value, 8);
|
|
Packit |
8681c6 |
memcpy(&key_SSL2, key_value + 8, 8);
|
|
Packit |
8681c6 |
memcpy(&key_SSL3, key_value + 16, 8);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL1, &des_key1);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL2, &des_key2);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL3, &des_key3);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// the des decrypt will only fail if the data length is not evenly divisible
|
|
Packit |
8681c6 |
// by 8
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// the encrypt and decrypt are done 8 bytes at a time
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
for (k = 0; k < in_data_len; k = k + 8) {
|
|
Packit |
8681c6 |
memcpy(in_key_data, in_data + k, 8);
|
|
Packit |
8681c6 |
DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
|
|
Packit |
8681c6 |
(DES_cblock *) & out_key_data,
|
|
Packit |
8681c6 |
&des_key1, &des_key2, &des_key3, DES_ENCRYPT);
|
|
Packit |
8681c6 |
memcpy(out_data + k, out_key_data, 8);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
for (j = 0; j < in_data_len; j = j + 8) {
|
|
Packit |
8681c6 |
memcpy(in_key_data, in_data + j, 8);
|
|
Packit |
8681c6 |
DES_ecb3_encrypt((const_DES_cblock *) & in_key_data,
|
|
Packit |
8681c6 |
(DES_cblock *) & out_key_data,
|
|
Packit |
8681c6 |
&des_key1, &des_key2, &des_key3, DES_DECRYPT);
|
|
Packit |
8681c6 |
memcpy(out_data + j, out_key_data, 8);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = EVP_des_ede3_ecb();
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
unsigned char dkey[3 * DES_KEY_SIZE];
|
|
Packit Service |
8aa27d |
CK_KEY_TYPE keytype;
|
|
Packit Service |
8aa27d |
CK_ULONG rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key type
|
|
Packit Service |
8aa27d |
rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
|
|
Packit Service |
8aa27d |
if (rc == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
return CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (keytype == CKK_DES2) {
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, 2 * DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
memcpy(dkey + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
} else {
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, 3 * DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, dkey, NULL, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_tdes_cbc(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
CK_RV rc = CKR_OK;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_KEY_TYPE keytype;
|
|
Packit |
8681c6 |
CK_BYTE key_value[3 * DES_KEY_SIZE];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
DES_key_schedule des_key1;
|
|
Packit |
8681c6 |
DES_key_schedule des_key2;
|
|
Packit |
8681c6 |
DES_key_schedule des_key3;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
const_DES_cblock key_SSL1, key_SSL2, key_SSL3;
|
|
Packit |
8681c6 |
DES_cblock ivec;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key type
|
|
Packit |
8681c6 |
rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (keytype == CKK_DES2) {
|
|
Packit |
8681c6 |
memcpy(key_value, attr->pValue, 2 * DES_KEY_SIZE);
|
|
Packit |
8681c6 |
memcpy(key_value + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
memcpy(key_value, attr->pValue, 3 * DES_KEY_SIZE);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// The key as passed in is a 24 byte string containing 3 keys
|
|
Packit |
8681c6 |
// pick it apart and create the key schedules
|
|
Packit |
8681c6 |
memcpy(&key_SSL1, key_value, 8);
|
|
Packit |
8681c6 |
memcpy(&key_SSL2, key_value + 8, 8);
|
|
Packit |
8681c6 |
memcpy(&key_SSL3, key_value + 16, 8);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL1, &des_key1);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL2, &des_key2);
|
|
Packit |
8681c6 |
DES_set_key_unchecked(&key_SSL3, &des_key3);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(ivec, init_v, sizeof(ivec));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// the des decrypt will only fail if the data length is not evenly divisible
|
|
Packit |
8681c6 |
// by 8
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Encrypt or decrypt the data
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
DES_ede3_cbc_encrypt(in_data,
|
|
Packit |
8681c6 |
out_data,
|
|
Packit |
8681c6 |
in_data_len,
|
|
Packit |
8681c6 |
&des_key1,
|
|
Packit |
8681c6 |
&des_key2, &des_key3, &ivec, DES_ENCRYPT);
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
DES_ede3_cbc_encrypt(in_data,
|
|
Packit |
8681c6 |
out_data,
|
|
Packit |
8681c6 |
in_data_len,
|
|
Packit |
8681c6 |
&des_key1,
|
|
Packit |
8681c6 |
&des_key2, &des_key3, &ivec, DES_DECRYPT);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = EVP_des_ede3_cbc();
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
unsigned char dkey[3 * DES_KEY_SIZE];
|
|
Packit Service |
8aa27d |
CK_KEY_TYPE keytype;
|
|
Packit Service |
8aa27d |
CK_ULONG rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key type
|
|
Packit Service |
8aa27d |
rc = template_attribute_find(key->template, CKA_KEY_TYPE, &attr);
|
|
Packit Service |
8aa27d |
if (rc == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_KEY_TYPE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % DES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
return CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (keytype == CKK_DES2) {
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, 2 * DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
memcpy(dkey + (2 * DES_KEY_SIZE), attr->pValue, DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
} else {
|
|
Packit Service |
8aa27d |
memcpy(dkey, attr->pValue, 3 * DES_KEY_SIZE);
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, dkey, init_v, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(dkey, sizeof(dkey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* wrap the 20 bytes of auth data @authData and store in an attribute of the two
|
|
Packit |
8681c6 |
* keys.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
CK_RV token_wrap_auth_data(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * authData, TEMPLATE * publ_tmpl,
|
|
Packit |
8681c6 |
TEMPLATE * priv_tmpl)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *new_attr;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
BYTE *blob;
|
|
Packit |
8681c6 |
UINT32 blob_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if ((tpm_data->hPrivateLeafKey == NULL_HKEY) &&
|
|
Packit |
8681c6 |
(tpm_data->hPublicLeafKey == NULL_HKEY)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Shouldn't be wrapping auth data in a " "public path!\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
} else if (tpm_data->hPublicLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicLeafKey;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPrivateLeafKey;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create the encrypted data object */
|
|
Packit |
8681c6 |
rc = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = Tspi_Data_Bind(hEncData, hParentKey, SHA1_HASH_SIZE, authData);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* pull the encrypted data out of the encrypted data object */
|
|
Packit |
8681c6 |
rc = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB, &blob_size, &blob;;
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(publ_tmpl, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_ENC_AUTHDATA, blob, blob_size, &new_attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_tmpl, new_attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_unwrap_auth_data(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * encAuthData, CK_ULONG encAuthDataLen,
|
|
Packit |
8681c6 |
TSS_HKEY hKey, BYTE ** authData)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
BYTE *buf;
|
|
Packit |
8681c6 |
UINT32 buf_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
Packit |
8681c6 |
encAuthDataLen, encAuthData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* unbind the data, receiving the plaintext back */
|
|
Packit |
8681c6 |
result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf;;
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Unbind failed: rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (buf_size != SHA1_HASH_SIZE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("auth data decrypt error.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*authData = buf;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// convert from the local PKCS11 template representation to
|
|
Packit |
8681c6 |
// the underlying requirement
|
|
Packit |
8681c6 |
// returns the pointer to the local key representation
|
|
Packit |
8681c6 |
CK_BYTE *rsa_convert_public_key(OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *modulus = NULL;
|
|
Packit |
8681c6 |
CK_BYTE *ret;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = template_attribute_find(key_obj->template, CKA_MODULUS, &modulus);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
ret = malloc(modulus->ulValueLen);
|
|
Packit |
8681c6 |
if (ret == NULL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(ret, modulus->pValue, modulus->ulValueLen);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return ret;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_generate_keypair(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
TEMPLATE * publ_tmpl,
|
|
Packit |
8681c6 |
TEMPLATE * priv_tmpl)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
CK_ULONG mod_bits = 0;
|
|
Packit |
8681c6 |
CK_BBOOL flag;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_BYTE tpm_pubexp[3] = { 1, 0, 1 }; // 65537
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
TSS_FLAG initFlags = 0;
|
|
Packit |
8681c6 |
BYTE authHash[SHA1_HASH_SIZE];
|
|
Packit |
8681c6 |
BYTE *authData = NULL;
|
|
Packit |
8681c6 |
TSS_HKEY hKey = NULL_HKEY;
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey = NULL_HKEY;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
UINT32 ulBlobLen;
|
|
Packit |
8681c6 |
BYTE *rgbBlob;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Make sure the public exponent is usable */
|
|
Packit |
8681c6 |
if ((util_check_public_exponent(publ_tmpl))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("Invalid public exponent\n");
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCONSISTENT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
flag = template_attribute_find(publ_tmpl, CKA_MODULUS_BITS, &attr);
|
|
Packit |
8681c6 |
if (!flag) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_MODULUS_BITS) failed.\n");
|
|
Packit |
8681c6 |
return CKR_TEMPLATE_INCOMPLETE; // should never happen
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
mod_bits = *(CK_ULONG *) attr->pValue;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if ((initFlags = util_get_keysize_flag(mod_bits)) == 0) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_KEY_SIZE_RANGE));
|
|
Packit |
8681c6 |
return CKR_KEY_SIZE_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* If we're not logged in, hPrivateLeafKey and hPublicLeafKey
|
|
Packit |
8681c6 |
* should be NULL */
|
|
Packit |
8681c6 |
if ((tpm_data->hPrivateLeafKey == NULL_HKEY) &&
|
|
Packit |
8681c6 |
(tpm_data->hPublicLeafKey == NULL_HKEY)) {
|
|
Packit |
8681c6 |
/* public session, wrap key with the PRK */
|
|
Packit |
8681c6 |
initFlags |=
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_LEGACY | TSS_KEY_NO_AUTHORIZATION | TSS_KEY_MIGRATABLE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if ((result = token_load_public_root_key(tokdata))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_public_root_key failed. "
|
|
Packit |
8681c6 |
"rc=%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicRootKey;
|
|
Packit |
8681c6 |
} else if (tpm_data->hPrivateLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
/* logged in USER session */
|
|
Packit |
8681c6 |
initFlags |=
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* get a random SHA1 hash for the auth data */
|
|
Packit |
8681c6 |
if ((rc = token_specific_rng(tokdata, authHash, SHA1_HASH_SIZE))) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rng failed. rc=%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
authData = authHash;
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPrivateRootKey;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
/* logged in SO session */
|
|
Packit |
8681c6 |
initFlags |=
|
|
Packit |
8681c6 |
TSS_KEY_TYPE_LEGACY | TSS_KEY_AUTHORIZATION | TSS_KEY_MIGRATABLE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* get a random SHA1 hash for the auth data */
|
|
Packit |
8681c6 |
rc = token_specific_rng(tokdata, authHash, SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rng failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
authData = authHash;
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicRootKey;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = tss_generate_key(tokdata, initFlags, authData, hParentKey, &hKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("tss_generate_key returned 0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYBLOB_BLOB,
|
|
Packit |
8681c6 |
&ulBlobLen, &rgbBlob);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute(CKA_IBM_OPAQUE) failed.\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_tmpl, attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_IBM_OPAQUE, rgbBlob, ulBlobLen, &attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute(CKA_IBM_OPAQUE) failed.\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(publ_tmpl, attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* grab the public key to put into the public key object */
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
|
|
Packit |
8681c6 |
&ulBlobLen, &rgbBlob);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetAttribData failed with rc: 0x%x\n", result);
|
|
Packit |
8681c6 |
return result;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the public key blob to the object template */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute(CKA_MODULUS) failed.\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(publ_tmpl, attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* add the public key blob to the object template */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_MODULUS, rgbBlob, ulBlobLen, &attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute(CKA_MODULUS) failed.\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_tmpl, attr);
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, rgbBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* put the public exponent into the private key object */
|
|
Packit |
8681c6 |
rc = build_attribute(CKA_PUBLIC_EXPONENT,
|
|
Packit |
8681c6 |
tpm_pubexp, sizeof(tpm_pubexp), &attr);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("build_attribute(CKA_PUBLIC_EXPONENT) failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
template_update_attribute(priv_tmpl, attr);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* wrap the authdata and put it into an object */
|
|
Packit |
8681c6 |
if (authData != NULL) {
|
|
Packit |
8681c6 |
rc = token_wrap_auth_data(tokdata, authData, publ_tmpl, priv_tmpl);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_wrap_auth_data failed with rc: 0x%lx\n", rc);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_rsa_load_key(STDLL_TokData_t * tokdata, OBJECT * key_obj,
|
|
Packit |
8681c6 |
TSS_HKEY * phKey)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HPOLICY hPolicy = NULL_HPOLICY;
|
|
Packit |
8681c6 |
TSS_HKEY hParentKey;
|
|
Packit |
8681c6 |
BYTE *authData = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
CK_OBJECT_HANDLE handle;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tpm_data->hPrivateLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPrivateRootKey;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
result = token_load_public_root_key(tokdata);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_public_root_key failed. "
|
|
Packit |
8681c6 |
"rc=%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicRootKey;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
/* if the key blob wasn't found, then try to wrap the key */
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map2(tokdata, key_obj, &handle);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* The Object holds the READ lock, but token_load_key might need the
|
|
Packit |
8681c6 |
* WRITE lock, so unlock the object
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
rc = object_unlock(key_obj);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_load_key(tokdata, handle, hParentKey, NULL, phKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
object_lock(key_obj, READ_LOCK);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Get the READ lock again */
|
|
Packit |
8681c6 |
rc = object_lock(key_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* try again to get the CKA_IBM_OPAQUE attr */
|
|
Packit |
8681c6 |
rc = template_attribute_find(key_obj->template, CKA_IBM_OPAQUE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Could not find key blob\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_LoadKeyByBlob(tpm_data->tspContext, hParentKey,
|
|
Packit |
8681c6 |
attr->ulValueLen, attr->pValue, phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_LoadKeyByBlob failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* auth data may be required */
|
|
Packit |
8681c6 |
if (template_attribute_find(key_obj->template, CKA_ENC_AUTHDATA, &attr) ==
|
|
Packit |
8681c6 |
TRUE && attr) {
|
|
Packit |
8681c6 |
if ((tpm_data->hPrivateLeafKey == NULL_HKEY) &&
|
|
Packit |
8681c6 |
(tpm_data->hPublicLeafKey == NULL_HKEY)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Shouldn't be in a public session here\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
} else if (tpm_data->hPublicLeafKey != NULL_HKEY) {
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPublicLeafKey;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
hParentKey = tpm_data->hPrivateLeafKey;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = token_unwrap_auth_data(tokdata, attr->pValue, attr->ulValueLen,
|
|
Packit |
8681c6 |
hParentKey, &authData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_unwrap_auth_data: 0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_GetPolicyObject(*phKey, TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_GetPolicyObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* If the policy handle returned is the same as the context's default
|
|
Packit |
8681c6 |
* policy, then a new policy must be created and assigned to the key.
|
|
Packit |
8681c6 |
* Otherwise, just set the secret in the policy */
|
|
Packit |
8681c6 |
if (hPolicy == tpm_data->hDefaultPolicy) {
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_POLICY,
|
|
Packit |
8681c6 |
TSS_POLICY_USAGE, &hPolicy);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject: 0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE, authData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. "
|
|
Packit |
8681c6 |
"rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Policy_AssignToObject(hPolicy, *phKey);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_AssignToObject failed."
|
|
Packit |
8681c6 |
" rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_SHA1,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE, authData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Policy_SetSecret failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, authData);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_decrypt(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len, OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HKEY hKey;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData = NULL_HENCDATA;
|
|
Packit |
8681c6 |
UINT32 buf_size = 0;
|
|
Packit |
8681c6 |
BYTE *buf = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_rsa_load_key(tokdata, key_obj, &hKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* push the data into the encrypted data object */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_SetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
Packit |
8681c6 |
in_data_len, in_data);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* unbind the data, receiving the plaintext back */
|
|
Packit |
8681c6 |
TRACE_DEVEL("unbinding data with size: %ld\n", in_data_len);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Data_Unbind(hEncData, hKey, &buf_size, &buf;;
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Unbind failed: 0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (*out_data_len < buf_size) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, buf);
|
|
Packit |
8681c6 |
return CKR_BUFFER_TOO_SMALL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(out_data, buf, buf_size);
|
|
Packit |
8681c6 |
*out_data_len = buf_size;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, buf);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_verify(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
SESSION * sess,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * sig,
|
|
Packit |
8681c6 |
CK_ULONG sig_len, OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HHASH hHash;
|
|
Packit |
8681c6 |
TSS_HKEY hKey;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(sess);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_rsa_load_key(tokdata, key_obj, &hKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Create the hash object we'll use to sign */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_HASH,
|
|
Packit |
8681c6 |
TSS_HASH_OTHER, &hHash);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Insert the data into the hash object */
|
|
Packit |
8681c6 |
result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Hash_SetHashValue failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Verify */
|
|
Packit |
8681c6 |
result = Tspi_Hash_VerifySignature(hHash, hKey, sig_len, sig);
|
|
Packit |
8681c6 |
if (result != TSS_SUCCESS && TPMTOK_TSS_ERROR_CODE(result) != TSS_E_FAIL) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Hash_VerifySignature failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (TPMTOK_TSS_ERROR_CODE(result) == TSS_E_FAIL) {
|
|
Packit |
8681c6 |
rc = CKR_SIGNATURE_INVALID;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_sign(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
SESSION * sess,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len, OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HHASH hHash;
|
|
Packit |
8681c6 |
BYTE *sig;
|
|
Packit |
8681c6 |
UINT32 sig_len;
|
|
Packit |
8681c6 |
TSS_HKEY hKey;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(sess);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_rsa_load_key(tokdata, key_obj, &hKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Create the hash object we'll use to sign */
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_HASH,
|
|
Packit |
8681c6 |
TSS_HASH_OTHER, &hHash);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Insert the data into the hash object */
|
|
Packit |
8681c6 |
result = Tspi_Hash_SetHashValue(hHash, in_data_len, in_data);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Hash_SetHashValue failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Sign */
|
|
Packit |
8681c6 |
result = Tspi_Hash_Sign(hHash, hKey, &sig_len, &sig);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Hash_Sign failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (sig_len > *out_data_len) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Buffer too small to hold result.\n");
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, sig);
|
|
Packit |
8681c6 |
return CKR_BUFFER_TOO_SMALL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(out_data, sig, sig_len);
|
|
Packit |
8681c6 |
*out_data_len = sig_len;
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, sig);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_encrypt(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len, OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
tpm_private_data_t *tpm_data = (tpm_private_data_t *)tokdata->private_data;
|
|
Packit |
8681c6 |
TSS_RESULT result;
|
|
Packit |
8681c6 |
TSS_HENCDATA hEncData;
|
|
Packit |
8681c6 |
BYTE *dataBlob;
|
|
Packit |
8681c6 |
UINT32 dataBlobSize;
|
|
Packit |
8681c6 |
TSS_HKEY hKey;
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_rsa_load_key(tokdata, key_obj, &hKey);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("token_rsa_load_key failed. rc=0x%lx\n", rc);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Context_CreateObject(tpm_data->tspContext,
|
|
Packit |
8681c6 |
TSS_OBJECT_TYPE_ENCDATA,
|
|
Packit |
8681c6 |
TSS_ENCDATA_BIND, &hEncData);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Context_CreateObject failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_Data_Bind(hEncData, hKey, in_data_len, in_data);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_Data_Bind failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
result = Tspi_GetAttribData(hEncData, TSS_TSPATTRIB_ENCDATA_BLOB,
|
|
Packit |
8681c6 |
TSS_TSPATTRIB_ENCDATABLOB_BLOB,
|
|
Packit |
8681c6 |
&dataBlobSize, &dataBlob);
|
|
Packit |
8681c6 |
if (result) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Tspi_SetAttribData failed. rc=0x%x\n", result);
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (dataBlobSize > *out_data_len) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, dataBlob);
|
|
Packit |
8681c6 |
return CKR_DATA_LEN_RANGE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(out_data, dataBlob, dataBlobSize);
|
|
Packit |
8681c6 |
*out_data_len = dataBlobSize;
|
|
Packit |
8681c6 |
Tspi_Context_FreeMemory(tpm_data->tspContext, dataBlob);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_rsa_verify_recover(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * signature, CK_ULONG sig_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key_obj)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = token_specific_rsa_encrypt(tokdata, signature, sig_len, out_data,
|
|
Packit |
8681c6 |
out_data_len, key_obj);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
TRACE_DEVEL("token specific rsa_encrypt failed.\n");
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
CK_RV token_specific_aes_key_gen(STDLL_TokData_t *tokdata, CK_BYTE **key,
|
|
Packit Service |
8aa27d |
CK_ULONG *len, CK_ULONG keysize,
|
|
Packit Service |
8aa27d |
CK_BBOOL *is_opaque)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
*key = malloc(keysize);
|
|
Packit Service |
8aa27d |
if (*key == NULL)
|
|
Packit Service |
8aa27d |
return CKR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
*len = keysize;
|
|
Packit Service |
8aa27d |
*is_opaque = FALSE;
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
return rng_generate(tokdata, *key, keysize);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_aes_ecb(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
AES_KEY ssl_aes_key;
|
|
Packit |
8681c6 |
unsigned int i;
|
|
Packit |
8681c6 |
/* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0,
|
|
Packit |
8681c6 |
* so this is fine */
|
|
Packit |
8681c6 |
CK_ULONG loops = (CK_ULONG) (in_data_len / AES_BLOCK_SIZE);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(&ssl_aes_key, 0, sizeof(AES_KEY));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// AES_ecb_encrypt encrypts only a single block, so we have to break up the
|
|
Packit |
8681c6 |
// input data here
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
AES_set_encrypt_key((unsigned char *) attr->pValue,
|
|
Packit |
8681c6 |
(attr->ulValueLen * 8), &ssl_aes_key);
|
|
Packit |
8681c6 |
for (i = 0; i < loops; i++) {
|
|
Packit |
8681c6 |
AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
|
|
Packit |
8681c6 |
(unsigned char *) out_data + (i * AES_BLOCK_SIZE),
|
|
Packit |
8681c6 |
&ssl_aes_key, AES_ENCRYPT);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
AES_set_decrypt_key((unsigned char *) attr->pValue,
|
|
Packit |
8681c6 |
(attr->ulValueLen * 8), &ssl_aes_key);
|
|
Packit |
8681c6 |
for (i = 0; i < loops; i++) {
|
|
Packit |
8681c6 |
AES_ecb_encrypt((unsigned char *) in_data + (i * AES_BLOCK_SIZE),
|
|
Packit |
8681c6 |
(unsigned char *) out_data + (i * AES_BLOCK_SIZE),
|
|
Packit |
8681c6 |
&ssl_aes_key, AES_DECRYPT);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
CK_RV rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
unsigned char akey[AES_KEY_SIZE_256];
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = NULL;
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
CK_ULONG keylen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
keylen = attr->ulValueLen;
|
|
Packit Service |
8aa27d |
if (keylen == 128 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_128_ecb();
|
|
Packit Service |
8aa27d |
} else if (keylen == 192 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_192_ecb();
|
|
Packit Service |
8aa27d |
} else if (keylen == 256 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_256_ecb();
|
|
Packit Service |
8aa27d |
} else {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("Invalid AES key size.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
memcpy(akey, attr->pValue, keylen);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % AES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
rc = CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, akey, NULL, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(akey, sizeof(akey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_aes_cbc(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_BYTE * in_data,
|
|
Packit |
8681c6 |
CK_ULONG in_data_len,
|
|
Packit |
8681c6 |
CK_BYTE * out_data,
|
|
Packit |
8681c6 |
CK_ULONG * out_data_len,
|
|
Packit |
8681c6 |
OBJECT * key, CK_BYTE * init_v, CK_BYTE encrypt)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
Packit |
8681c6 |
AES_KEY ssl_aes_key;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// get the key value
|
|
Packit |
8681c6 |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(&ssl_aes_key, 0, sizeof(AES_KEY));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike
|
|
Packit |
8681c6 |
// AES_ecb_encrypt, so no looping required.
|
|
Packit |
8681c6 |
if (encrypt) {
|
|
Packit |
8681c6 |
AES_set_encrypt_key((unsigned char *) attr->pValue,
|
|
Packit |
8681c6 |
(attr->ulValueLen * 8), &ssl_aes_key);
|
|
Packit |
8681c6 |
AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
|
|
Packit |
8681c6 |
in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
AES_set_decrypt_key((unsigned char *) attr->pValue,
|
|
Packit |
8681c6 |
(attr->ulValueLen * 8), &ssl_aes_key);
|
|
Packit |
8681c6 |
AES_cbc_encrypt((unsigned char *) in_data, (unsigned char *) out_data,
|
|
Packit |
8681c6 |
in_data_len, &ssl_aes_key, init_v, AES_DECRYPT);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
*out_data_len = in_data_len;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit Service |
8aa27d |
#else
|
|
Packit Service |
8aa27d |
CK_RV rc;
|
|
Packit Service |
8aa27d |
int outlen;
|
|
Packit Service |
8aa27d |
unsigned char akey[AES_KEY_SIZE_256];
|
|
Packit Service |
8aa27d |
const EVP_CIPHER *cipher = NULL;
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX *ctx = NULL;
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit Service |
8aa27d |
CK_ULONG keylen;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
// get the key value
|
|
Packit Service |
8aa27d |
if (template_attribute_find(key->template, CKA_VALUE, &attr) == FALSE) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("template_attribute_find(CKA_VALUE) failed.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
keylen = attr->ulValueLen;
|
|
Packit Service |
8aa27d |
if (keylen == 128 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_128_cbc();
|
|
Packit Service |
8aa27d |
} else if (keylen == 192 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_192_cbc();
|
|
Packit Service |
8aa27d |
} else if (keylen == 256 / 8) {
|
|
Packit Service |
8aa27d |
cipher = EVP_aes_256_cbc();
|
|
Packit Service |
8aa27d |
} else {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("Invalid AES key size.\n");
|
|
Packit Service |
8aa27d |
return CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
memcpy(akey, attr->pValue, keylen);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (in_data_len % AES_BLOCK_SIZE || in_data_len > INT_MAX) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
|
|
Packit Service |
8aa27d |
rc = CKR_DATA_LEN_RANGE;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
ctx = EVP_CIPHER_CTX_new();
|
|
Packit Service |
8aa27d |
if (ctx == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit Service |
8aa27d |
rc = ERR_HOST_MEMORY;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (EVP_CipherInit_ex(ctx, cipher,
|
|
Packit Service |
8aa27d |
NULL, akey, init_v, encrypt ? 1 : 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CIPHER_CTX_set_padding(ctx, 0) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherUpdate(ctx, out_data, &outlen, in_data, in_data_len) != 1
|
|
Packit Service |
8aa27d |
|| EVP_CipherFinal_ex(ctx, out_data, &outlen) != 1) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("%s\n", ock_err(ERR_GENERAL_ERROR));
|
|
Packit Service |
8aa27d |
rc = ERR_GENERAL_ERROR;
|
|
Packit Service |
8aa27d |
goto done;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
*out_data_len = in_data_len;
|
|
Packit Service |
8aa27d |
rc = CKR_OK;
|
|
Packit Service |
8aa27d |
done:
|
|
Packit Service |
8aa27d |
OPENSSL_cleanse(akey, sizeof(akey));
|
|
Packit Service |
8aa27d |
EVP_CIPHER_CTX_free(ctx);
|
|
Packit Service |
8aa27d |
return rc;
|
|
Packit Service |
8aa27d |
#endif
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_get_mechanism_list(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_MECHANISM_TYPE_PTR pMechanismList,
|
|
Packit |
8681c6 |
CK_ULONG_PTR pulCount)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
return ock_generic_get_mechanism_list(tokdata, pMechanismList, pulCount);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_get_mechanism_info(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_MECHANISM_TYPE type,
|
|
Packit |
8681c6 |
CK_MECHANISM_INFO_PTR pInfo)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
return ock_generic_get_mechanism_info(tokdata, type, pInfo);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
int token_specific_creatlock(void)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
char lockfile[PATH_MAX + (sizeof(LOCKDIR_PATH) - 1)
|
|
Packit |
8681c6 |
+ 2 * (sizeof(SUB_DIR) - 1)
|
|
Packit |
8681c6 |
+ (sizeof("///LCK..") - 1) + 1];
|
|
Packit |
8681c6 |
char lockdir[(sizeof(LOCKDIR_PATH) - 1) + (sizeof(SUB_DIR) - 1)
|
|
Packit |
8681c6 |
+ (sizeof("/") - 1) + 1];
|
|
Packit |
8681c6 |
struct passwd *pw = NULL;
|
|
Packit |
8681c6 |
struct stat statbuf;
|
|
Packit |
8681c6 |
mode_t mode = (S_IRUSR | S_IWUSR | S_IXUSR);
|
|
Packit |
8681c6 |
int lockfd = -1;;
|
|
Packit |
8681c6 |
int ret = -1;
|
|
Packit |
8681c6 |
struct group *grp = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* get userid */
|
|
Packit |
8681c6 |
pw = getpwuid(getuid());
|
|
Packit |
8681c6 |
if (pw == NULL) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "getpwuid(): %s\n", strerror(errno));
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (strlen(pw->pw_name) > PATH_MAX) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "Username(%s) too long\n", pw->pw_name);
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/** create lock subdir for each token if it doesn't exist.
|
|
Packit |
8681c6 |
* The root /var/lock/opencryptoki directory should be created in slotmgr
|
|
Packit |
8681c6 |
* daemon **/
|
|
Packit |
8681c6 |
sprintf(lockdir, "%s/%s", LOCKDIR_PATH, SUB_DIR);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
ret = stat(lockdir, &statbuf);
|
|
Packit |
8681c6 |
if (ret != 0 && errno == ENOENT) {
|
|
Packit |
8681c6 |
/* dir does not exist, try to create it */
|
|
Packit |
8681c6 |
ret = mkdir(lockdir, S_IRWXU | S_IRWXG);
|
|
Packit |
8681c6 |
if (ret != 0) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR,
|
|
Packit |
8681c6 |
"Directory(%s) missing: %s\n", lockdir, strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (grp == NULL) {
|
|
Packit |
8681c6 |
fprintf(stderr, "getgrname(pkcs11): %s", strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
/* set ownership to euid, and pkcs11 group */
|
|
Packit |
8681c6 |
if (chown(lockdir, geteuid(), grp->gr_gid) != 0) {
|
|
Packit |
8681c6 |
fprintf(stderr, "Failed to set owner:group \
|
|
Packit |
8681c6 |
ownership\
|
|
Packit |
8681c6 |
on %s directory", lockdir);
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
/* mkdir does not set group permission right, so
|
|
Packit |
8681c6 |
** trying explictly here again */
|
|
Packit |
8681c6 |
if (chmod(lockdir, S_IRWXU | S_IRWXG) != 0) {
|
|
Packit |
8681c6 |
fprintf(stderr, "Failed to change \
|
|
Packit |
8681c6 |
permissions\
|
|
Packit |
8681c6 |
on %s directory", lockdir);
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create user-specific directory */
|
|
Packit |
8681c6 |
sprintf(lockfile, "%s/%s/%s", LOCKDIR_PATH, SUB_DIR, pw->pw_name);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* see if it exists, otherwise mkdir will fail */
|
|
Packit |
8681c6 |
if (stat(lockfile, &statbuf) < 0) {
|
|
Packit |
8681c6 |
if (mkdir(lockfile, mode) == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "mkdir(%s): %s\n", lockfile, strerror(errno));
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* ensure correct perms on user dir */
|
|
Packit |
8681c6 |
if (chmod(lockfile, mode) == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "chmod(%s): %s\n", lockfile, strerror(errno));
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create user lock file */
|
|
Packit |
8681c6 |
memset(lockfile, 0, sizeof(lockfile));
|
|
Packit |
8681c6 |
sprintf(lockfile, "%s/%s/%s/LCK..%s", LOCKDIR_PATH, SUB_DIR, pw->pw_name,
|
|
Packit |
8681c6 |
SUB_DIR);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
lockfd = open(lockfile, O_CREAT | O_RDWR, mode);
|
|
Packit |
8681c6 |
if (lockfd == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "open(%s): %s\n", lockfile, strerror(errno));
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
/* umask may prevent correct mode, so set it. */
|
|
Packit |
8681c6 |
if (fchmod(lockfd, mode) == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "fchmod(%s): %s\n", lockfile, strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return lockfd;
|
|
Packit |
8681c6 |
err:
|
|
Packit |
8681c6 |
if (lockfd != -1)
|
|
Packit |
8681c6 |
close(lockfd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return -1;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV token_specific_init_token_data(STDLL_TokData_t * tokdata,
|
|
Packit |
8681c6 |
CK_SLOT_ID slot_id)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
UNUSED(slot_id);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* do nothing. */
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
CK_RV token_specific_key_wrap(STDLL_TokData_t *tokdata, SESSION *session,
|
|
Packit Service |
8aa27d |
CK_MECHANISM *mech, CK_BBOOL length_only,
|
|
Packit Service |
8aa27d |
OBJECT *wrapping_key, OBJECT *key,
|
|
Packit Service |
8aa27d |
CK_BYTE *wrapped_key, CK_ULONG *wrapped_key_len,
|
|
Packit Service |
8aa27d |
CK_BBOOL *not_opaque)
|
|
Packit Service |
8aa27d |
{
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr;
|
|
Packit Service |
8aa27d |
CK_OBJECT_CLASS class;
|
|
Packit Service |
8aa27d |
CK_KEY_TYPE keytype;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
UNUSED(session);
|
|
Packit Service |
8aa27d |
UNUSED(length_only);
|
|
Packit Service |
8aa27d |
UNUSED(wrapped_key);
|
|
Packit Service |
8aa27d |
UNUSED(wrapped_key_len);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(wrapping_key->template, CKA_CLASS, &attr))
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
class = *(CK_OBJECT_CLASS *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (class != CKO_SECRET_KEY)
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(key->template, CKA_CLASS, &attr))
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
class = *(CK_OBJECT_CLASS *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (class != CKO_SECRET_KEY)
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(wrapping_key->template, CKA_KEY_TYPE, &attr))
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
switch (mech->mechanism) {
|
|
Packit Service |
8aa27d |
case CKM_DES_ECB:
|
|
Packit Service |
8aa27d |
case CKM_DES_CBC:
|
|
Packit Service |
8aa27d |
case CKM_DES_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_DES)
|
|
Packit Service |
8aa27d |
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_DES3_ECB:
|
|
Packit Service |
8aa27d |
case CKM_DES3_CBC:
|
|
Packit Service |
8aa27d |
case CKM_DES3_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_DES2 && keytype != CKK_DES3)
|
|
Packit Service |
8aa27d |
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_AES_ECB:
|
|
Packit Service |
8aa27d |
case CKM_AES_CBC:
|
|
Packit Service |
8aa27d |
case CKM_AES_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_AES)
|
|
Packit Service |
8aa27d |
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
default:
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(key->template, CKA_KEY_TYPE, &attr))
|
|
Packit Service |
8aa27d |
return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
switch (keytype) {
|
|
Packit Service |
8aa27d |
case CKK_DES:
|
|
Packit Service |
8aa27d |
case CKK_DES2:
|
|
Packit Service |
8aa27d |
case CKK_DES3:
|
|
Packit Service |
8aa27d |
case CKK_AES:
|
|
Packit Service |
8aa27d |
case CKK_GENERIC_SECRET:
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
default:
|
|
Packit Service |
8aa27d |
return CKR_KEY_NOT_WRAPPABLE;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
/* Symmetric keys are not opaque, so we can let common code do the wrap */
|
|
Packit Service |
8aa27d |
*not_opaque = TRUE;
|
|
Packit Service |
8aa27d |
return CKR_OK;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
CK_RV token_specific_key_unwrap(STDLL_TokData_t *tokdata, SESSION *session,
|
|
Packit Service |
8aa27d |
CK_MECHANISM *mech,
|
|
Packit Service |
8aa27d |
CK_BYTE *wrapped_key, CK_ULONG wrapped_key_len,
|
|
Packit Service |
8aa27d |
OBJECT *unwrapping_key, OBJECT *unwrapped_key,
|
|
Packit Service |
8aa27d |
CK_BBOOL *not_opaque)
|
|
Packit Service |
8aa27d |
{
|
|
Packit Service |
8aa27d |
CK_ATTRIBUTE *attr;
|
|
Packit Service |
8aa27d |
CK_OBJECT_CLASS class;
|
|
Packit Service |
8aa27d |
CK_KEY_TYPE keytype;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
UNUSED(tokdata);
|
|
Packit Service |
8aa27d |
UNUSED(session);
|
|
Packit Service |
8aa27d |
UNUSED(wrapped_key);
|
|
Packit Service |
8aa27d |
UNUSED(wrapped_key_len);
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(unwrapping_key->template, CKA_CLASS, &attr))
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
class = *(CK_OBJECT_CLASS *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (class != CKO_SECRET_KEY)
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(unwrapped_key->template, CKA_CLASS, &attr))
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
class = *(CK_OBJECT_CLASS *)attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (class != CKO_SECRET_KEY)
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(unwrapping_key->template, CKA_KEY_TYPE, &attr))
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
switch (mech->mechanism) {
|
|
Packit Service |
8aa27d |
case CKM_DES_ECB:
|
|
Packit Service |
8aa27d |
case CKM_DES_CBC:
|
|
Packit Service |
8aa27d |
case CKM_DES_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_DES)
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_DES3_ECB:
|
|
Packit Service |
8aa27d |
case CKM_DES3_CBC:
|
|
Packit Service |
8aa27d |
case CKM_DES3_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_DES2 && keytype != CKK_DES3)
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_AES_ECB:
|
|
Packit Service |
8aa27d |
case CKM_AES_CBC:
|
|
Packit Service |
8aa27d |
case CKM_AES_CBC_PAD:
|
|
Packit Service |
8aa27d |
if (keytype != CKK_AES)
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
default:
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
if (!template_attribute_find(unwrapped_key->template, CKA_KEY_TYPE, &attr))
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
switch (keytype) {
|
|
Packit Service |
8aa27d |
case CKK_DES:
|
|
Packit Service |
8aa27d |
case CKK_DES2:
|
|
Packit Service |
8aa27d |
case CKK_DES3:
|
|
Packit Service |
8aa27d |
case CKK_AES:
|
|
Packit Service |
8aa27d |
case CKK_GENERIC_SECRET:
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
default:
|
|
Packit Service |
8aa27d |
return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
/* Symmetric keys are not opaque, so we can let common code do the unwrap */
|
|
Packit Service |
8aa27d |
*not_opaque = TRUE;
|
|
Packit Service |
8aa27d |
return CKR_OK;
|
|
Packit Service |
8aa27d |
}
|