From 3196c8e4bcb5704a1a2a5ed66b7c7f07ae04b87c Mon Sep 17 00:00:00 2001 From: Geovane Fedrecheski Date: Wed, 11 Oct 2023 10:52:54 +0200 Subject: [PATCH] fix: i_prepare_ead_1 pass tests --- ead/edhoc-ead-zeroconf/src/lib.rs | 75 +++++++++++++------------- examples/test-vectors-playground.ipynb | 26 ++++----- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/ead/edhoc-ead-zeroconf/src/lib.rs b/ead/edhoc-ead-zeroconf/src/lib.rs index df73a8ad..8a56677a 100644 --- a/ead/edhoc-ead-zeroconf/src/lib.rs +++ b/ead/edhoc-ead-zeroconf/src/lib.rs @@ -106,12 +106,13 @@ fn build_enc_id( ss: u8, ) -> EdhocMessageBuffer { // PRK = EDHOC-Extract(salt, IKM) - // FIXME: salt should be 0x (the zero-length byte string), but crypto backends are hardcoded to salts of size SHA256_DIGEST_LEN (32). - let salt_fixme: BytesHashLen = [0u8; SHA256_DIGEST_LEN]; + // NOTE: salt should be h'' (the zero-length byte string), but crypto backends are hardcoded to salts of size SHA256_DIGEST_LEN (32). + // using a larger but all-zeroes salt seems to generate the same result though. + let salt: BytesHashLen = [0u8; SHA256_DIGEST_LEN]; let g_xw = p256_ecdh(x, g_w); - let prk = hkdf_extract(&salt_fixme, &g_xw); + let prk = hkdf_extract(&salt, &g_xw); - let (k_1, iv_1) = compute_k_1_iv_1(&prk); // FIXME (wrong) + let (k_1, iv_1) = compute_k_1_iv_1(&prk); // plaintext = (ID_U: bstr) let mut plaintext = EdhocMessageBuffer::new(); @@ -120,7 +121,6 @@ fn build_enc_id( plaintext.len = 1 + id_u.len; // external_aad = (SS: int) - // DRAFT: ADD in Section 4.4.1: "The external_aad is wrapped in an enc_structure as defined in Section 5.3 of RFC8152." let enc_structure = encode_enc_structure(ss); // ENC_ID = 'ciphertext' of COSE_Encrypt0 @@ -207,15 +207,19 @@ fn edhoc_kdf( fn encode_ead_1(loc_w: &EdhocMessageBuffer, enc_id: &EdhocMessageBuffer) -> EdhocMessageBuffer { let mut output = EdhocMessageBuffer::new(); - output.content[0] = CBOR_TEXT_STRING; - output.content[1] = loc_w.len as u8; - output.content[2..2 + loc_w.len].copy_from_slice(&loc_w.content[..loc_w.len]); + output.content[0] = CBOR_BYTE_STRING; + // put length at output.content[1] after other sizes are known - output.content[2 + loc_w.len] = CBOR_MAJOR_BYTE_STRING + enc_id.len as u8; - output.content[3 + loc_w.len..3 + loc_w.len + enc_id.len] + output.content[2] = CBOR_TEXT_STRING; + output.content[3] = loc_w.len as u8; + output.content[4..4 + loc_w.len].copy_from_slice(&loc_w.content[..loc_w.len]); + + output.content[4 + loc_w.len] = CBOR_MAJOR_BYTE_STRING + enc_id.len as u8; + output.content[5 + loc_w.len..5 + loc_w.len + enc_id.len] .copy_from_slice(&enc_id.content[..enc_id.len]); - output.len = 3 + loc_w.len + enc_id.len; + output.len = 5 + loc_w.len + enc_id.len; + output.content[1] = (output.len - 2) as u8; output } @@ -243,63 +247,60 @@ mod test_initiator { const K_1_TV: &[u8] = &hex!("95a90f115d8fc5252849a25ba5225575"); const IV_1_TV: &[u8] = &hex!("083cb9a00da66af4f56877fcda"); - const VOUCHER_INFO_TV: &[u8] = - &hex!("58305818636f61703a2f2f656e726f6c6c6d656e742e7365727665725536b4ce1137b5687354edfac67f12bf611be1aaa1c3"); + const EAD1_VALUE_TV: &[u8] = &hex!( + "58287818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711" + ); const SS_TV: u8 = 2; #[test] - fn test_compute_k_1_iv_1() { - let x: BytesP256ElemLen = X_TV.try_into().unwrap(); - let g_w: BytesP256ElemLen = G_W_TV.try_into().unwrap(); + fn test_compute_keys() { let k_1_tv: BytesCcmKeyLen = K_1_TV.try_into().unwrap(); let iv_1_tv: BytesCcmIvLen = IV_1_TV.try_into().unwrap(); let prk_tv: BytesHashLen = PRK_TV.try_into().unwrap(); - let prk = hkdf_extract(&[0u8; SHA256_DIGEST_LEN], &p256_ecdh(&x, &g_w)); + let prk = hkdf_extract( + &[0u8; SHA256_DIGEST_LEN], + &p256_ecdh(&X_TV.try_into().unwrap(), &G_W_TV.try_into().unwrap()), + ); assert_eq!(prk, prk_tv); let (k_1, iv_1) = compute_k_1_iv_1(&prk); - assert_eq!(iv_1, iv_1_tv); assert_eq!(k_1, k_1_tv); + assert_eq!(iv_1, iv_1_tv); } #[test] fn test_build_enc_id() { - let x: BytesP256ElemLen = X_TV.try_into().unwrap(); - let id_u: EdhocMessageBuffer = ID_U_TV.try_into().unwrap(); - let g_w: BytesP256ElemLen = G_W_TV.try_into().unwrap(); let enc_id_tv: EdhocMessageBuffer = ENC_ID_TV.try_into().unwrap(); - let enc_id = build_enc_id(&x, &id_u, &g_w, SS_TV); + let enc_id = build_enc_id( + &X_TV.try_into().unwrap(), + &ID_U_TV.try_into().unwrap(), + &G_W_TV.try_into().unwrap(), + SS_TV, + ); assert_eq!(enc_id.content, enc_id_tv.content); } #[test] fn test_prepare_ead_1() { - let x: BytesP256ElemLen = X_TV.try_into().unwrap(); - let id_u: EdhocMessageBuffer = ID_U_TV.try_into().unwrap(); - let g_w: BytesP256ElemLen = G_W_TV.try_into().unwrap(); - let loc_w: EdhocMessageBuffer = LOC_W_TV.try_into().unwrap(); - let ead_1_value_tv: EdhocMessageBuffer = VOUCHER_INFO_TV.try_into().unwrap(); - let ss: u8 = EDHOC_SUPPORTED_SUITES[0]; + let ead_1_value_tv: EdhocMessageBuffer = EAD1_VALUE_TV.try_into().unwrap(); - ead_initiator_set_global_state(EADInitiatorState::new(id_u, g_w, loc_w)); + ead_initiator_set_global_state(EADInitiatorState::new( + ID_U_TV.try_into().unwrap(), + G_W_TV.try_into().unwrap(), + LOC_W_TV.try_into().unwrap(), + )); - let ead_1 = i_prepare_ead_1(&x, ss).unwrap(); + let ead_1 = i_prepare_ead_1(&X_TV.try_into().unwrap(), SS_TV).unwrap(); assert_eq!( ead_initiator_get_global_state().protocol_state, EADInitiatorProtocolState::WaitEAD2 ); assert_eq!(ead_1.label, EAD_ZEROCONF_LABEL); assert_eq!(ead_1.is_critical, true); - - // FIXME: testing only loc_w in the absense of a ENC_ID test vector - assert_eq!( - ead_1.value.unwrap().content[0..loc_w.len + 2], - ead_1_value_tv.content[0..loc_w.len + 2] - ); - // assert_eq!(ead_1.value.unwrap().content, ead_1_value_tv.content); + assert_eq!(ead_1.value.unwrap().content, ead_1_value_tv.content); } } diff --git a/examples/test-vectors-playground.ipynb b/examples/test-vectors-playground.ipynb index f929b291..6dce1a26 100644 --- a/examples/test-vectors-playground.ipynb +++ b/examples/test-vectors-playground.ipynb @@ -150,7 +150,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -165,7 +165,7 @@ "\n", "# enc_id\n", "const ENC_ID_TV: &[u8] = &hex!(\"71fb72788b180ebe332697d711\");\n", - "const SALT_FIXME_TV: &[u8] = &hex!(\"0000000000000000000000000000000000000000000000000000000000000000\");\n", + "const SALT_FIXME_TV: &[u8] = &hex!(\"\");\n", "const G_XW_TV: &[u8] = &hex!(\"e19be60432dfa2e033af21329d393a5d0d3150a6c998b4f4b951af67694dbe1a\");\n", "const PRK_TV: &[u8] = &hex!(\"04da32d221db25db701667f9d3903374a45a9b04f25d1cb481b099a480cece04\");\n", "const K_1_INFO_TV: &[u8] = &hex!(\"004010\");\n", @@ -176,22 +176,22 @@ "const ENC_STRUCTURE_TV: &[u8] = &hex!(\"8368456e637279707430404102\");\n", "\n", "# voucher_info\n", - "const VOUCHER_INFO_TV: &[u8] = &hex!(\"58285818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", - "const VOUCHER_INFO_SEQ_TV: &[u8] = &hex!(\"5818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", + "const VOUCHER_INFO_TV: &[u8] = &hex!(\"58287818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", + "const VOUCHER_INFO_SEQ_TV: &[u8] = &hex!(\"7818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", "\n", "# ead1\n", - "const EAD1_TV: &[u8] = &hex!(\"0158285818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", - "const LABEL_TV: &[u8] = &hex!(\"01\");\n", - "const VALUE_TV: &[u8] = &hex!(\"58285818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n" + "const EAD1_TV: &[u8] = &hex!(\"0158287818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n", + "const EAD1_LABEL_TV: &[u8] = &hex!(\"01\");\n", + "const EAD1_VALUE_TV: &[u8] = &hex!(\"58287818636f61703a2f2f656e726f6c6c6d656e742e7365727665724d71fb72788b180ebe332697d711\");\n" ] } ], "source": [ "\n", "def add_enc_id(tv):\n", - " salt_fixme = \"00\" * 32 # FIXME rust\n", + " salt = \"\"\n", " g_xw = p256_ecdh(tv[\"ephemeral_keys\"][\"X\"], tv[\"static_keys\"][\"G_W\"], tv[\"static_keys\"][\"_G_W_y\"])\n", - " prk = hkdf_extract(salt_fixme, g_xw)\n", + " prk = hkdf_extract(salt, g_xw)\n", " k_1_info = (cbor2.dumps(0)+cbor2.dumps(b'')+cbor2.dumps(16)).hex() # info is (0, b'', 16) # FIXME[draft] make 'length' explicit\n", " iv_1_info = (cbor2.dumps(1)+cbor2.dumps(b'')+cbor2.dumps(16)).hex() # info is (1, b'', 16) # FIXME[draft] make 'length' explicit\n", " k_1 = hkdf_expand(prk, unhexlify(k_1_info), 16)\n", @@ -203,7 +203,7 @@ " tv.update({\n", " \"enc_id\": {\n", " \"enc_id\": enc_id,\n", - " \"salt_fixme\": salt_fixme,\n", + " \"salt\": salt,\n", " \"g_xw\": g_xw,\n", " \"prk\": prk,\n", " \"k_1_info\": k_1_info,\n", @@ -219,7 +219,7 @@ "\n", "def add_voucher_info(tv):\n", " # (LOC_W: tstr, ENC_ID: bstr)\n", - " voucher_info_seq = (cbor2.dumps(unhexlify(tv[\"input\"][\"LOC_W\"])) + cbor2.dumps(unhexlify(tv[\"enc_id\"][\"enc_id\"]))).hex()\n", + " voucher_info_seq = (cbor2.dumps(unhexlify(tv[\"input\"][\"LOC_W\"]).decode()) + cbor2.dumps(unhexlify(tv[\"enc_id\"][\"enc_id\"]))).hex()\n", " voucher_info = cbor2.dumps(unhexlify(voucher_info_seq)).hex()\n", " tv.update({\n", " \"voucher_info\": {\n", @@ -236,8 +236,8 @@ " tv.update({\n", " \"ead1\": {\n", " \"ead1\": ead1,\n", - " \"label\": label,\n", - " \"value\": value,\n", + " \"ead1_label\": label,\n", + " \"ead1_value\": value,\n", " }\n", " })\n", " return tv\n",