📄 mech_ssl3.c
字号:
CK_BYTE * base_key_value = NULL; CK_BBOOL base_sensitive; CK_BBOOL base_always_sensitive; CK_BBOOL base_extractable; CK_BBOOL base_never_extractable; CK_OBJECT_HANDLE client_MAC_handle = 0; CK_OBJECT_HANDLE server_MAC_handle = 0; CK_OBJECT_HANDLE client_write_handle = 0; CK_OBJECT_HANDLE server_write_handle = 0; CK_SSL3_KEY_MAT_PARAMS * params = NULL; ATTRIBUTE_PARSE_LIST base_attrs[] = { {CKA_SENSITIVE , &base_sensitive , sizeof(CK_BBOOL), FALSE}, {CKA_EXTRACTABLE , &base_extractable , sizeof(CK_BBOOL), FALSE}, {CKA_ALWAYS_SENSITIVE , &base_always_sensitive , sizeof(CK_BBOOL), FALSE}, {CKA_NEVER_EXTRACTABLE, &base_never_extractable, sizeof(CK_BBOOL), FALSE}, }; if (!sess || !mech){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } params = (CK_SSL3_KEY_MAT_PARAMS *)mech->pParameter; rc = object_mgr_find_in_map1( base_key, &base_key_obj ); if (rc != CKR_OK){ st_err_log(18, __FILE__, __LINE__); return CKR_KEY_HANDLE_INVALID; } rc = template_attribute_find( base_key_obj->template, CKA_VALUE, &attr ); if (rc == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } else base_key_value = attr->pValue; template_attribute_find_multiple( base_key_obj->template, base_attrs, 4 ); for (i=0; i < 4; i++) { if (base_attrs[i].found == FALSE){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } } // The SSL3 spec says the IVs are 16 bytes long in the exportable case. // For now, we'll barf if someone asks for an exportable output and asks // for more than 128 bits of IV... // if (params->bIsExport != FALSE && params->ulIVSizeInBits > 128){ st_err_log(29, __FILE__, __LINE__); return CKR_MECHANISM_PARAM_INVALID; } // the template must specify the key type for the client and server keys // // also, CKA_SENSITIVE, CKA_ALWAYS_SENSITIVE, CKA_EXTRACTABLE and // CKA_NEVER_EXTRACTABLE, if present, are not allowed to differ from // the base key. We also check for stupid stuff. // for (i=0, attr = pTemplate; i < ulCount; i++, attr++) { CK_BBOOL tmp; if (attr->type == CKA_KEY_TYPE) keytype = *(CK_KEY_TYPE *)attr->pValue; else if (attr->type == CKA_SENSITIVE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_sensitive){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_ALWAYS_SENSITIVE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_always_sensitive){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_EXTRACTABLE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_extractable){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_NEVER_EXTRACTABLE) { tmp = *(CK_BBOOL *)attr->pValue; if (tmp != base_never_extractable){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } else if (attr->type == CKA_CLASS) { CK_OBJECT_CLASS cl = *(CK_OBJECT_CLASS *)attr->pValue; if (cl != CKO_SECRET_KEY){ st_err_log(49, __FILE__, __LINE__); return CKR_TEMPLATE_INCONSISTENT; } } } // a key type must be specified for the client and server write keys // if (keytype == 0xFFFFFFFF){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } // figure out how much key material we need to generate // key_material_loop_count = 2 * ((params->ulMacSizeInBits + 7) / 8) + 2 * ((params->ulKeySizeInBits + 7) / 8); if (params->bIsExport == FALSE) key_material_loop_count += 2 * ((params->ulIVSizeInBits + 7) / 8); // we stop at 'ZZZZ....' presumably this is enough for all cases? // if (key_material_loop_count > 26 * 16){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } key_material_loop_count = (key_material_loop_count + 15) / 16; // generate the key material // for (i=0; i < key_material_loop_count; i++) { memset( variable_data, ('A' + i), i+1 ); rc = ssl3_sha_then_md5( sess, base_key_value, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, variable_data, i+1, &(key_block[i*16]) ); if (rc != CKR_OK){ st_err_log(136, __FILE__, __LINE__); goto error; } } // Break key material into pieces // MAC_len = (params->ulMacSizeInBits + 7) / 8; write_len = (params->ulKeySizeInBits + 7) / 8; // check this client_MAC_key_value = key_block; server_MAC_key_value = client_MAC_key_value + MAC_len; client_write_key_value = server_MAC_key_value + MAC_len; server_write_key_value = client_write_key_value + (params->ulKeySizeInBits + 7)/8; if (params->ulIVSizeInBits != 0) { iv_len = (params->ulIVSizeInBits + 7) / 8; client_IV = server_write_key_value + write_len; server_IV = client_IV + iv_len; } // Exportable ciphers require additional processing // if (params->bIsExport == TRUE) { write_len = 16; iv_len = 16; rc = ssl3_md5_only( sess, client_write_key_value, (params->ulKeySizeInBits + 7)/8, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, &(key_block[16*26]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } client_write_key_value = &(key_block[16*26]); rc = ssl3_md5_only( sess, server_write_key_value, (params->ulKeySizeInBits + 7)/8, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, &(key_block[16*26+16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } server_write_key_value = &(key_block[16*26+16]); if (params->ulIVSizeInBits != 0) { rc = ssl3_md5_only( sess, NULL, 0, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, &(key_block[16*26+2*16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } client_IV = &(key_block[16*26+2*16]); rc = ssl3_md5_only( sess, NULL, 0, params->RandomInfo.pServerRandom, params->RandomInfo.ulServerRandomLen, params->RandomInfo.pClientRandom, params->RandomInfo.ulClientRandomLen, &(key_block[16*26+3*16]) ); if (rc != CKR_OK){ st_err_log(137, __FILE__, __LINE__); goto error; } server_IV = &(key_block[16*26+3*16]); } } rc = ssl3_kmd_process_mac_keys( sess, pTemplate, ulCount, &client_MAC_handle, client_MAC_key_value, &server_MAC_handle, server_MAC_key_value, MAC_len ); if (rc != CKR_OK){ st_err_log(138, __FILE__, __LINE__); goto error; } rc = ssl3_kmd_process_write_keys( sess, pTemplate, ulCount, keytype, &client_write_handle, client_write_key_value, &server_write_handle, server_write_key_value, write_len ); if (rc != CKR_OK){ st_err_log(139, __FILE__, __LINE__); goto error; } params->pReturnedKeyMaterial->hClientMacSecret = client_MAC_handle; params->pReturnedKeyMaterial->hServerMacSecret = server_MAC_handle; params->pReturnedKeyMaterial->hClientKey = client_write_handle; params->pReturnedKeyMaterial->hServerKey = server_write_handle; if (params->ulIVSizeInBits != 0) { if (params->pReturnedKeyMaterial->pIVClient) memcpy( params->pReturnedKeyMaterial->pIVClient, client_IV, iv_len ); if (params->pReturnedKeyMaterial->pIVServer) memcpy( params->pReturnedKeyMaterial->pIVServer, server_IV, iv_len );#if 0 CK_BYTE *p1, *p2; p1 = (CK_BYTE *)malloc( iv_len ); p2 = (CK_BYTE *)malloc( iv_len ); if (!p1 || !p2) { rc = CKR_HOST_MEMORY; goto error; } memcpy( p1, client_IV, iv_len ); memcpy( p2, server_IV, iv_len ); params->pReturnedKeyMaterial->pIVClient = p1; params->pReturnedKeyMaterial->pIVServer = p2;#endif } return rc;error: if (client_write_handle != 0) object_mgr_remove_from_map( client_write_handle ); if (server_write_handle != 0) object_mgr_remove_from_map( server_write_handle ); return rc;}CK_RVssl3_kmd_process_mac_keys( SESSION * sess, CK_ATTRIBUTE * pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE * client_handle, CK_BYTE * client_value, CK_OBJECT_HANDLE * server_handle, CK_BYTE * server_value, CK_ULONG mac_len ){ OBJECT * client_obj = NULL; OBJECT * server_obj = NULL; CK_ATTRIBUTE * client_val_attr = NULL; CK_ATTRIBUTE * client_val_len_attr = NULL; CK_ATTRIBUTE * server_val_attr = NULL; CK_ATTRIBUTE * server_val_len_attr = NULL; CK_ATTRIBUTE * attr = NULL; CK_ATTRIBUTE * new_attrs = NULL; CK_ULONG i, cnt; CK_ULONG true_vals[] = { CKA_SIGN, CKA_VERIFY, CKA_DERIVE }; CK_ULONG false_vals[] = { CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP }; CK_RV rc; // for the MAC keys, we want the following default values: // CKA_SIGN, CKA_VERIFY, CKA_DERIVE = TRUE // CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP = FALSE // // attributes are added in sequential order so we stick the defaults // at the beginning so that they may be overridden by caller-specified // values. // new_attrs = (CK_ATTRIBUTE *)malloc((ulCount + 7) * (sizeof(CK_ATTRIBUTE))); if (!new_attrs) goto error; // we have to treat these attributes a bit differently. normally, we allocate // the CK_ATTRIBUTE and the value with a single malloc and just point the pValue // member to the extra space. we can't do that here because we have to "emulate" // the way attributes are passed in from the cryptoki application...as an array // of CK_ATTRIBUTEs with no extra space (that is, pValue must be allocated // separately). // attr = new_attrs; for (i=0; i < sizeof(true_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = true_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = TRUE; } for (i=0; i < sizeof(false_vals) / sizeof(CK_ULONG); i++, attr++) { attr->type = false_vals[i]; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BBOOL *)malloc(sizeof(CK_BBOOL)); if (!attr->pValue) { rc = CKR_HOST_MEMORY; st_err_log(0, __FILE__, __LINE__); goto error; } *(CK_BBOOL *)attr->pValue = FALSE; } for (i=0, cnt=0; i < ulCount; i++) { if (pTempl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -