Blame usr/lib/common/mech_des.c

Packit 8681c6
/*
Packit 8681c6
 * COPYRIGHT (c) International Business Machines Corp. 2001-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
// File:  mech_des.c
Packit 8681c6
//
Packit 8681c6
// Mechanisms for DES
Packit 8681c6
//
Packit 8681c6
Packit 8681c6
#include <string.h>             // for memcmp() et al
Packit 8681c6
#include <stdlib.h>
Packit 8681c6
Packit 8681c6
#include "pkcs11types.h"
Packit 8681c6
#include "defs.h"
Packit 8681c6
#include "host_defs.h"
Packit 8681c6
#include "h_extern.h"
Packit 8681c6
#include "tok_spec_struct.h"
Packit 8681c6
#include "trace.h"
Packit 8681c6
Packit 8681c6
#include <openssl/crypto.h>
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV pk_des_ecb_encrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                         SESSION *sess,
Packit 8681c6
                         CK_BBOOL length_only,
Packit 8681c6
                         ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                         CK_BYTE *in_data,
Packit 8681c6
                         CK_ULONG in_data_len,
Packit 8681c6
                         CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // CKM_DES_ECB requires the input data to be an integral
Packit 8681c6
    // multiple of the block size
Packit 8681c6
    //
Packit 8681c6
    if (in_data_len % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        rc = CKR_BUFFER_TOO_SMALL;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    rc = ckm_des_ecb_encrypt(tokdata, in_data, in_data_len,
Packit 8681c6
                             out_data, out_data_len, key);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_ecb_decrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                      SESSION *sess,
Packit 8681c6
                      CK_BBOOL length_only,
Packit 8681c6
                      ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                      CK_BYTE *in_data,
Packit 8681c6
                      CK_ULONG in_data_len,
Packit 8681c6
                      CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // CKM_DES_ECB requires the input data to be an integral
Packit 8681c6
    // multiple of the block size
Packit 8681c6
    //
Packit 8681c6
    if (in_data_len % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        rc = CKR_BUFFER_TOO_SMALL;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    rc = ckm_des_ecb_decrypt(tokdata, in_data, in_data_len,
Packit 8681c6
                             out_data, out_data_len, key);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV pk_des_cbc_encrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                         SESSION *sess,
Packit 8681c6
                         CK_BBOOL length_only,
Packit 8681c6
                         ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                         CK_BYTE *in_data,
Packit 8681c6
                         CK_ULONG in_data_len,
Packit 8681c6
                         CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // CKM_DES_CBC requires the input data to be an integral
Packit 8681c6
    // multiple of the block size
Packit 8681c6
    //
Packit 8681c6
    if (in_data_len % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        rc = CKR_BUFFER_TOO_SMALL;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    rc = ckm_des_cbc_encrypt(tokdata, in_data, in_data_len, out_data,
Packit 8681c6
                             out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_decrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                      SESSION *sess,
Packit 8681c6
                      CK_BBOOL length_only,
Packit 8681c6
                      ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                      CK_BYTE *in_data,
Packit 8681c6
                      CK_ULONG in_data_len,
Packit 8681c6
                      CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // CKM_DES_CBC requires the input data to be an integral
Packit 8681c6
    // multiple of the block size
Packit 8681c6
    //
Packit 8681c6
    if (in_data_len % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        rc = CKR_BUFFER_TOO_SMALL;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    rc = ckm_des_cbc_decrypt(tokdata, in_data, in_data_len, out_data,
Packit 8681c6
                             out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_encrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                          SESSION *sess,
Packit 8681c6
                          CK_BBOOL length_only,
Packit 8681c6
                          ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                          CK_BYTE *in_data,
Packit 8681c6
                          CK_ULONG in_data_len,
Packit 8681c6
                          CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *clear = NULL;
Packit 8681c6
    CK_ULONG padded_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // DES-CBC-PAD has no input length requirements
Packit 8681c6
    //
Packit 8681c6
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
    // compute the output length, accounting for padding
Packit 8681c6
    //
Packit 8681c6
    padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1);
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = padded_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (*out_data_len < padded_len) {
Packit 8681c6
        *out_data_len = padded_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        rc = CKR_BUFFER_TOO_SMALL;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    clear = (CK_BYTE *) malloc(padded_len);
Packit 8681c6
    if (!clear) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
        rc = CKR_HOST_MEMORY;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit Service 8aa27d
    if (in_data != NULL && in_data_len > 0)
Packit Service 8aa27d
        memcpy(clear, in_data, in_data_len);
Packit 8681c6
Packit 8681c6
    add_pkcs_padding(clear + in_data_len,
Packit 8681c6
                     DES_BLOCK_SIZE, in_data_len, padded_len);
Packit 8681c6
Packit 8681c6
    rc = ckm_des_cbc_encrypt(tokdata, clear, padded_len, out_data, out_data_len,
Packit 8681c6
                             ctx->mech.pParameter, key);
Packit 8681c6
    free(clear);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_decrypt(STDLL_TokData_t *tokdata,
Packit 8681c6
                          SESSION *sess,
Packit 8681c6
                          CK_BBOOL length_only,
Packit 8681c6
                          ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                          CK_BYTE *in_data,
Packit 8681c6
                          CK_ULONG in_data_len,
Packit 8681c6
                          CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *clear = NULL;
Packit 8681c6
    CK_ULONG padded_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    //
Packit 8681c6
    // no need to validate the input length since we'll pad as necessary
Packit 8681c6
    //
Packit 8681c6
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
    // we're decrypting so even with CBC-PAD, we should have an integral
Packit 8681c6
    // number of block to decrypt
Packit 8681c6
    //
Packit 8681c6
    if (in_data_len % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        rc = CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
    // the amount of cleartext after stripping the padding will actually be less
Packit 8681c6
    // than the input bytes...
Packit 8681c6
    //
Packit 8681c6
    padded_len = in_data_len;
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = padded_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    clear = (CK_BYTE *) malloc(padded_len);
Packit 8681c6
    if (!clear) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
        rc = CKR_HOST_MEMORY;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
    rc = ckm_des_cbc_decrypt(tokdata, in_data, in_data_len, clear, &padded_len,
Packit 8681c6
                             ctx->mech.pParameter, key);
Packit 8681c6
Packit 8681c6
    if (rc == CKR_OK) {
Packit 8681c6
        strip_pkcs_padding(clear, padded_len, out_data_len);
Packit 8681c6
        memcpy(out_data, clear, *out_data_len);
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    free(clear);
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_ecb_encrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                             SESSION *sess,
Packit 8681c6
                             CK_BBOOL length_only,
Packit 8681c6
                             ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                             CK_BYTE *in_data,
Packit 8681c6
                             CK_ULONG in_data_len,
Packit 8681c6
                             CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *clear = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = (context->len + in_data_len);
Packit 8681c6
Packit 8681c6
    if (total < DES_BLOCK_SIZE) {
Packit 8681c6
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block
Packit 8681c6
        //
Packit 8681c6
        remain = (total % DES_BLOCK_SIZE);
Packit 8681c6
        out_len = (total - remain);     // should always be at least 1 block
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        clear = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!clear) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous encryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(clear, context->data, context->len);
Packit 8681c6
        memcpy(clear + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_ecb_encrypt(tokdata, clear, out_len, out_data,
Packit 8681c6
                                 out_data_len, key);
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
Packit 8681c6
            // update the context buffer.  we already used the buffer's current
Packit 8681c6
            // contents so we completely overwrite it
Packit 8681c6
            //
Packit 8681c6
            if (remain != 0)
Packit 8681c6
                memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        free(clear);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_ecb_decrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                             SESSION *sess,
Packit 8681c6
                             CK_BBOOL length_only,
Packit 8681c6
                             ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                             CK_BYTE *in_data,
Packit 8681c6
                             CK_ULONG in_data_len,
Packit 8681c6
                             CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *cipher = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = (context->len + in_data_len);
Packit 8681c6
Packit 8681c6
    if (total < DES_BLOCK_SIZE) {
Packit 8681c6
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block
Packit 8681c6
        //
Packit 8681c6
        remain = (total % DES_BLOCK_SIZE);
Packit 8681c6
        out_len = total - remain;
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        cipher = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!cipher) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous decryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(cipher, context->data, context->len);
Packit 8681c6
        memcpy(cipher + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_ecb_decrypt(tokdata, cipher, out_len, out_data,
Packit 8681c6
                                 out_data_len, key);
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
Packit 8681c6
            // copy the remaining 'new' input data to the context buffer
Packit 8681c6
            //
Packit 8681c6
            if (remain != 0)
Packit 8681c6
                memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        free(cipher);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_encrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                             SESSION *sess,
Packit 8681c6
                             CK_BBOOL length_only,
Packit 8681c6
                             ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                             CK_BYTE *in_data,
Packit 8681c6
                             CK_ULONG in_data_len,
Packit 8681c6
                             CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *clear = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = (context->len + in_data_len);
Packit 8681c6
Packit 8681c6
    if (total < DES_BLOCK_SIZE) {
Packit 8681c6
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block
Packit 8681c6
        //
Packit 8681c6
        remain = (total % DES_BLOCK_SIZE);
Packit 8681c6
        out_len = total - remain;
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
        // these buffers need to be longword aligned
Packit 8681c6
        //
Packit 8681c6
        clear = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!clear) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous encryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(clear, context->data, context->len);
Packit 8681c6
        memcpy(clear + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
Packit 8681c6
                                 out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
Packit 8681c6
            // the new init_v is the last encrypted data block
Packit 8681c6
            //
Packit 8681c6
            memcpy(ctx->mech.pParameter,
Packit 8681c6
                   out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE);
Packit 8681c6
Packit 8681c6
            // copy the remaining 'new' input data to the context buffer
Packit 8681c6
            //
Packit 8681c6
            if (remain != 0)
Packit 8681c6
                memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        free(clear);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_decrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                             SESSION *sess,
Packit 8681c6
                             CK_BBOOL length_only,
Packit 8681c6
                             ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                             CK_BYTE *in_data,
Packit 8681c6
                             CK_ULONG in_data_len,
Packit 8681c6
                             CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *cipher = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = context->len + in_data_len;
Packit 8681c6
Packit 8681c6
    if (total < DES_BLOCK_SIZE) {
Packit 8681c6
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block
Packit 8681c6
        //
Packit 8681c6
        remain = total % DES_BLOCK_SIZE;
Packit 8681c6
        out_len = total - remain;
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
        // these buffers need to be longword aligned
Packit 8681c6
        //
Packit 8681c6
        cipher = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!cipher) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous decryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(cipher, context->data, context->len);
Packit 8681c6
        memcpy(cipher + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_cbc_decrypt(tokdata, cipher, out_len, out_data,
Packit 8681c6
                                 out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
Packit 8681c6
            // the new init_v is the last decrypted data block
Packit 8681c6
            //
Packit 8681c6
            memcpy(ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE),
Packit 8681c6
                   DES_BLOCK_SIZE);
Packit 8681c6
Packit 8681c6
            // copy the remaining 'new' input data to the context buffer
Packit 8681c6
            //
Packit 8681c6
            if (remain != 0)
Packit 8681c6
                memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        free(cipher);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_encrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                                 SESSION *sess,
Packit 8681c6
                                 CK_BBOOL length_only,
Packit 8681c6
                                 ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                                 CK_BYTE *in_data,
Packit 8681c6
                                 CK_ULONG in_data_len,
Packit 8681c6
                                 CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *clear = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = (context->len + in_data_len);
Packit 8681c6
Packit 8681c6
    // note, this is subtly different from the other encrypt update routines
Packit 8681c6
    //
Packit 8681c6
    if (total <= DES_BLOCK_SIZE) {
Packit Service 8aa27d
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block + 1 byte
Packit 8681c6
        //
Packit 8681c6
        remain = total % DES_BLOCK_SIZE;
Packit 8681c6
        out_len = total - remain;
Packit 8681c6
Packit 8681c6
        if (remain == 0) {
Packit 8681c6
            remain = DES_BLOCK_SIZE;
Packit 8681c6
            out_len -= DES_BLOCK_SIZE;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
        // at this point, we should have:
Packit 8681c6
        //    1) remain != 0
Packit 8681c6
        //    2) out_len != 0
Packit 8681c6
        //
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
        // these buffers need to be longword aligned
Packit 8681c6
        //
Packit 8681c6
        clear = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!clear) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous encryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(clear, context->data, context->len);
Packit 8681c6
        memcpy(clear + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        //
Packit 8681c6
        // we don't do padding during the update
Packit 8681c6
        //
Packit 8681c6
        rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
Packit 8681c6
                                 out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            // the new init_v is the last encrypted data block
Packit 8681c6
            //
Packit 8681c6
            memcpy(ctx->mech.pParameter,
Packit 8681c6
                   out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE);
Packit 8681c6
Packit 8681c6
            // copy the remaining 'new' input data to the temporary space
Packit 8681c6
            //
Packit 8681c6
            memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        free(clear);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_decrypt_update(STDLL_TokData_t *tokdata,
Packit 8681c6
                                 SESSION *sess,
Packit 8681c6
                                 CK_BBOOL length_only,
Packit 8681c6
                                 ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                                 CK_BYTE *in_data,
Packit 8681c6
                                 CK_ULONG in_data_len,
Packit 8681c6
                                 CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE *cipher = NULL;
Packit 8681c6
    CK_ULONG total, remain, out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    total = (context->len + in_data_len);
Packit 8681c6
Packit 8681c6
    // note, this is subtly different from the other decrypt update routines
Packit 8681c6
    //
Packit 8681c6
    if (total <= DES_BLOCK_SIZE) {
Packit Service 8aa27d
        if (length_only == FALSE && in_data_len) {
Packit 8681c6
            memcpy(context->data + context->len, in_data, in_data_len);
Packit 8681c6
            context->len += in_data_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        *out_data_len = 0;
Packit 8681c6
        return CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        // we have at least 1 block + 1 byte
Packit 8681c6
        //
Packit 8681c6
        remain = total % DES_BLOCK_SIZE;
Packit 8681c6
        out_len = total - remain;
Packit 8681c6
Packit 8681c6
        if (remain == 0) {
Packit 8681c6
            remain = DES_BLOCK_SIZE;
Packit 8681c6
            out_len -= DES_BLOCK_SIZE;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
        if (length_only == TRUE) {
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
            return CKR_OK;
Packit 8681c6
        }
Packit 8681c6
        // at this point, we should have:
Packit 8681c6
        //    1) remain != 0
Packit 8681c6
        //    2) out_len != 0
Packit 8681c6
        //
Packit 8681c6
        rc = object_mgr_find_in_map_nocache(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
        if (rc != CKR_OK) {
Packit 8681c6
            TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
            return rc;
Packit 8681c6
        }
Packit 8681c6
        // these buffers need to be longword aligned
Packit 8681c6
        //
Packit 8681c6
        cipher = (CK_BYTE *) malloc(out_len);
Packit 8681c6
        if (!cipher) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            object_put(tokdata, key, TRUE);
Packit 8681c6
            key = NULL;
Packit 8681c6
            return CKR_HOST_MEMORY;
Packit 8681c6
        }
Packit 8681c6
        // copy any data left over from the previous decryption operation first
Packit 8681c6
        //
Packit 8681c6
        memcpy(cipher, context->data, context->len);
Packit 8681c6
        memcpy(cipher + context->len, in_data, out_len - context->len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_cbc_decrypt(tokdata, cipher, out_len, out_data,
Packit 8681c6
                                 out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            // the new init_v is the last decrypted data block
Packit 8681c6
            //
Packit 8681c6
            memcpy(ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE),
Packit 8681c6
                   DES_BLOCK_SIZE);
Packit 8681c6
Packit 8681c6
            // copy the remaining 'new' input data to the temporary space
Packit 8681c6
            //
Packit 8681c6
            memcpy(context->data, in_data + (in_data_len - remain), remain);
Packit 8681c6
            context->len = remain;
Packit 8681c6
        }
Packit 8681c6
        free(cipher);
Packit 8681c6
Packit 8681c6
        object_put(tokdata, key, TRUE);
Packit 8681c6
        key = NULL;
Packit 8681c6
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_ecb_encrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                            SESSION *sess,
Packit 8681c6
                            CK_BBOOL length_only,
Packit 8681c6
                            ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                            CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
Packit 8681c6
    UNUSED(tokdata);
Packit 8681c6
    UNUSED(out_data);
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // satisfy the compiler
Packit 8681c6
    //
Packit 8681c6
    if (length_only)
Packit 8681c6
        context = NULL;
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // DES-ECB does no padding so there had better not be
Packit 8681c6
    // any data in the context buffer.  if there is it means
Packit 8681c6
    // that the overall data length was not a multiple of the blocksize
Packit 8681c6
    //
Packit 8681c6
    if (context->len != 0) {
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
    *out_data_len = 0;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_ecb_decrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                            SESSION *sess,
Packit 8681c6
                            CK_BBOOL length_only,
Packit 8681c6
                            ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                            CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
Packit 8681c6
    UNUSED(tokdata);
Packit 8681c6
    UNUSED(out_data);
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // satisfy the compiler
Packit 8681c6
    //
Packit 8681c6
    if (length_only)
Packit 8681c6
        context = NULL;
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // DES-ECB does no padding so there had better not be
Packit 8681c6
    // any data in the context buffer.  if there is it means
Packit 8681c6
    // that the overall data length was not a multiple of the blocksize
Packit 8681c6
    //
Packit 8681c6
    if (context->len != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    *out_data_len = 0;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_encrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                            SESSION *sess,
Packit 8681c6
                            CK_BBOOL length_only,
Packit 8681c6
                            ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                            CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
Packit 8681c6
    UNUSED(tokdata);
Packit 8681c6
    UNUSED(out_data);
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // satisfy the compiler
Packit 8681c6
    //
Packit 8681c6
    if (length_only)
Packit 8681c6
        context = NULL;
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // DES-CBC does no padding so there had better not be
Packit 8681c6
    // any data in the context buffer.  if there is it means
Packit 8681c6
    // that the overall data length was not a multiple of the blocksize
Packit 8681c6
    //
Packit 8681c6
    if (context->len != 0) {
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
    *out_data_len = 0;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_decrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                            SESSION *sess,
Packit 8681c6
                            CK_BBOOL length_only,
Packit 8681c6
                            ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                            CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
Packit 8681c6
    UNUSED(tokdata);
Packit 8681c6
    UNUSED(out_data);
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    // satisfy the compiler
Packit 8681c6
    //
Packit 8681c6
    if (length_only)
Packit 8681c6
        context = NULL;
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // DES-CBC does no padding so there had better not be
Packit 8681c6
    // any data in the context buffer.  if there is it means
Packit 8681c6
    // that the overall data length was not a multiple of the blocksize
Packit 8681c6
    //
Packit 8681c6
    if (context->len != 0) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        return CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    *out_data_len = 0;
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_encrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                                SESSION *sess,
Packit 8681c6
                                CK_BBOOL length_only,
Packit 8681c6
                                ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                                CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE clear[2 * DES_BLOCK_SIZE];
Packit 8681c6
    CK_ULONG out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // there will never be more than one block in the context buffer
Packit 8681c6
    // so the amount of output is as follows:
Packit 8681c6
    // if less than 1 block stored, we generate one block of output
Packit 8681c6
    // if a full block is stored, we generate two blocks of output (one pad
Packit 8681c6
    // block)
Packit 8681c6
    //
Packit 8681c6
    if (context->len == DES_BLOCK_SIZE)
Packit 8681c6
        out_len = 2 * DES_BLOCK_SIZE;
Packit 8681c6
    else
Packit 8681c6
        out_len = DES_BLOCK_SIZE;
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = out_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        memcpy(clear, context->data, context->len);
Packit 8681c6
Packit 8681c6
        add_pkcs_padding(clear + context->len,
Packit 8681c6
                         DES_BLOCK_SIZE, context->len, out_len);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
Packit 8681c6
                                 out_data_len, ctx->mech.pParameter, key);
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV des_cbc_pad_decrypt_final(STDLL_TokData_t *tokdata,
Packit 8681c6
                                SESSION *sess,
Packit 8681c6
                                CK_BBOOL length_only,
Packit 8681c6
                                ENCR_DECR_CONTEXT *ctx,
Packit 8681c6
                                CK_BYTE *out_data, CK_ULONG *out_data_len)
Packit 8681c6
{
Packit 8681c6
    DES_CONTEXT *context = NULL;
Packit 8681c6
    OBJECT *key = NULL;
Packit 8681c6
    CK_BYTE clear[DES_BLOCK_SIZE];
Packit 8681c6
    CK_BYTE cipher[DES_BLOCK_SIZE];
Packit 8681c6
    CK_ULONG out_len;
Packit 8681c6
    CK_RV rc;
Packit 8681c6
Packit 8681c6
    if (!sess || !ctx || !out_data_len) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    rc = object_mgr_find_in_map1(tokdata, ctx->key, &key, READ_LOCK);
Packit 8681c6
    if (rc != CKR_OK) {
Packit 8681c6
        TRACE_ERROR("Failed to find specified object.\n");
Packit 8681c6
        return rc;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    context = (DES_CONTEXT *) ctx->context;
Packit 8681c6
Packit 8681c6
    // there had better be a full block in the context buffer
Packit 8681c6
    //
Packit 8681c6
    if (context->len != DES_BLOCK_SIZE) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
Packit 8681c6
        rc = CKR_ENCRYPTED_DATA_LEN_RANGE;
Packit 8681c6
        goto done;
Packit 8681c6
    }
Packit 8681c6
    // we don't know a priori how much data we'll be returning. we won't
Packit 8681c6
    // know until after we decrypt it and strip the padding. it's possible
Packit 8681c6
    // that we'll return nothing (the final block might be a padding block).
Packit 8681c6
    //
Packit 8681c6
    out_len = DES_BLOCK_SIZE;   // upper bound on what we'll return
Packit 8681c6
Packit 8681c6
    if (length_only == TRUE) {
Packit 8681c6
        *out_data_len = out_len;
Packit 8681c6
        rc = CKR_OK;
Packit 8681c6
    } else {
Packit 8681c6
        memcpy(cipher, context->data, DES_BLOCK_SIZE);
Packit 8681c6
Packit 8681c6
        rc = ckm_des_cbc_decrypt(tokdata, cipher, DES_BLOCK_SIZE, clear,
Packit 8681c6
                                 &out_len, ctx->mech.pParameter, key);
Packit 8681c6
        if (rc == CKR_OK) {
Packit 8681c6
            strip_pkcs_padding(clear, DES_BLOCK_SIZE, &out_len);
Packit 8681c6
Packit 8681c6
            if (out_len != 0)
Packit 8681c6
                memcpy(out_data, clear, out_len);
Packit 8681c6
Packit 8681c6
            *out_data_len = out_len;
Packit 8681c6
        }
Packit 8681c6
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
done:
Packit 8681c6
    object_put(tokdata, key, TRUE);
Packit 8681c6
    key = NULL;
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
// mechanisms
Packit 8681c6
//
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_key_gen(STDLL_TokData_t *tokdata, TEMPLATE *tmpl)
Packit 8681c6
{
Packit 8681c6
Packit 8681c6
    CK_ATTRIBUTE *value_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *opaque_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *key_type_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *class_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *local_attr = NULL;
Packit 8681c6
    CK_BYTE *des_key = NULL;
Packit 8681c6
    CK_ULONG rc;
Packit Service 8aa27d
    CK_ULONG keysize = 0;
Packit Service 8aa27d
    CK_BBOOL is_opaque = FALSE;
Packit 8681c6
Packit 8681c6
    if (token_specific.t_des_key_gen == NULL) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
    }
Packit 8681c6
Packit Service 8aa27d
    rc = token_specific.t_des_key_gen(tokdata, &des_key, &keysize,
Packit Service 8aa27d
                                      DES_KEY_SIZE, &is_opaque);
Packit 8681c6
    if (rc != CKR_OK)
Packit 8681c6
        goto err;
Packit 8681c6
Packit Service 8aa27d
    /* For opaque keys put in CKA_IBM_OPAQUE and put dummy_key in CKA_VALUE. */
Packit Service 8aa27d
    if (is_opaque) {
Packit 8681c6
        opaque_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + keysize);
Packit 8681c6
        if (!opaque_attr) {
Packit 8681c6
            TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
            rc = CKR_HOST_MEMORY;
Packit 8681c6
            goto err;
Packit 8681c6
        }
Packit 8681c6
        opaque_attr->type = CKA_IBM_OPAQUE;
Packit 8681c6
        opaque_attr->ulValueLen = keysize;
Packit 8681c6
        opaque_attr->pValue = (CK_BYTE *) opaque_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
        memcpy(opaque_attr->pValue, des_key, keysize);
Packit 8681c6
        template_update_attribute(tmpl, opaque_attr);
Packit Service 8aa27d
    } else {
Packit Service 8aa27d
        if (keysize != DES_KEY_SIZE) {
Packit Service 8aa27d
            TRACE_ERROR("Invalid key size: %lu\n", keysize);
Packit Service 8aa27d
            rc = CKR_FUNCTION_FAILED;
Packit Service 8aa27d
            goto err;
Packit Service 8aa27d
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE);
Packit 8681c6
    key_type_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
Packit 8681c6
    class_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
Packit 8681c6
    local_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
Packit 8681c6
Packit 8681c6
    if (!value_attr || !key_type_attr || !class_attr || !local_attr) {
Packit 8681c6
        if (value_attr)
Packit 8681c6
            free(value_attr);
Packit 8681c6
        if (key_type_attr)
Packit 8681c6
            free(key_type_attr);
Packit 8681c6
        if (class_attr)
Packit 8681c6
            free(class_attr);
Packit 8681c6
        if (local_attr)
Packit 8681c6
            free(local_attr);
Packit 8681c6
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
        rc = CKR_HOST_MEMORY;
Packit 8681c6
        goto err;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    value_attr->type = CKA_VALUE;
Packit 8681c6
    value_attr->ulValueLen = DES_KEY_SIZE;
Packit 8681c6
    value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
Packit Service 8aa27d
    if (is_opaque)
Packit Service 8aa27d
        memset(value_attr->pValue, 0, DES_KEY_SIZE);
Packit 8681c6
    else
Packit 8681c6
        memcpy(value_attr->pValue, des_key, DES_KEY_SIZE);
Packit 8681c6
    free(des_key);
Packit 8681c6
Packit 8681c6
    key_type_attr->type = CKA_KEY_TYPE;
Packit 8681c6
    key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
Packit 8681c6
    key_type_attr->pValue = (CK_BYTE *) key_type_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_KEY_TYPE *) key_type_attr->pValue = CKK_DES;
Packit 8681c6
Packit 8681c6
    class_attr->type = CKA_CLASS;
Packit 8681c6
    class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
Packit 8681c6
    class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
Packit 8681c6
Packit 8681c6
    local_attr->type = CKA_LOCAL;
Packit 8681c6
    local_attr->ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_BBOOL *) local_attr->pValue = TRUE;
Packit 8681c6
Packit 8681c6
    template_update_attribute(tmpl, value_attr);
Packit 8681c6
    template_update_attribute(tmpl, key_type_attr);
Packit 8681c6
    template_update_attribute(tmpl, class_attr);
Packit 8681c6
    template_update_attribute(tmpl, local_attr);
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
Packit 8681c6
err:
Packit 8681c6
    if (des_key)
Packit 8681c6
        free(des_key);
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
#if !(NOCDMF)
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_cdmf_key_gen(STDLL_TokData_t *tokdata, TEMPLATE *tmpl)
Packit 8681c6
{
Packit 8681c6
    CK_ATTRIBUTE *value_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *key_type_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *class_attr = NULL;
Packit 8681c6
    CK_ATTRIBUTE *local_attr = NULL;
Packit 8681c6
    CK_BYTE cdmf_key[DES_KEY_SIZE];
Packit 8681c6
    CK_ULONG repl_len, expected_repl_len;
Packit 8681c6
    CK_ULONG rc;
Packit 8681c6
Packit 8681c6
    repl_len = expected_repl_len = DES_KEY_SIZE;
Packit 8681c6
Packit 8681c6
    rc = communicate(PK_CDMF_KEYGEN,
Packit 8681c6
                     NULL, 0, cdmf_key, &repl_len, NULL, 0, NULL, 0);
Packit 8681c6
Packit 8681c6
    if (rc == CKR_OK) {
Packit 8681c6
        if (repl_len != expected_repl_len)
Packit 8681c6
            return CKR_GENERAL_ERROR;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE);
Packit 8681c6
    key_type_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
Packit 8681c6
    class_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
Packit 8681c6
    local_attr =
Packit 8681c6
        (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
Packit 8681c6
Packit 8681c6
    if (!value_attr || !key_type_attr || !class_attr || !local_attr) {
Packit 8681c6
        if (value_attr)
Packit 8681c6
            free(value_attr);
Packit 8681c6
        if (key_type_attr)
Packit 8681c6
            free(key_type_attr);
Packit 8681c6
        if (class_attr)
Packit 8681c6
            free(class_attr);
Packit 8681c6
        if (local_attr)
Packit 8681c6
            free(local_attr);
Packit 8681c6
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
        return CKR_HOST_MEMORY;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    value_attr->type = CKA_VALUE;
Packit 8681c6
    value_attr->ulValueLen = DES_KEY_SIZE;
Packit 8681c6
    value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    memcpy(value_attr->pValue, cdmf_key, DES_KEY_SIZE);
Packit 8681c6
Packit 8681c6
    key_type_attr->type = CKA_KEY_TYPE;
Packit 8681c6
    key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
Packit 8681c6
    key_type_attr->pValue = (CK_BYTE *) key_type_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_KEY_TYPE *) key_type_attr->pValue = CKK_CDMF;
Packit 8681c6
Packit 8681c6
    class_attr->type = CKA_CLASS;
Packit 8681c6
    class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
Packit 8681c6
    class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
Packit 8681c6
Packit 8681c6
    local_attr->type = CKA_LOCAL;
Packit 8681c6
    local_attr->ulValueLen = sizeof(CK_BBOOL);
Packit 8681c6
    local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
Packit 8681c6
    *(CK_BBOOL *) local_attr->pValue = TRUE;
Packit 8681c6
Packit 8681c6
    template_update_attribute(tmpl, value_attr);
Packit 8681c6
    template_update_attribute(tmpl, key_type_attr);
Packit 8681c6
    template_update_attribute(tmpl, class_attr);
Packit 8681c6
    template_update_attribute(tmpl, local_attr);
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
#endif
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_ecb_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)
Packit 8681c6
{
Packit 8681c6
    CK_ULONG rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!in_data || !out_data || !key) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        return CKR_BUFFER_TOO_SMALL;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (token_specific.t_des_ecb == NULL) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
    }
Packit 8681c6
    rc = token_specific.t_des_ecb(tokdata, in_data, in_data_len,
Packit 8681c6
                                  out_data, out_data_len, key, 1);
Packit 8681c6
Packit 8681c6
    if (rc != CKR_OK)
Packit 8681c6
        TRACE_DEVEL("Token specific des_ecb encrypt failed.\n");
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_ecb_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)
Packit 8681c6
{
Packit 8681c6
    CK_ULONG rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!in_data || !out_data || !key) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        return CKR_BUFFER_TOO_SMALL;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (token_specific.t_des_ecb == NULL) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
    }
Packit 8681c6
    rc = token_specific.t_des_ecb(tokdata, in_data, in_data_len, out_data,
Packit 8681c6
                                  out_data_len, key, 0);
Packit 8681c6
    if (rc != CKR_OK)
Packit 8681c6
        TRACE_ERROR("Token specific des ecb decrypt failed.\n");
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_cbc_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,
Packit 8681c6
                          CK_BYTE *init_v, OBJECT *key)
Packit 8681c6
{
Packit 8681c6
    CK_ULONG rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!in_data || !out_data || !init_v || !key) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        *out_data_len = in_data_len;
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        return CKR_BUFFER_TOO_SMALL;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (token_specific.t_des_cbc == NULL) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
    }
Packit 8681c6
    rc = token_specific.t_des_cbc(tokdata, in_data, in_data_len, out_data,
Packit 8681c6
                                  out_data_len, key, init_v, 1);
Packit 8681c6
Packit 8681c6
    if (rc != CKR_OK)
Packit 8681c6
        TRACE_ERROR("Token specific dec cbc encrypt failed.\n");
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
//
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_cbc_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,
Packit 8681c6
                          CK_BYTE *init_v, OBJECT *key)
Packit 8681c6
{
Packit 8681c6
    CK_ULONG rc;
Packit 8681c6
Packit 8681c6
Packit 8681c6
    if (!in_data || !out_data || !init_v || !key) {
Packit 8681c6
        TRACE_ERROR("%s received bad argument(s)\n", __func__);
Packit 8681c6
        return CKR_FUNCTION_FAILED;
Packit 8681c6
    }
Packit 8681c6
    if (*out_data_len < in_data_len) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
Packit 8681c6
        return CKR_BUFFER_TOO_SMALL;
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    if (token_specific.t_des_cbc == NULL) {
Packit 8681c6
        TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
Packit 8681c6
        return CKR_MECHANISM_INVALID;
Packit 8681c6
    }
Packit 8681c6
    rc = token_specific.t_des_cbc(tokdata, in_data, in_data_len, out_data,
Packit 8681c6
                                  out_data_len, key, init_v, 0);
Packit 8681c6
Packit 8681c6
    if (rc != CKR_OK)
Packit 8681c6
        TRACE_ERROR("Token specific des cbc decrypt failed.\n");
Packit 8681c6
Packit 8681c6
    return rc;
Packit 8681c6
}
Packit 8681c6
Packit 8681c6
Packit 8681c6
// we're preparing to wrap a key using DES.  need to make sure the
Packit 8681c6
// data length is a integral multiple of the DES block size.
Packit 8681c6
//
Packit 8681c6
// PKCS #11 specifies that the padding shall be in the form of NULL
Packit 8681c6
// bytes appended to the data
Packit 8681c6
//
Packit 8681c6
// this routine works with either DES and 3DES as the wrapping mechanism
Packit 8681c6
//
Packit 8681c6
CK_RV ckm_des_wrap_format(STDLL_TokData_t *tokdata,
Packit 8681c6
                          CK_BBOOL length_only,
Packit 8681c6
                          CK_BYTE **data, CK_ULONG *data_len)
Packit 8681c6
{
Packit 8681c6
    CK_BYTE *ptr = NULL;
Packit 8681c6
    CK_ULONG len1, len2;
Packit 8681c6
Packit 8681c6
    UNUSED(tokdata);
Packit 8681c6
Packit 8681c6
    len1 = *data_len;
Packit 8681c6
    if (*data == NULL)
Packit 8681c6
        len1 = 0;
Packit 8681c6
Packit 8681c6
    // if the input key data isn't a multiple of the blocksize,
Packit 8681c6
    // we pad with NULLs to the next blocksize multiple.
Packit 8681c6
    //
Packit 8681c6
    if (len1 % DES_BLOCK_SIZE != 0) {
Packit 8681c6
        len2 = DES_BLOCK_SIZE * ((len1 / DES_BLOCK_SIZE) + 1);
Packit 8681c6
Packit 8681c6
        if (length_only == FALSE) {
Packit 8681c6
            /*
Packit 8681c6
             * Don't use realloc here, since the buffer contains a key and the
Packit 8681c6
             * old buffer needs to be cleansed before it is freed.
Packit 8681c6
             */
Packit 8681c6
            ptr = (CK_BYTE *)malloc(len2);
Packit 8681c6
            if (!ptr) {
Packit 8681c6
                TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
Packit 8681c6
                return CKR_HOST_MEMORY;
Packit 8681c6
            }
Packit 8681c6
Packit 8681c6
            memset(ptr + len1, 0x0, (len2 - len1));
Packit 8681c6
            if (*data != NULL) {
Packit 8681c6
                memcpy(ptr, *data, len1);
Packit 8681c6
                OPENSSL_cleanse(*data, len1);
Packit 8681c6
                free(*data);
Packit 8681c6
            }
Packit 8681c6
Packit 8681c6
            *data = ptr;
Packit 8681c6
            *data_len = len2;
Packit 8681c6
        }
Packit 8681c6
    }
Packit 8681c6
Packit 8681c6
    return CKR_OK;
Packit 8681c6
}