Blame usr/lib/common/mech_dh.c

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