📄 cr_specific.c
字号:
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;}#ifndef NOAESCK_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// 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 ret_val ; RC rc ; token z_tok, y_tok, x_tok, p_tok ; // Setup the tokens with values from the input params z_tok.p_data = z ; z_tok.data_size = p_len ; y_tok.p_data = y ; y_tok.data_size = y_len ; x_tok.p_data = x ; x_tok.data_size = x_len ; p_tok.p_data = p ; p_tok.data_size = p_len ; // Perform: z = y^x mod p rc = CR_mod_exp_mont(&z_tok, &y_tok, &p_tok, &x_tok) ; if ( rc == SUCCESS ) ret_val = CKR_OK; else { ret_val = CKR_FUNCTION_FAILED; st_err_log(4, __FILE__, __LINE__); } /* Corrent library may return results after triming leading zeros. Insert the leading zeros back and adjust length below, if necessary */ if (z_tok.data_size < p_len) { memmove(z+(p_len-z_tok.data_size), z, z_tok.data_size) ; memset(z, 0, p_len-z_tok.data_size) ; z_tok.data_size = p_len ; } *z_len = z_tok.data_size ; return ret_val; } /* 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 ){ RC rc; CK_ATTRIBUTE *prime_attr = NULL; CK_ATTRIBUTE *base_attr = NULL; CK_ATTRIBUTE *temp_attr = NULL ; CK_ATTRIBUTE *value_bits_attr = NULL; CK_ATTRIBUTE *temp_value_bits_attr ; CK_BYTE *temp_byte; CK_ULONG temp_bn_len, count ; CK_BYTE *priv_key_value ; CK_ULONG priv_key_value_len ; CK_BYTE *pub_key_value ; CK_ULONG pub_key_value_len ; CK_BYTE *p_temp ; token pub_key_t, priv_key_t, prime_t, base_t ; char *base_p ; 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 > CR_MAX_MODULUS_SIZE_BYTES) || (prime_attr->ulValueLen < 64)) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Check if the CKA_VALUE_BITS attribute of the private key has been set. // If set, then check value to be less than size of prime, and use that value. // If not set, then use the value dependent on size of prime. rc = template_attribute_find( priv_tmpl, CKA_VALUE_BITS, &temp_value_bits_attr ); if (rc == FALSE) { // Randomly generate private key value priv_key_value_len = prime_attr->ulValueLen ; priv_key_value = malloc(priv_key_value_len) ; token_rng(priv_key_value, priv_key_value_len) ; // Right shift MSB of private to make it smaller than the prime p_temp = (CK_BYTE *)prime_attr->pValue ; while (p_temp[0] < priv_key_value[0]) priv_key_value[0] = priv_key_value[0] >> 1 ; } else { // Randomly generate private key value. Round off the value of CKA_VALUE_BITS // to next higher byte size for added security (and convenience/speed). priv_key_value_len = *(CK_ULONG *)temp_value_bits_attr->pValue ; if (priv_key_value_len > CR_MAX_MODULUS_SIZE_BITS) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } // Convert to next higher Byte size priv_key_value_len = (priv_key_value_len/8) + 1 ; // If the value set is less than 22 (180 bits), then bump the private-key // value to at least 180 bits (23 bytes)...for additional security if (priv_key_value_len < 22) priv_key_value_len = 23 ; priv_key_value = malloc(priv_key_value_len) ; token_rng(priv_key_value, priv_key_value_len) ; // If private size is same as prime size, make sure that the private // value is less than prime value. if (priv_key_value_len == prime_attr->ulValueLen) { // Right shift MSB of private to make it smaller than the prime p_temp = (CK_BYTE *)prime_attr->pValue ; while (p_temp[0] < priv_key_value[0]) priv_key_value[0] = priv_key_value[0] >> 1 ; } } // Calculate public key using: pub_key = base^priv_key mod prime // Setup the tokens with values from the input params pub_key_t.data_size = CR_MAX_MODULUS_SIZE_BYTES ; pub_key_value = malloc(pub_key_t.data_size) ; pub_key_t.p_data = pub_key_value ; priv_key_t.p_data = priv_key_value ; priv_key_t.data_size = priv_key_value_len ; prime_t.p_data = (char *)prime_attr->pValue ; prime_t.data_size = prime_attr->ulValueLen ; base_t.p_data = (char *)base_attr->pValue ; base_t.data_size = base_attr->ulValueLen ; // Perform mod exp operation rc = CR_mod_exp_mont(&pub_key_t, &base_t, &prime_t, &priv_key_t) ; if ( rc != SUCCESS ) { st_err_log(4, __FILE__, __LINE__); return CKR_FUNCTION_FAILED ; } /* Corrent library may return results after triming leading zeros. Insert the leading zeros back and adjust length below, if necessary */ if (pub_key_t.data_size < prime_t.data_size) { memmove(pub_key_value+(prime_t.data_size-pub_key_t.data_size), pub_key_value, pub_key_t.data_size) ; memset(pub_key_value, 0, prime_t.data_size-pub_key_t.data_size) ; pub_key_t.data_size = prime_t.data_size ; } pub_key_value_len = pub_key_t.data_size ; // Insert the public key component in the publ_tmpl rc = build_attribute( CKA_VALUE, pub_key_value, pub_key_value_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(pub_key_value); // Insert the private key component in the priv_tmpl rc = build_attribute( CKA_VALUE, priv_key_value, priv_key_value_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(priv_key_value); // 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*priv_key_value_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 ); return CKR_OK ; } /* end token_specific_dh_key_pair_gen() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -