📄 bcom_specific.c
字号:
#include <pthread.h>#include <string.h> // for memcmp() et al#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 "tok_struct.h"#if 0#include <openssl/des.h>#include <openssl/rand.h>#include <openssl/rsa.h>#endif#ifndef NOAES#include <openssl/aes.h>#endif#ifndef NODH#include <openssl/dh.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>// SAB Bcom Add#include "ubsio.h"//#include "unix_wrap.h"#include "ubsec.h"#include "ubsec_lib.h"// SAB end Bcom Addtypedef unsigned int U32_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 BComHack";CK_CHAR descr[] = "IBM PKCS#11 Bcom token";CK_CHAR label[] = "IBM OS PKCS#11 ";/* Broadcom needs a non null pointer even for keys it doesn't use */unsigned char ZERO_KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/* Broadcom only implements CBC mode, to do ECB we need a zero IV */unsigned char ZERO_IV[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#include <stdio.h>int bcomfd; // SAB FIXME Broadcom adapter file descriptorvoid bignum_swapper(char *s, char *d, int size);void swapper(char *s, char *d, int size);CK_RVtoken_specific_session(CK_SLOT_ID slotid){ return CKR_OK;}CK_RVtoken_rng(CK_BYTE *output, CK_ULONG bytes){#if 1int bits = 0;int rc = 1; bits = bytes*8; rc = rng_ioctl(bcomfd, UBSEC_RNG_SHA1, output, &bits); if ( rc != 0) { return CKR_FUNCTION_FAILED; } return CKR_OK;#else /* XXX change this to call Broadcom randomness */ int ranfd; int r_len,total_len=0; ranfd = open("/dev/urandom",O_RDONLY); if (ranfd >= 0 ){ do { r_len = read(ranfd,output+total_len,bytes-total_len); total_len += r_len; } while( total_len < 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){ bcomfd = ubsec_open(UBSEC_KEY_DEVICE); return CKR_OK;}CK_RVtoken_specific_final(){ ubsec_close(bcomfd); 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; unsigned char in_block_data[8]; unsigned char out_block_data[8]; int i,j; int ret; ubsec_crypto_context_t ctx; // Initialize the crypto contexte ubsec_crypto_init(key_value, ZERO_KEY, ZERO_KEY, ZERO_KEY, UBSEC_DES, 0, &ctx); // 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__); rc = CKR_DATA_LEN_RANGE; goto done; } // Do the encryption or decryption // Broadcom only does CBC DES, so to do ECB we need to go DES block // by DES block, with IV = 0 if (encrypt) { for (i=0; i<in_data__len; i=i+8) { memcpy(in_block_data, in_data+i, 8); if ( 0 != ubsec_crypto_data_ioctl(bcomfd, UBSEC_ENCODE, &ctx, in_block_data, ZERO_IV, 8, 0, out_block_data, 8, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } memcpy(out_data+i, out_block_data, 8); } } else { for(j=0; j < in_data__len; j=j+8) { memcpy(in_block_data, in_data+j, 8); if ( 0 != ubsec_crypto_data_ioctl(bcomfd, UBSEC_DECODE, &ctx, in_block_data, ZERO_IV, 8, 0, out_block_data, 8, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } memcpy(out_data+j, out_block_data, 8); } } *out_data__len = in_data__len; rc = CKR_OK; done: ubsec_crypto_done(&ctx); 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; int ret; ubsec_crypto_context_t ctx; // Initialize the crypto contexte ubsec_crypto_init(key_value, ZERO_KEY, ZERO_KEY, ZERO_KEY, UBSEC_DES, 0, &ctx); // 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__); rc = CKR_DATA_LEN_RANGE; goto done; } // Do the encryption or decryption *out_data__len = in_data__len; if ( 0 != ubsec_crypto_data_ioctl(bcomfd, encrypt?UBSEC_ENCODE:UBSEC_DECODE, &ctx, in_data, init_v, in_data__len, 0, out_data, *out_data__len, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: ubsec_crypto_done(&ctx); 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_ULONG rc; unsigned char in_block_data[8]; unsigned char out_block_data[8]; int i,j; int ret; ubsec_crypto_context_t ctx; // Initialize the crypto contexte // the triple DES key is in the 24-byte array key_value ubsec_crypto_init(key_value, key_value+8, key_value+16, ZERO_KEY, UBSEC_3DES, 0, &ctx); // 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__); rc = CKR_DATA_LEN_RANGE; goto done; } // Do the encryption or decryption // Broadcom only does CBC DES, so to do ECB we need to go DES block by DES // block, with IV = 0 if (encrypt) { for (i=0; i<in_data__len; i=i+8) { memcpy(in_block_data, in_data+i, 8); if ( 0 != ubsec_crypto_data_ioctl(bcomfd, UBSEC_ENCODE, &ctx, in_block_data, ZERO_IV, 8, 0, out_block_data, 8, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } memcpy(out_data+i, out_block_data, 8); } } else { for(j=0; j < in_data__len; j=j+8) { memcpy(in_block_data, in_data+j, 8); if ( 0 != ubsec_crypto_data_ioctl(bcomfd, UBSEC_DECODE, &ctx, in_block_data, ZERO_IV, 8, 0, out_block_data, 8, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } memcpy(out_data+j, out_block_data, 8); } } *out_data__len = in_data__len; rc = CKR_OK; done: ubsec_crypto_done(&ctx); 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_ULONG rc; int ret; ubsec_crypto_context_t ctx; // Initialize the crypto contexte // Triple DES key is in the 24-byte array key_value ubsec_crypto_init(key_value, key_value+8, key_value+16, ZERO_KEY, UBSEC_3DES, 0, &ctx); // 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__); rc = CKR_DATA_LEN_RANGE; goto done; } // Do the encryption or decryption *out_data__len = in_data__len; if ( 0 != ubsec_crypto_data_ioctl(bcomfd, encrypt?UBSEC_ENCODE:UBSEC_DECODE, &ctx, in_data, init_v, in_data__len, 0, out_data, *out_data__len, NULL) ) { rc = CKR_FUNCTION_FAILED; goto done; } rc = CKR_OK; done: ubsec_crypto_done(&ctx); return rc;}#define RNG_BUF_SIZE 100// This function is only required if public key cryptography// has been selected in your variant set up.// Set a mutex in this function and get a cache;// using the ICA device to get random numbers a byte at a// time is VERY slow.. Keygen is gated by this function.unsigned charnextRandom (void) { static unsigned char buffer[RNG_BUF_SIZE]; unsigned char byte; static int used = (RNG_BUF_SIZE); // protected access by the mutex pthread_mutex_lock(&nextmutex); if (used >= RNG_BUF_SIZE){ rng_generate(buffer,sizeof(buffer)); used = 0; } byte = buffer[used++]; pthread_mutex_unlock(&nextmutex); return((unsigned char)byte);}void swapper(char *s, char *d, int size){ int i=0; int j=size; for(i=0;i<size;i++) d[i]=s[--j];}/* * if we swapp a number that looks like XYZ0..0, * we don't want to get 0..0ZYX, we want ZYX0..0 */void bignum_swapper(char *s, char *d, int size){ int i; i = size -1; while (s[i] == 0x00) { d[i] = 0x00; i--; } swapper(s, d, i + 1);} CK_RV build_swapped_attribute(CK_ATTRIBUTE_TYPE type, CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attrib){ CK_BYTE *swapped_data; CK_RV rv; CK_ULONG pos; CK_ULONG real_data_len; swapped_data = (unsigned char *)malloc(data_len); if (! swapped_data) { return CKR_DEVICE_ERROR; } bzero(swapped_data, data_len); real_data_len = data_len; pos = data_len -1; while (data[pos--] == 0x00) { real_data_len--; } swapper(data, swapped_data, real_data_len); rv = build_attribute(type, swapped_data, data_len, attrib); if (swapped_data) { free(swapped_data); } return rv;}typedef struct BCOM_RSA_PUB_KEY_s { U32_t *n; unsigned int n_len; U32_t *e; unsigned int e_len;} BCOM_RSA_PUB_KEY_t;typedef struct BCOM_RSA_CRT_KEY_s { U32_t *n; /* modulo */ unsigned int n_len; U32_t *p; /* prime p */ unsigned int p_len; U32_t *q; /* prime q */ unsigned int q_len; U32_t *d; /* private decryption exponent */ unsigned int d_len; U32_t *dp; /* CRT exp1 */ unsigned int dp_len; U32_t *dq; /* CRT exp2 */ unsigned int dq_len; U32_t *pinv; /* CRT Coeff */ unsigned int pinv_len;} BCOM_RSA_CRT_KEY_t;int bcom_rsa_pub_new(BCOM_RSA_PUB_KEY_t **out_rsa_pub){ int rc = -1; BCOM_RSA_PUB_KEY_t *rsa_pub; rsa_pub = (BCOM_RSA_PUB_KEY_t *)malloc(sizeof(BCOM_RSA_PUB_KEY_t)); if (! rsa_pub) { goto error; } rsa_pub->n = (U32_t *)malloc(MAX_PUBLIC_KEY_BYTES*sizeof(unsigned char)); bzero(rsa_pub->n, MAX_PUBLIC_KEY_BYTES);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -