47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * The Initial Developer of the Original Code is International
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Business Machines Corporation. Portions created by IBM
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Corporation are Copyright (C) 2005 International Business
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Machines Corporation. All Rights Reserved.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * This program is free software; you can redistribute it and/or modify
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * it under the terms of the Common Public License as published by
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * IBM Corporation; either version 1 of the License, or (at your option)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * any later version.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * This program is distributed in the hope that it will be useful,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * but WITHOUT ANY WARRANTY; without even the implied warranty of
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Common Public License for more details.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll *
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * You should have received a copy of the Common Public License
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * along with this program; if not, a copy can be viewed at
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * http://www.opensource.org/licenses/cpl1.0.php.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll/*
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll * Use is subject to license terms.
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll */
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll#include "tpmtok_int.h"
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersolldecr_mgr_init(
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll SESSION *sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ENCR_DECR_CONTEXT *ctx,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG operation,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_MECHANISM *mech,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_OBJECT_HANDLE key_handle)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll OBJECT * key_obj = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *ptr = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_KEY_TYPE keytype;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL flag;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_RV rc;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! sess) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (ctx->active != FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OPERATION_ACTIVE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (operation == OP_DECRYPT_INIT) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, key_handle,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_HANDLE_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_DECRYPT, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_FUNCTION_NOT_PERMITTED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = *(CK_BBOOL *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag != TRUE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_FUNCTION_NOT_PERMITTED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else if (operation == OP_UNWRAP) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, key_handle,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll &key_obj);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc != CKR_OK) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_WRAPPING_KEY_HANDLE_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_UNWRAP, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll flag = *(CK_BBOOL *)(attr->pValue);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (flag == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (mech->mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (mech->ulParameterLen != 0)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_MECHANISM_PARAM_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll rc = template_attribute_find(key_obj->template,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CKA_KEY_TYPE, &attr);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (rc == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_TYPE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll } else {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll keytype = *(CK_KEY_TYPE *)attr->pValue;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (keytype != CKK_RSA) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_KEY_TYPE_INCONSISTENT);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->context_len = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->context = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll break;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_MECHANISM_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (mech->ulParameterLen > 0) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ptr = (CK_BYTE *)malloc(mech->ulParameterLen);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! ptr) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_HOST_MEMORY);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll (void) memcpy(ptr, mech->pParameter, mech->ulParameterLen);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->key = key_handle;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.ulParameterLen = mech->ulParameterLen;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.mechanism = mech->mechanism;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.pParameter = ptr;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->multi = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->active = TRUE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OK);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersolldecr_mgr_cleanup(ENCR_DECR_CONTEXT *ctx)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! ctx) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->key = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.ulParameterLen = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.mechanism = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->multi = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->active = FALSE;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->context_len = 0;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (ctx->mech.pParameter) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll free(ctx->mech.pParameter);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->mech.pParameter = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (ctx->context) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll free(ctx->context);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx->context = NULL;
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OK);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys IngersollCK_RV
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersolldecr_mgr_decrypt(SESSION *sess,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BBOOL length_only,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ENCR_DECR_CONTEXT *ctx,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *in_data,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG in_data_len,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_BYTE *out_data,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll CK_ULONG *out_data_len)
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll{
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (! sess || ! ctx) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (ctx->active == FALSE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OPERATION_NOT_INITIALIZED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if ((length_only == FALSE) && (! in_data || ! out_data)) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_FUNCTION_FAILED);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll if (ctx->multi == TRUE) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_OPERATION_ACTIVE);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll switch (ctx->mech.mechanism) {
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll case CKM_RSA_PKCS:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (rsa_pkcs_decrypt(sess, length_only,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll ctx, in_data, in_data_len, out_data,
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll out_data_len));
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll default:
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll return (CKR_MECHANISM_INVALID);
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll }
47e946e784719ae402ace34695f67b0e6e76ae5cWyllys Ingersoll}