some problems about AES CCM

1st problem:

There are some failed case when i run  \v2.9.1\modules\bsim_hw_models\nrf_hw_models\tests\zephyr_apps\54_aar_ccm_ecb\src\test_ccm.c

2nd problem:

If I reduce the amount of encrypted data in test_ccm_12b_encr_ble_255b_w_adata_nomac, the encryption process gets stuck.

Parents
  • ZTEST(nrf_ccm_tests, test_ccm_12c_encr_ble_0_255b_w_adata_nomac)
    {
    	printk("Encrypt 0-255 byte payload with adata and no MAC in BLE mode\n");
    
    	uint8_t K[16] = {0x99, 0xAD, 0x1B, 0x52, 0x26, 0xA3, 0x7E, 0x3E, 0x05, 0x8E, 0x3B, 0x8E, 0x27, 0xC2, 0xC6, 0x66};
    	uint8_t N[16] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0xAB, 0xDC, 0xBA, 0xBE, 0xBA, 0xAF, 0xDE};
    	uint8_t A[] = {0x0E};
    	uint8_t P[] = {0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,  0x8,  0x9, 0xa, 0xb,  0xc,  0xd,  0xe,  0xf,  0x10,
    			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
    			0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
    			0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
    			0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
    			0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65,
    			0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
    			0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
    			0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
    			0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
    			0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
    			0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,
    			0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
    			0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
    	uint8_t C[] = {
    			0x6D, 0x71, 0xB7, 0x03, 0x74, 0x41, 0x0C, 0x9D, 0x0A, 0x74, 0xE2, 0xFD, 0x67, 0x67, 0x64, 0x26, 0x0A, 0xF6, 0x76,
    			0x6F, 0x59, 0x4B, 0x7B, 0xBC, 0xC6, 0xDF, 0x18, 0x5B, 0x50, 0x2D, 0x3D, 0x5E, 0xD9, 0xAF, 0xF6, 0xB8, 0xFE, 0x86,
    			0xC5, 0x23, 0x3A, 0xA8, 0x35, 0xE4, 0xE6, 0xA0, 0xB6, 0xC9, 0x48, 0xFF, 0xFF, 0xF5, 0xA0, 0xC0, 0x19, 0x32, 0x71,
    			0x60, 0x61, 0x0C, 0x1B, 0xE5, 0x43, 0xCE, 0xB5, 0xBC, 0x9E, 0x3A, 0x3D, 0x85, 0xB7, 0xAA, 0x65, 0x64, 0x2E, 0x38,
    			0x82, 0x27, 0x3D, 0xA4, 0x13, 0xFE, 0xE5, 0x89, 0x1F, 0x2F, 0x0E, 0x9B, 0x02, 0x0B, 0x10, 0xCD, 0xA8, 0xCD, 0xBA,
    			0xA6, 0xD0, 0x40, 0x44, 0xD0, 0x75, 0x37, 0xBB, 0x06, 0x16, 0x54, 0x04, 0x7F, 0x8A, 0x0C, 0x2E, 0x7E, 0xB8, 0x06,
    			0x06, 0x63, 0x3F, 0x4A, 0x08, 0xFF, 0x21, 0x28, 0x6C, 0x8F, 0x65, 0xB6, 0x29, 0xE5, 0xFC, 0x58, 0x29, 0x7D, 0x55,
    			0xFE, 0xA8, 0x24, 0xDE, 0xE5, 0xB1, 0x8C, 0x9B, 0xAF, 0xD3, 0x78, 0xCE, 0x87, 0x92, 0x07, 0x4F, 0x40, 0x75, 0xE6,
    			0xA7, 0x61, 0x09, 0x73, 0xBE, 0x0A, 0x29, 0x05, 0x3F, 0xF7, 0xBD, 0xD8, 0x9C, 0xC7, 0xDA, 0x4B, 0xAC, 0xE9, 0xC2,
    			0xE4, 0xD7, 0x4C, 0x2C, 0x26, 0x8C, 0x00, 0xE4, 0xE6, 0xBE, 0x05, 0x0E, 0xC2, 0xDA, 0x1E, 0xA7, 0xAE, 0xD7, 0x35,
    			0xA8, 0x26, 0xCD, 0xF8, 0x93, 0x93, 0x26, 0x0C, 0xD5, 0x47, 0x9B, 0x7C, 0x35, 0x62, 0x7D, 0xFB, 0xCF, 0xAD, 0x78,
    			0x91, 0xA6, 0x0C, 0xC8, 0x5C, 0xBF, 0x05, 0xBF, 0x7E, 0xE4, 0x0C, 0x4A, 0x9E, 0xC9, 0xD2, 0x9F, 0x75, 0x7A, 0x58,
    			0x84, 0x9B, 0xD4, 0x9A, 0x2B, 0x51, 0xB2, 0x4A, 0x3A, 0x45, 0xEB, 0x58, 0x33, 0x86, 0x53, 0xC5, 0xBA, 0x63, 0x73,
    			0xB6, 0x89, 0x25, 0xD7,
    	};
    	unsigned mac_len = 0;
    	uint8_t adata_mask = 0xE3;
    
    	for (uint8_t len = 0; len <= 255; len++)
    	{
    		build_ccm_test_case_and_run(K, N, P, len, len, A, sizeof(A), C, len, mac_len, adata_mask, false,
    				false, ENCRYPT, BLE_MODE, NULL, false);
    	}
    }

    I wrote an example of encrypting data of different lengths according to test_ccm_12b, but it got stuck when len=36.

  • Could this be Errata [1] CCM: MAC error is returned if MDATA size is slightly larger than MLEN?

    Try to set MLEN (len) to a lot higher than sizeof(P), as suggested in the workaround

  • I looked at test_ccm_12b_encr_ble_255b_w_adata_nomac, and it does not have mlen set to a large number.

    When I run test_ccm_12b_encr_ble_255b_w_adata_nomac as is, it freezes, as you describe.

    However, when I do

    build_ccm_test_case_and_run(K, N, P, len, 1000, A, sizeof(A), C, len, mac_len, adata_mask, false, false, ENCRYPT, BLE_MODE, NULL, false);

    It no longer freezes, but returns an error instead.
    Do you see the same?

  • yes, It prompts CCM->EVENTS_ERROR not equal zero, and CCM->ERRORSTATUS = 1, which means End of INPTR job list before CCM data structure was read.

    If i have mlen set to len, it freezes when len = 36

  • Since CCM is usually with a MAC, I found it easier to make a CCM test script for the test_ccm_12b_encr_ble_255b_w_adata case. So I did.
    Here is an example of a shorter CCM with that case, and the python script (made with help from chatgpt)  that I used to generate test data:

    54_ccm_only_2.zip

    from Crypto.Cipher import AES
    from Crypto.Util import Counter
    
    # === Configuration ===
    # Key (16 bytes)
    K = bytes([
        0x99, 0xAD, 0x1B, 0x52, 0x26, 0xA3, 0x7E, 0x3E,
        0x05, 0x8E, 0x3B, 0x8E, 0x27, 0xC2, 0xC6, 0x66
    ])
    # Full Nonce Blob (16 bytes)
    N_full = bytes([
        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80,
        0x24, 0xAB, 0xDC, 0xBA, 0xBE, 0xBA, 0xAF, 0xDE
    ])
    # CCM requires nonce length 7..13 bytes; take the last 13 bytes
    nonce = N_full[-13:]
    
    # Associated data (AAD)
    A = bytes([0x0E])
    # Hardware-specific AAD mask for BLE mode
    adata_mask = 0xE3
    # Apply mask to each AAD byte
    masked_A = bytes([b & adata_mask for b in A])
    
    # Define mac length; set to 0 for "no MAC"
    mac_len = 0
    # Tag length in bytes (4, 6, 8, 10, 12, 14, or 16) when mac_len > 0
    tag_len = 4
    
    # === Define Plaintext P below ===
    # Replace or extend this byte list as needed
    P = bytes([
        0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,  0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf,  0x10,
    			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
    			0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
    			0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43,
    			0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
    			0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65,
    			0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
    			0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
    			0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
    			0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
    			0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
    			0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc,
    			0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
    			0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
    ])
    
    # === Encryption ===
    if mac_len > 0:
        # AES-CCM authenticated encryption
        cipher = AES.new(
            K,
            AES.MODE_CCM,
            nonce=nonce,
            mac_len=tag_len,
            msg_len=len(P)
        )
        # Use masked AAD
        cipher.update(masked_A)
        C = cipher.encrypt(P)
        tag = cipher.digest()
        data = C + tag
    else:
        # AES-CTR for "no MAC" scenario
        # Construct counter using nonce as prefix
        bit_len = 128 - len(nonce)*8
        ctr = Counter.new(bit_len, prefix=nonce)
        cipher = AES.new(K, AES.MODE_CTR, counter=ctr)
        data = cipher.encrypt(P)
    
    # === Output in C-array format ===
    for i, b in enumerate(data):
        end = "\n" if (i + 1) % 8 == 0 else " "
        sep = "," if i < len(data) - 1 else ""
        print(f"    0x{b:02X}{sep}", end=end)
    print()
    print(f"// Output length = {len(data)} bytes")
    

    Are these helpful?

  • I need to encrypt packets on-the-fly in radio transmit mode later, so I need to know why it freezes when use CCM.

  • Did you test the sample I uploaded? Does it work for you?

    LeeRJ said:
    I need to encrypt packets on-the-fly in radio transmit mode later, so I need to know why it freezes when use CCM.

    It freezes in  here in the sample code.

    If the freeze is an issue for you, you can make this loop time out, and then handle it as an error.

Reply Children
No Data
Related