diverta / onecard-fido

MIT License
0 stars 0 forks source link

[障害・解決済] nRF52側でリソース不足によるエラー発生 #2

Closed makmorit closed 6 years ago

makmorit commented 6 years ago

確認された事象

U2Fトークン(One Card上のFIDO BLE U2Fサービス)を使って、U2FテストサイトにSign(テスト認証)を数回繰り返すと、nRF52ボードのリソース不足が原因で、処理が失敗する障害が発生。 (2017/11/30 14:52頃に発覚)

ログ

U2F管理ツール(U2FMaintenanceTool.app)のログ

default 14:51:27.348903 +0900   U2FMaintenanceTool  Install secure key start
default 14:51:27.349223 +0900   U2FMaintenanceTool  FIDO U2Fデバイスのスキャンを開始します
default 14:51:27.511009 +0900   U2FMaintenanceTool  FIDO U2Fデバイスのスキャンを完了しました
default 14:51:28.347465 +0900   U2FMaintenanceTool  FIDO U2Fデバイスに接続しました。
default 14:51:28.350325 +0900   U2FMaintenanceTool  FIDO BLE U2Fサービスが見つかりました。
default 14:51:29.486783 +0900   U2FMaintenanceTool  受信データの監視を開始します。
default 14:51:29.738864 +0900   U2FMaintenanceTool  Sent request <83002900 40030000 002045cc 9100f4a3 d2aa7dce 0cac6255 d76e26c5 cc9139ae af8f55ec 1f468c23 93d40000>
default 14:51:29.739028 +0900   U2FMaintenanceTool  リクエストを送信しました。
default 14:51:29.861724 +0900   U2FMaintenanceTool  Received response <83000200 06>
default 14:51:29.861874 +0900   U2FMaintenanceTool  レスポンスを受信しました。
default 14:51:29.958596 +0900   U2FMaintenanceTool  FIDO U2Fデバイスの接続を切断しました。
default 14:51:29.961533 +0900   U2FMaintenanceTool  BLEエラーが発生しました。処理を再試行してください。

nRF52のUARTログ

FDS(Flash ROM読み書き用のライブラリー)のリソース不足により「ble_u2f_flash:ERROR:fds_record_update returns 0x07 」のログが出力されていました。

APP:INFO:[APP]Connected to a previously bonded device.
nrf_ble_gatt:DEBUG:Requesting to update ATT MTU to 67 bytes on connection 0x0.
nrf_ble_gatt:DEBUG:Requesting to update data length to 71 on connection 0x0.
ble_u2f_command:DEBUG:ble_u2f_command_initialize_context done 
:INFO:[BLE]BLE_GAP_EVT_CONNECTED
APP:INFO:[APP]Connected.
nrf_ble_gatt:DEBUG:ATT MTU updated to 67 bytes on connection 0x0 (response).
nrf_ble_gatt:DEBUG:Data length updated to 71 on connection 0x0.
nrf_ble_gatt:DEBUG:max_rx_octets: 71
nrf_ble_gatt:DEBUG:max_tx_octets: 71
nrf_ble_gatt:DEBUG:max_rx_time: 680
nrf_ble_gatt:DEBUG:max_tx_time: 680
APP:INFO:[APP]Connection secured: role: 1, conn_handle: 0x0, procedure: 0.
ble_u2f_pairing_lesc:INFO:Security connection updated: Security Mode=1, Level=2 
nrf_ble_gatt:DEBUG:Peer on connection 0x0 requested an ATT MTU of 1000 bytes.
nrf_ble_gatt:DEBUG:Updating ATT MTU to 67 bytes (desired: 67) on connection 0x0.
:INFO:[BLE]BLE_GATTS_EVT_WRITE
:INFO:[BLE]BLE_GATTS_EVT_WRITE
ble_u2f:DEBUG:on_cccd_write: Notification status changed to enabled 
:INFO:[BLE]BLE_GATTS_EVT_WRITE
ble_u2f_control_point:DEBUG:ble_u2f_control_point_receive length=44 
ble_u2f_control_point:DEBUG:INIT frame: CMD(0x83) LEN(41) SEQ(255) 
ble_u2f_control_point_apdu:DEBUG:CLA(0x00) INS(0x40) P1(0x03) P2(0x00) 
ble_u2f_control_point_apdu:DEBUG:Lc(32 bytes) in Extended Length Encoding
ble_u2f_control_point_apdu:DEBUG:response_message_buffer allocated (1024 bytes) 
ble_u2f_control_point_apdu:DEBUG:Le(65536 bytes) in Extended Length Encoding 
ble_u2f_control_point_apdu:DEBUG:INIT frame: received data (32 bytes) 
ble_u2f_command:DEBUG:get_command_type: initial skey data received 
ble_u2f_securekey:DEBUG:ble_u2f_securekey_install_skey start 
ble_u2f_flash:DEBUG:securekey_buffer allocated (1060 bytes) 
ble_u2f_securekey:DEBUG:convert_skey_bytes_to_word start 
ble_u2f_securekey:DEBUG:Converted to [0x0091cc45]
ble_u2f_securekey:DEBUG:Converted to [0xaad2a3f4]
ble_u2f_securekey:DEBUG:Converted to [0xac0cce7d]
ble_u2f_securekey:DEBUG:Converted to [0x6ed75562]
ble_u2f_securekey:DEBUG:Converted to [0x91ccc526]
ble_u2f_securekey:DEBUG:Converted to [0x8fafae39]
ble_u2f_securekey:DEBUG:Converted to [0x461fec55]
ble_u2f_securekey:DEBUG:Converted to [0xd493238c]
ble_u2f_securekey:DEBUG:convert_skey_bytes_to_word end 
ble_u2f_flash:ERROR:fds_record_update returns 0x07 
ble_u2f_status:DEBUG:u2f_response_send (5bytes) 
ble_u2f_command:DEBUG:m_u2f_context.securekey_buffer freed 
ble_u2f_command:DEBUG:m_u2f_context.apdu_data_buffer freed 
ble_u2f_command:DEBUG:ble_u2f_command_finalize_context done 
:INFO:[BLE]BLE_GAP_EVT_DISCONNECTED
APP:INFO:[APP]Disconnected.
makmorit commented 6 years ago

原因調査

問題のある場所の特定

FDSによりFlash ROM書込み管理を行うと、書込みのために必要な領域がいっぱいになった場合、FDSの関数 (fds_record_update, fds_record_write) から「FDS_ERR_NO_SPACE_IN_FLASH」というステータスが戻ります。

該当箇所は下記4箇所になりますが、いずれの処理でも「FDS_ERR_NO_SPACE_IN_FLASH」というステータスが戻る可能性はあります。

static bool write_pairing_mode(void)
{
:
    if (ret == FDS_SUCCESS) {
        // 既存のデータが存在する場合は上書き
        ret = fds_record_update(&record_desc, &record);
:
    } else if (ret == FDS_ERR_NOT_FOUND) {
        // 既存のデータが存在しない場合は新規追加
        ret = fds_record_write(&record_desc, &record);
:
}
bool ble_u2f_flash_keydata_write(ble_u2f_context_t *p_u2f_context)
{
:
    if (ret == FDS_SUCCESS) {
        // 既存のデータが存在する場合は上書き
        ret = fds_record_update(&record_desc, &record);
:
    } else if (ret == FDS_ERR_NOT_FOUND) {
        // 既存のデータが存在しない場合は新規追加
        ret = fds_record_write(&record_desc, &record);
:
}

bool ble_u2f_flash_token_counter_write(ble_u2f_context_t *p_u2f_context, uint8_t *p_appid_hash, uint32_t token_counter, uint32_t reserve_word)
{
:
    if (found == true) {
        // 既存のデータが存在する場合は上書き
        ret = fds_record_update(&record_desc, &record);

    } else {
        // 既存のデータが存在しない場合は新規追加
        ret = fds_record_write(&record_desc, &record);
    }
:
}
static bool write_random_vector(uint32_t *p_fds_record_buffer)
{
:
    if (ret == FDS_SUCCESS) {
        // 既存のデータが存在する場合は上書き
        ret = fds_record_update(&record_desc, &record);
:
    } else if (ret == FDS_ERR_NOT_FOUND) {
        // 既存のデータが存在しない場合は新規追加
        ret = fds_record_write(&record_desc, &record);
:
}

この問題による影響

Chrome BookのBLEエクステンションは、BLE接続がキープされる仕様なので、(One Cardアプリケーション側で用意した)BLE接続の切断時に行われる、FDSのガベージコレクション(以下GCと略す)処理が行われない不具合があります。

このため、Chromeブラウザーで処理を再試行しても、FDSのリソース不足が解消されるタイミングがなく、エラーが発生し続けてしまいます。

また、同じくBLE接続がキープされる仕様のFIDO認証テストツール(BLECertificationTool.exe)でも、同様な問題が発生してしまいます。

対策

修正方針

上記問題・影響を踏まえ、以下の対策を施したいと考えます。

makmorit commented 6 years ago

問題が解決しましたのでcloseします。