static void slots_load_info (slot_info_t* pInfo) { gchar guid_buf[GUID_ENCODING_LENGTH + 1]; g_return_if_fail (pInfo != NULL); g_return_if_fail (pInfo->be != NULL); g_return_if_fail (pInfo->guid != NULL); g_return_if_fail (pInfo->pKvpFrame != NULL); (void)guid_to_string_buff (pInfo->guid, guid_buf); std::stringstream buf; buf << "SELECT * FROM " << TABLE_NAME << " WHERE obj_guid='" << guid_buf << "'"; auto stmt = pInfo->be->create_statement_from_sql (buf.str()); if (stmt != nullptr) { auto result = pInfo->be->execute_select_statement (stmt); for (auto row : *result) load_slot (pInfo, row); } }
static void slots_load_info ( slot_info_t *pInfo ) { gchar* buf; GncSqlResult* result; gchar guid_buf[GUID_ENCODING_LENGTH + 1]; GncSqlStatement* stmt; g_return_if_fail( pInfo != NULL ); g_return_if_fail( pInfo->be != NULL ); g_return_if_fail( pInfo->guid != NULL ); g_return_if_fail( pInfo->pKvpFrame != NULL ); (void)guid_to_string_buff( pInfo->guid, guid_buf ); buf = g_strdup_printf( "SELECT * FROM %s WHERE obj_guid='%s'", TABLE_NAME, guid_buf ); stmt = gnc_sql_create_statement_from_sql( pInfo->be, buf ); g_free( buf ); if ( stmt != NULL ) { result = gnc_sql_execute_select_statement( pInfo->be, stmt ); gnc_sql_statement_dispose( stmt ); if ( result != NULL ) { GncSqlRow* row = gnc_sql_result_get_first_row( result ); while ( row != NULL ) { load_slot( pInfo, row ); row = gnc_sql_result_get_next_row( result ); } gnc_sql_result_dispose( result ); } } }
static fsl_shw_return_t create(fsl_shw_uco_t * user_ctx, fsl_shw_sko_t * key_info) { fsl_shw_return_t ret = FSL_RETURN_ERROR_S; unsigned key_length = key_info->key_length; di_return_t di_code; if (!(key_info->flags & FSL_SKO_KEY_SW_KEY)) { /* Must be creating key for PK */ if ((key_info->algorithm != FSL_KEY_ALG_TDES) || ((key_info->key_length != 16) && (key_info->key_length != 21) /* permuted 168-bit key */ &&(key_info->key_length != 24))) { ret = FSL_RETURN_ERROR_S; goto out; } key_length = 21; /* 168-bit PK */ } /* operational block */ { uint8_t key_value[key_length]; #ifdef DIAG_SECURITY_FUNC LOG_DIAG("Creating random key\n"); #endif ret = fsl_shw_get_random(user_ctx, key_length, key_value); if (ret != FSL_RETURN_OK_S) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG("get_random for CREATE KEY failed\n"); #endif goto out; } if (key_info->flags & FSL_SKO_KEY_SW_KEY) { ret = load_slot(user_ctx, key_info, key_value); } else { di_code = dryice_set_programmed_key(key_value, 8 * key_length, 0); if (di_code != 0) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS("di set_pk failed: %s\n", di_error_string(di_code)); #endif ret = FSL_RETURN_ERROR_S; goto out; } ret = FSL_RETURN_OK_S; } memset(key_value, 0, key_length); } /* end operational block */ #ifdef DIAG_SECURITY_FUNC if (ret != FSL_RETURN_OK_S) { LOG_DIAG("Loading random key failed"); } #endif out: return ret; } /* end fn create */
static fsl_shw_return_t accept(fsl_shw_uco_t * user_ctx, fsl_shw_sko_t * key_info, const uint8_t * key) { uint8_t permuted_key[21]; fsl_shw_return_t ret = FSL_RETURN_ERROR_S; if (key == NULL) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG("ACCEPT: Red Key is NULL"); #endif ret = FSL_RETURN_ERROR_S; goto out; } #ifdef DIAG_SECURITY_FUNC dump("red", key, key_info->key_length); #endif /* Only SW keys go into the keystore */ if (key_info->flags & FSL_SKO_KEY_SW_KEY) { /* Copy in safe number of bytes of Red key */ ret = load_slot(user_ctx, key_info, key); } else { /* not SW key */ di_return_t di_ret; /* Only 3DES PGM key types can be established */ if (((key_info->pf_key != FSL_SHW_PF_KEY_PRG) && (key_info->pf_key != FSL_SHW_PF_KEY_IIM_PRG)) || (key_info->algorithm != FSL_KEY_ALG_TDES)) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS ("ACCEPT: Failed trying to establish non-PRG" " or invalid 3DES Key: iim%d, iim_prg%d, alg%d\n", (key_info->pf_key != FSL_SHW_PF_KEY_PRG), (key_info->pf_key != FSL_SHW_PF_KEY_IIM_PRG), (key_info->algorithm != FSL_KEY_ALG_TDES)); #endif ret = FSL_RETURN_ERROR_S; goto out; } if ((key_info->key_length != 16) && (key_info->key_length != 21) && (key_info->key_length != 24)) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS("ACCEPT: Failed trying to establish" " invalid 3DES Key: len=%d (%d)\n", key_info->key_length, ((key_info->key_length != 16) && (key_info->key_length != 21) && (key_info->key_length != 24))); #endif ret = FSL_RETURN_BAD_KEY_LENGTH_S; goto out; } /* Convert key into 168-bit value and put it into PK */ if (key_info->key_length != 21) { fsl_shw_permute1_bytes(key, permuted_key, key_info->key_length / 8); di_ret = dryice_set_programmed_key(permuted_key, 168, 0); } else { /* Already permuted ! */ di_ret = dryice_set_programmed_key(key, 168, 0); } if (di_ret != DI_SUCCESS) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS ("ACCEPT: DryIce error setting Program Key: %s", di_error_string(di_ret)); #endif ret = FSL_RETURN_ERROR_S; goto out; } } ret = FSL_RETURN_OK_S; out: memset(permuted_key, 0, 21); return ret; } /* end fn accept */
/*! * Perform unwrapping of a black key into a RED slot * * @param user_ctx A user context from #fsl_shw_register_user(). * @param[in,out] key_info The information about the key to be which will * be unwrapped... key length, slot info, etc. * @param black_key Encrypted key * * @return A return code of type #fsl_shw_return_t. */ static fsl_shw_return_t unwrap(fsl_shw_uco_t * user_ctx, fsl_shw_sko_t * key_info, const uint8_t * black_key) { fsl_shw_return_t ret; uint8_t hmac[ICV_LENGTH]; uint8_t T[T_LENGTH]; uint8_t kek[KEK_LENGTH + 20]; int key_length = black_key[LENGTH_OFFSET]; int rounded_key_length = ROUND_LENGTH(key_length); uint8_t key[rounded_key_length]; fsl_shw_sko_t t_key_info; fsl_shw_scco_t t_key_ctx; fsl_shw_sko_t kek_key_info; fsl_shw_scco_t kek_ctx; int unwrapping_sw_key = key_info->flags & FSL_SKO_KEY_SW_KEY; int pk_needs_restoration = 0; /* bool */ unsigned original_key_length = key_info->key_length; int pk_was_held = 0; uint8_t current_pk[21]; di_return_t di_code; ret = check_wrap_key(user_ctx->wrap_key); if (ret != FSL_RETURN_OK_S) { goto out; } if (black_key == NULL) { ret = FSL_RETURN_ERROR_S; goto out; } #ifdef DIAG_SECURITY_FUNC dump("black", black_key, KEY_PRIME_OFFSET + key_length); #endif /* Validate SW flags to prevent misuse */ if ((key_info->flags & FSL_SKO_KEY_SW_KEY) && !(black_key[FLAGS_OFFSET] & FLAGS_SW_KEY)) { ret = FSL_RETURN_BAD_FLAG_S; goto out; } /* Compute T = 3des-dec-ecb(wrap_key, T') */ init_wrap_key(user_ctx->wrap_key, &t_key_info, &t_key_ctx); ret = fsl_shw_symmetric_decrypt(user_ctx, &t_key_info, &t_key_ctx, T_LENGTH, black_key + T_PRIME_OFFSET, T); if (ret != FSL_RETURN_OK_S) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG("Recovery of nonce (T) failed"); #endif /*DIAG_SECURITY_FUNC */ goto out; } /* Compute ICV = HMAC(T, ownerid | len | alg | flags | key' */ ret = calc_icv(T, (uint8_t *) & key_info->userid, sizeof(key_info->userid), black_key, original_key_length, hmac); if (ret != FSL_RETURN_OK_S) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG("Calculation of ICV failed"); #endif /*DIAG_SECURITY_FUNC */ goto out; } #ifdef DIAG_SECURITY_FUNC LOG_DIAG("Validating MAC of wrapped key"); #endif /* Check computed ICV against value in Black Key */ if (memcmp(black_key + ICV_OFFSET, hmac, ICV_LENGTH) != 0) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG("Computed ICV fails validation\n"); #endif ret = FSL_RETURN_AUTH_FAILED_S; goto out; } /* Compute KEK = SHA256(T | ownerid). */ ret = calc_kek((uint8_t *) & key_info->userid, sizeof(key_info->userid), T, kek); if (ret != FSL_RETURN_OK_S) { goto out; } if (unwrapping_sw_key) { di_code = dryice_get_programmed_key(current_pk, 8 * 21); if (di_code != DI_SUCCESS) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS("Could not save current PK: %s\n", di_error_string(di_code)); #endif ret = FSL_RETURN_ERROR_S; goto out; } } /* * "Establish" the KEK in the PK. If the PK was held and unwrapping a * software key, then release it and try again, but remember that we need * to leave it 'held' if we are unwrapping a software key. * * If the PK is held while we are unwrapping a key for the PK, then * the user didn't call release, so gets an error. */ di_code = dryice_set_programmed_key(kek, 8 * 21, 0); if ((di_code == DI_ERR_INUSE) && unwrapping_sw_key) { /* Temporarily reprogram the PK out from under the user */ pk_was_held = 1; dryice_release_programmed_key(); di_code = dryice_set_programmed_key(kek, 8 * 21, 0); } if (di_code != DI_SUCCESS) { #ifdef DIAG_SECURITY_FUNC LOG_DIAG_ARGS("Could not program KEK: %s\n", di_error_string(di_code)); #endif ret = FSL_RETURN_ERROR_S; goto out; } if (unwrapping_sw_key) { pk_needs_restoration = 1; } dryice_release_programmed_key(); /* Because of previous 'set' */ /* Compute KEY = TDES-decrypt(KEK, KEY') */ fsl_shw_sko_init_pf_key(&kek_key_info, FSL_KEY_ALG_TDES, FSL_SHW_PF_KEY_PRG); fsl_shw_sko_set_key_length(&kek_key_info, KEK_LENGTH); fsl_shw_scco_init(&kek_ctx, FSL_KEY_ALG_TDES, FSL_SYM_MODE_CBC); fsl_shw_scco_set_flags(&kek_ctx, FSL_SYM_CTX_LOAD); fsl_shw_scco_set_context(&kek_ctx, (uint8_t *) & key_info->userid); #ifdef DIAG_SECURITY_FUNC dump("KEY'", black_key + KEY_PRIME_OFFSET, rounded_key_length); #endif ret = fsl_shw_symmetric_decrypt(user_ctx, &kek_key_info, &kek_ctx, rounded_key_length, black_key + KEY_PRIME_OFFSET, key); if (ret != FSL_RETURN_OK_S) { goto out; } #ifdef DIAG_SECURITY_FUNC dump("KEY", key, original_key_length); #endif /* Now either put key into PK or into a slot */ if (key_info->flags & FSL_SKO_KEY_SW_KEY) { ret = load_slot(user_ctx, key_info, key); } else { /* * Since we have just unwrapped a program key, it had * to have been wrapped as a program key, so it must * be 168 bytes long and permuted ... */ ret = dryice_set_programmed_key(key, 8 * key_length, 0); if (ret != FSL_RETURN_OK_S) { goto out; } } out: key_info->key_length = original_key_length; if (pk_needs_restoration) { di_code = dryice_set_programmed_key(current_pk, 8 * 21, 0); } if (!pk_was_held) { dryice_release_programmed_key(); } /* Erase tracks of confidential data */ memset(T, 0, T_LENGTH); memset(key, 0, rounded_key_length); memset(current_pk, 0, sizeof(current_pk)); memset(&t_key_info, 0, sizeof(t_key_info)); memset(&t_key_ctx, 0, sizeof(t_key_ctx)); memset(&kek_key_info, 0, sizeof(kek_key_info)); memset(&kek_ctx, 0, sizeof(kek_ctx)); memset(kek, 0, KEK_LENGTH); return ret; } /* unwrap */