📄 ica_specific.c
字号:
* pieces because we need to cache the last 64 bytes so that * we're not stuck with 0 bytes when the MSG_PART_FINAL * comes in. - KEY */ if (!(in_data_len % 64)) { oc_sha_ctx->tail_len = 64; memcpy(oc_sha_ctx->tail, in_data + in_data_len - 64, 64); in_data_len -= 64; } else oc_sha_ctx->tail_len = in_data_len & 0x3f; if( oc_sha_ctx->tail_len < 64) { in_data_len &= ~0x3f; memcpy(oc_sha_ctx->tail, in_data + in_data_len, oc_sha_ctx->tail_len); } } } } else { /* ctx->multi == FALSE, but we've run previously. That's * our signal that this is the last part -KEY */ if( ica_sha_ctx->runningLength > 0 ) oc_sha_ctx->message_part = SHA_MSG_PART_FINAL; else oc_sha_ctx->message_part = SHA_MSG_PART_ONLY; } if( in_data_len || oc_sha_ctx->message_part == SHA_MSG_PART_FINAL ) { if( icaSha1( adapter_handle, (unsigned int)oc_sha_ctx->message_part, (unsigned int)in_data_len, in_data + fill_size, (unsigned int)LENGTH_SHA_CONTEXT, ica_sha_ctx, &oc_sha_ctx->hash_len, oc_sha_ctx->hash)) return CKR_FUNCTION_FAILED; } return CKR_OK;}CK_RVtoken_specific_sha_final( DIGEST_CONTEXT *ctx, CK_BYTE *out_data, CK_ULONG *out_data_len ){ CK_RV rv = CKR_OK; oc_sha1_ctx *oc_sha_ctx = (oc_sha1_ctx *)ctx->context; int copy_len = MIN(*out_data_len, LENGTH_SHA_HASH); if( !ctx ) return CKR_OPERATION_NOT_INITIALIZED; if( !out_data || (*out_data_len < LENGTH_SHA_HASH) ) return CKR_FUNCTION_FAILED; if( oc_sha_ctx->message_part != SHA_MSG_PART_FINAL && oc_sha_ctx->message_part != SHA_MSG_PART_ONLY) { /* Finalize the SHA operation; tell update that this multi-part * operation is done. -KEY */ ctx->multi = FALSE; token_specific_sha_update(ctx, oc_sha_ctx->tail, oc_sha_ctx->tail_len); } memcpy(out_data, oc_sha_ctx->hash, copy_len); *out_data_len = copy_len; /* ctx->context is freed inside digest_mgr_cleanup - KEY */ free(oc_sha_ctx->dev_ctx); return rv;}#ifndef NOAES/* If you'd like openssl AES support, install opensl 0.9.7, edit * usr/lib/pkcs11/ica_stdll/Makefile.am and remove the -DNOAES CFLAG. - KEY */CK_RVtoken_specific_aes_key_gen( CK_BYTE *key, CK_ULONG len ){ return rng_generate(key, len);}CK_RVtoken_specific_aes_ecb( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE encrypt){ AES_KEY ssl_aes_key; int i; /* There's a previous check that in_data_len % AES_BLOCK_SIZE == 0, * so this is fine */ CK_ULONG loops = (CK_ULONG)(in_data_len/AES_BLOCK_SIZE); memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_ecb_encrypt encrypts only a single block, so we have to break up the // input data here if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; i<loops; i++ ) { AES_ecb_encrypt((unsigned char *)in_data + (i*AES_BLOCK_SIZE), (unsigned char *)out_data + (i*AES_BLOCK_SIZE), &ssl_aes_key, AES_ENCRYPT); } } else { AES_set_decrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); for( i=0; i<loops; i++ ) { AES_ecb_encrypt((unsigned char *)in_data + (i*AES_BLOCK_SIZE), (unsigned char *)out_data + (i*AES_BLOCK_SIZE), &ssl_aes_key, AES_DECRYPT); } } *out_data_len = in_data_len; return CKR_OK;}CK_RVtoken_specific_aes_cbc( CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len, CK_BYTE *key_value, CK_ULONG key_len, CK_BYTE *init_v, CK_BYTE encrypt){ AES_KEY ssl_aes_key; int i; memset( &ssl_aes_key, 0, sizeof(AES_KEY)); // AES_cbc_encrypt chunks the data into AES_BLOCK_SIZE blocks, unlike // AES_ecb_encrypt, so no looping required. if (encrypt) { AES_set_encrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); AES_cbc_encrypt((unsigned char *)in_data, (unsigned char *)out_data, in_data_len, &ssl_aes_key, init_v, AES_ENCRYPT); } else { AES_set_decrypt_key((unsigned char *)key_value, (key_len*8), &ssl_aes_key); AES_cbc_encrypt((unsigned char *)in_data, (unsigned char *)out_data, in_data_len, &ssl_aes_key, init_v, AES_DECRYPT); } *out_data_len = in_data_len; return CKR_OK;}#endif#ifndef NODH// This computes DH shared secret, where:// Output: z is computed shared secret// Input: y is other party's public key// x is private key// p is prime// All length's are in number of bytes. All data comes in as Big Endian. CK_RVtoken_specific_dh_pkcs_derive( CK_BYTE *z, CK_ULONG *z_len, CK_BYTE *y, CK_ULONG y_len, CK_BYTE *x, CK_ULONG x_len, CK_BYTE *p, CK_ULONG p_len){ CK_RV rc ; BIGNUM *bn_z, *bn_y, *bn_x, *bn_p ; BN_CTX *ctx; // Create and Init the BIGNUM structures. bn_y = BN_new() ; bn_x = BN_new() ; bn_p = BN_new() ; bn_z = BN_new() ; if (bn_z == NULL || bn_p == NULL || bn_x == NULL || bn_y == NULL) { if (bn_y) BN_free(bn_y); if (bn_x) BN_free(bn_x); if (bn_p) BN_free(bn_p); if (bn_z) BN_free(bn_z); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_y) ; BN_init(bn_x) ; BN_init(bn_p) ; // Initialize context ctx=BN_CTX_new(); if (ctx == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Add data into these new BN structures BN_bin2bn((char *)y, y_len, bn_y); BN_bin2bn((char *)x, x_len, bn_x); BN_bin2bn((char *)p, p_len, bn_p); rc = BN_mod_exp(bn_z,bn_y,bn_x,bn_p,ctx); if (rc == 0) { BN_free(bn_z); BN_free(bn_y); BN_free(bn_x); BN_free(bn_p); BN_CTX_free(ctx); st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } *z_len = BN_num_bytes(bn_z); BN_bn2bin(bn_z, z); BN_free(bn_z); BN_free(bn_y); BN_free(bn_x); BN_free(bn_p); BN_CTX_free(ctx); return CKR_OK; } /* end token_specific_dh_pkcs_derive() */ // This computes DH key pair, where:// Output: priv_tmpl is generated private key// pub_tmpl is computed public key// Input: pub_tmpl is public key (prime and generator)// All length's are in number of bytes. All data comes in as Big Endian.CK_RVtoken_specific_dh_pkcs_key_pair_gen( TEMPLATE * publ_tmpl, TEMPLATE * priv_tmpl ){ CK_BBOOL rc; CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *temp_attr = NULL ; CK_ATTRIBUTE *value_bits_attr = NULL; CK_BYTE *temp_byte; CK_ULONG temp_bn_len ; DH *dh ; BIGNUM *bn_p ; BIGNUM *bn_g ; BIGNUM *temp_bn ; rc = template_attribute_find( publ_tmpl, CKA_PRIME, &prime_attr ); rc &= template_attribute_find( publ_tmpl, CKA_BASE, &base_attr ); if (rc == FALSE) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } if ((prime_attr->ulValueLen > 256) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } dh = DH_new() ; if (dh == NULL) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Create and init BIGNUM structs to stick in the DH struct bn_p = BN_new(); bn_g = BN_new(); if (bn_g == NULL || bn_p == NULL) { if (bn_g) BN_free(bn_g); if (bn_p) BN_free(bn_p); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } BN_init(bn_p); BN_init(bn_g); // Convert from strings to BIGNUMs and stick them in the DH struct BN_bin2bn((char *)prime_attr->pValue, prime_attr->ulValueLen, bn_p); dh->p = bn_p; BN_bin2bn((char *)base_attr->pValue, base_attr->ulValueLen, bn_g); dh->g = bn_g; // Generate the DH Key if (!DH_generate_key(dh)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Extract the public and private key components from the DH struct, // and insert them in the publ_tmpl and priv_tmpl // // pub_key // //temp_bn = BN_new(); temp_bn = dh->pub_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( publ_tmpl, temp_attr ); free(temp_byte); // // priv_key // //temp_bn = BN_new(); temp_bn = dh->priv_key; temp_bn_len = BN_num_bytes(temp_bn); temp_byte = malloc(temp_bn_len); temp_bn_len = BN_bn2bin(temp_bn, temp_byte); rc = build_attribute( CKA_VALUE, temp_byte, temp_bn_len, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); free(temp_byte); // Update CKA_VALUE_BITS attribute in the private key value_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); value_bits_attr->type = CKA_VALUE_BITS; value_bits_attr->ulValueLen = sizeof(CK_ULONG); value_bits_attr->pValue = (CK_BYTE *)value_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)value_bits_attr->pValue = 8*temp_bn_len; template_update_attribute( priv_tmpl, value_bits_attr ); // Add prime and base to the private key template rc = build_attribute( CKA_PRIME,(char *)prime_attr->pValue, prime_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); rc = build_attribute( CKA_BASE,(char *)base_attr->pValue, base_attr->ulValueLen, &temp_attr ); // in bytes if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); return CKR_FUNCTION_FAILED; } template_update_attribute( priv_tmpl, temp_attr ); // Cleanup DH key DH_free(dh) ; return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -