📄 aeptok_specific.c
字号:
/*************************************************//* AEP Token Implementation. *//* Currently it uses openssl's libcrypto.so *//* for DES, 3DES and key generation. *//* Modular Exponentiation (RSA encrypt/decrypt) *//* is done in hardware. *//*************************************************/#include <pthread.h>#include <string.h>#include <stdlib.h>#include "pkcs11types.h"#include "defs.h"#include "host_defs.h"#include "h_extern.h"#include "args.h"#include "errno.h"#include "tok_specific.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <openssl/des.h>#include <openssl/rand.h>#include <openssl/rsa.h>#ifndef NOAES#include <openssl/aes.h>#endif#ifndef NODH#include <openssl/dh.h>#endiftypedef unsigned int uint32_t;pthread_mutex_t rngmtx = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t nextmutex = PTHREAD_MUTEX_INITIALIZER;unsigned int rnginitialized=0;CK_CHAR manuf[] = "IBM Corp.";CK_CHAR model[] = "IBM AEPToken";CK_CHAR descr[] = "IBM PKCS#11 AEP token";CK_CHAR label[] = "AEP OS PKCS#11 ";/* variable indicating if AEP hardware is available */int cryptoki_aep_avail = TRUE;/* max length of modulae which can be handled by the card */static int max_key_len = 2176;CK_RVtoken_specific_session(CK_SLOT_ID slotid){ return CKR_OK;}CK_RVtoken_rng(CK_BYTE *output, CK_ULONG bytes){#if 0 int bytes2 = 384; char state[bytes2]; pthread_mutex_lock(&rngmtx); if (!rnginitialized) { RAND_seed(&state, bytes2); rnginitialized=1; } RAND_pseudo_bytes(output, bytes); pthread_mutex_unlock(&rngmtx);#else int ranfd; int rlen,totallen=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { rlen = read(ranfd,output+totallen,bytes-totallen); totallen += rlen; } while( totallen < bytes); return CKR_OK; } else { return CKR_FUNCTION_FAILED; } #endif}// convert pkcs slot number to local representationinttok_slot2local(CK_SLOT_ID snum){ return 1; }CK_RVtoken_specific_init(char * Correlator,CK_SLOT_ID SlotNumber){ return CKR_OK;}CK_RVtoken_specific_final(){ return CKR_OK;}CK_RVtoken_specific_des_key_gen(CK_BYTE *des_key,CK_ULONG len){ // Nothing different to do for DES or TDES here as this is just // random data... Validation handles the rest rng_generate(des_key,len); // we really need to validate the key for parity etc... // we should do that here... The caller validates the single des keys // against the known and suspected poor keys.. return CKR_OK;}CK_RVtoken_specific_des_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt){ CK_ULONG rc; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; int i,j; int ret; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); // the des decrypt will only fail if the data length is not // evenly divisible by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Both the encrypt and the decrypt are done 8 bytes at a time if (encrypt) { for (i=0; i<in_data_len; i=i+8) { memcpy(in_key_data, in_data+i, 8); des_ecb_encrypt(&in_key_data, &out_key_data, des_key2, DES_ENCRYPT); memcpy(out_data+i, out_key_data, 8); } *out_data_len = in_data_len; rc = CKR_OK; } else { for(j=0; j < in_data_len; j=j+8) { memcpy(in_key_data, in_data+j, 8); des_ecb_encrypt(&in_key_data, &out_key_data, des_key2, DES_DECRYPT); memcpy(out_data+j, out_key_data, 8); } *out_data_len = in_data_len; rc = CKR_OK; } return rc;}CK_RVtoken_specific_des_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt){ CK_ULONG rc; des_cblock ivec; int ret; des_key_schedule des_key2; const_des_cblock key_val_SSL, in_key_data; des_cblock out_key_data; // Create the key schedule memcpy(&key_val_SSL, key_value, 8); des_set_key_unchecked(&key_val_SSL, des_key2); memcpy(&ivec, init_v, 8); // the des decrypt will only fail if the data length is not // evenly divisible by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } if ( encrypt){ des_ncbc_encrypt(in_data, out_data, in_data_len, des_key2, &ivec, DES_ENCRYPT); *out_data_len = in_data_len; rc = CKR_OK; } else { des_ncbc_encrypt(in_data, out_data, in_data_len, des_key2, &ivec, DES_DECRYPT); *out_data_len = in_data_len; rc = CKR_OK; } return rc;}CK_RVtoken_specific_tdes_ecb(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE encrypt){ CK_RV rc; int k,j, ret; des_cblock out_temp; des_key_schedule des_key1; des_key_schedule des_key2; des_key_schedule des_key3; const_des_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data; des_cblock out_key_data; // The key as passed is a 24 byte long string containing three des keys // pick them apart and create the 3 corresponding key schedules memcpy(&key_SSL1, key_value, 8); memcpy(&key_SSL2, key_value+8, 8); memcpy(&key_SSL3, key_value+16, 8); des_set_key_unchecked(&key_SSL1, des_key1); des_set_key_unchecked(&key_SSL2, des_key2); des_set_key_unchecked(&key_SSL3, des_key3); // the des decrypt will only fail if the data length is not // evenly divisible by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // the encrypt and decrypt are done 8 bytes at a time if (encrypt) { for(k=0;k<in_data_len;k=k+8){ memcpy(in_key_data, in_data+k, 8); des_ecb3_encrypt(&in_key_data, &out_key_data, des_key1, des_key2, des_key3, DES_ENCRYPT); memcpy(out_data+k, out_key_data, 8); } *out_data_len = in_data_len; rc = CKR_OK; } else { for (j=0;j<in_data_len;j=j+8){ memcpy(in_key_data, in_data+j, 8); des_ecb3_encrypt(&in_key_data, &out_key_data, des_key1, des_key2, des_key3, DES_DECRYPT); memcpy(out_data+j, out_key_data, 8); } *out_data_len = in_data_len; rc = CKR_OK; } return rc;}CK_RVtoken_specific_tdes_cbc(CK_BYTE * in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_BYTE *init_v, CK_BYTE encrypt){ CK_RV rc = CKR_OK; des_key_schedule des_key1; des_key_schedule des_key2; des_key_schedule des_key3; const_des_cblock key_SSL1, key_SSL2, key_SSL3, in_key_data; des_cblock ivec; // The key as passed in is a 24 byte string containing 3 keys // pick it apart and create the key schedules memcpy(&key_SSL1, key_value, 8); memcpy(&key_SSL2, key_value+8, 8); memcpy(&key_SSL3, key_value+16, 8); des_set_key_unchecked(&key_SSL1, des_key1); des_set_key_unchecked(&key_SSL2, des_key2); des_set_key_unchecked(&key_SSL3, des_key3); memcpy(ivec, init_v, sizeof(ivec)); // the des decrypt will only fail if the data length is not // evenly divisible by 8 if (in_data_len % 8 ){ st_err_log(11, __FILE__, __LINE__); return CKR_DATA_LEN_RANGE; } // Encrypt or decrypt the data if (encrypt){ des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_ENCRYPT); *out_data_len = in_data_len; rc = CKR_OK; } else { des_ede3_cbc_encrypt(in_data, out_data, in_data_len, des_key1, des_key2, des_key3, &ivec, DES_DECRYPT); *out_data_len = in_data_len; rc = CKR_OK; } return rc;}// convert from the local PKCS11 template representation to// the underlying requirement// returns the pointer to the local key representationvoid *rsa_convert_public_key( OBJECT * key_obj , int * mLen){ CK_BBOOL rc; CK_ATTRIBUTE * modulus = NULL; CK_ATTRIBUTE * pub_exp = NULL; RSA *rsa; BIGNUM *bn_mod, *bn_exp; rc = template_attribute_find( key_obj->template, CKA_MODULUS, &modulus ); rc &= template_attribute_find( key_obj->template, CKA_PUBLIC_EXPONENT, &pub_exp ); if (rc == FALSE) { return NULL; } // Create an RSA key struct to return rsa = RSA_new(); if (rsa == NULL) return NULL; RSA_blinding_off(rsa); // Create and init BIGNUM structs to stick in the RSA struct bn_mod = BN_new(); if (bn_mod == NULL) { RSA_free(rsa); return NULL; } bn_exp = BN_new(); if (bn_exp == NULL) { RSA_free(rsa); BN_free(bn_mod); return NULL; } BN_init(bn_mod); BN_init(bn_exp); // Convert from strings to BIGNUMs and stick them in the RSA struct BN_bin2bn((char *)modulus->pValue, modulus->ulValueLen, bn_mod); rsa->n = bn_mod; BN_bin2bn((char *)pub_exp->pValue, pub_exp->ulValueLen, bn_exp); rsa->e = bn_exp; /* get the length of modulus for the modexp operation */ *mLen = BN_num_bits(rsa->n); return (void *)rsa;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -