Commit 88fa0e09 authored by Yann Garcia's avatar Yann Garcia
Browse files

Add function to force OPc instead of deriving it from OP & K

parent dbd690a7
Loading
Loading
Loading
Loading
+42 −13
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@
namespace LIB__NG__NAS__Functions {

  static uint8_t OP[16] = {0}; // FIXME FSCOM To be refined. This is a Q&D implementation
  static uint8_t OPc[16] = {0}; // FIXME FSCOM To be refined. This is a Q&D implementation
  static bool FORCE_OPC = false;

  void fx__set__op(const OCTETSTRING& p_op) {
    loggers::get_instance().log_msg(">>> fx__set__op: p_op: ", p_op);
@@ -16,14 +18,25 @@ namespace LIB__NG__NAS__Functions {
  }

  void fx__get__op(OCTETSTRING& p_op) {
    loggers::get_instance().log_msg(">>> fx__get__op: p_op: ", p_op);
    p_op = OCTETSTRING(16, static_cast<const unsigned char*>(OP));
    loggers::get_instance().log_msg("<<< fx__get__op: OP: ", p_op);
  }

  void fx__force__opc(const OCTETSTRING& p_opc) {
    loggers::get_instance().log_msg(">>> fx__force__opc: p_opc: ", p_opc);
    std::memcpy(OPc, static_cast<const unsigned char*>(p_opc), 16);
    FORCE_OPC = true;
    loggers::get_instance().log_to_hexa("<<< fx__force__opc: OPc: ", static_cast<const unsigned char*>(OPc), 16);
  }

  INTEGER fx__compute__opc(const OCTETSTRING& p_authK, OCTETSTRING& p_opc) {
    loggers::get_instance().log_msg(">>> fx_compute_opc: OP: ", OCTETSTRING(16, static_cast<const unsigned char*>(OP)));

    if (FORCE_OPC) {
      loggers::get_instance().log_msg("<<< fx_compute_opc: OPC (forced): ", OCTETSTRING(16, static_cast<const unsigned char*>(OPc)));
      p_opc = OCTETSTRING(16, static_cast<const unsigned char*>(OPc));
      return 0;
    }
    rijndael r;
    r.rijndael_key_schedule(p_authK);
    opc op(r, OP);
@@ -56,9 +69,13 @@ namespace LIB__NG__NAS__Functions {
    rijndael r;
    OCTETSTRING authK = bit2oct(p_authK);
    r.rijndael_key_schedule(authK);
    opc op(r, OP);
    OCTETSTRING os;
    fx__compute__opc(authK, os);
    uint8_t op_c[16] = { 0x00 };
    op.compute_opc(op_c);
    std::memcpy(op_c, static_cast<const unsigned char*>(os), 16);
    // opc op(r, OP);
    // uint8_t op_c[16] = { 0x00 };
    // op.compute_opc(op_c);
    loggers::get_instance().log_to_hexa("fx__f1: op_c: ", op_c, 16);

    OCTETSTRING rand = bit2oct(p_rand);
@@ -104,7 +121,7 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 8; i++) {
      mac_a[i] = out1[i];
    } // End of 'for' statement
    OCTETSTRING os(8, static_cast<const unsigned char*>(&mac_a[0]));
    os = OCTETSTRING(8, static_cast<const unsigned char*>(&mac_a[0]));
    p_mac_a = oct2bit(os);
    loggers::get_instance().log_msg("fx__f1: p_mac_a: ", os);

@@ -118,9 +135,13 @@ namespace LIB__NG__NAS__Functions {
    rijndael r;
    OCTETSTRING authK = bit2oct(p_authK);
    r.rijndael_key_schedule(authK);
    opc op(r, OP);
    OCTETSTRING os;
    fx__compute__opc(authK, os);
    uint8_t op_c[16] = { 0x00 };
    op.compute_opc(op_c);
    std::memcpy(op_c, static_cast<const unsigned char*>(os), 16);
    // opc op(r, OP);
    // uint8_t op_c[16] = { 0x00 };
    // op.compute_opc(op_c);
    loggers::get_instance().log_to_hexa("fx__f1star: op_c: ", op_c, 16);
  
    OCTETSTRING rand = bit2oct(p_rand);
@@ -166,7 +187,7 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 8; i++) {
      mac_s[i] = out1[i + 8];
    } // End of 'for' statement
    OCTETSTRING os(8, static_cast<const unsigned char*>(&mac_s[0]));
    os = OCTETSTRING(8, static_cast<const unsigned char*>(&mac_s[0]));
    p_mac_s = oct2bit(os);
    loggers::get_instance().log_msg("fx__f1star: p_mac_s: ", os);

@@ -180,9 +201,13 @@ namespace LIB__NG__NAS__Functions {
    rijndael r;
    OCTETSTRING authK = bit2oct(p_authK);
    r.rijndael_key_schedule(authK);
    opc op(r, OP);
    OCTETSTRING os;
    fx__compute__opc(authK, os);
    uint8_t op_c[16] = { 0x00 };
    op.compute_opc(op_c);
    std::memcpy(op_c, static_cast<const unsigned char*>(os), 16);
    // opc op(r, OP);
    // uint8_t op_c[16] = { 0x00 };
    // op.compute_opc(op_c);
    loggers::get_instance().log_to_hexa("fx__f2345: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", op_c, 16);
  
    OCTETSTRING rand = bit2oct(p_rand);
@@ -259,7 +284,7 @@ namespace LIB__NG__NAS__Functions {
    } // End of 'for' statement
    loggers::get_instance().log_to_hexa("fx__f2345: f4/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", ik, 16);

    OCTETSTRING os(8, static_cast<const unsigned char*>(&res[0]));
    os = OCTETSTRING(8, static_cast<const unsigned char*>(&res[0]));
    p_res = oct2bit(os);
    os = OCTETSTRING(16, static_cast<const unsigned char*>(&ck[0]));
    p_ck = oct2bit(os);
@@ -282,9 +307,13 @@ namespace LIB__NG__NAS__Functions {
    rijndael r;
    OCTETSTRING authK = bit2oct(p_authK);
    r.rijndael_key_schedule(authK);
    opc op(r, OP);
    OCTETSTRING os;
    fx__compute__opc(authK, os);
    uint8_t op_c[16] = { 0x00 };
    op.compute_opc(op_c);
    std::memcpy(op_c, static_cast<const unsigned char*>(os), 16);
    // opc op(r, OP);
    // uint8_t op_c[16] = { 0x00 };
    // op.compute_opc(op_c);
    loggers::get_instance().log_to_hexa("fx__f5star: a entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", op_c, 16);
  
    OCTETSTRING rand = bit2oct(p_rand);
@@ -312,7 +341,7 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 6; i++) {
      ak[i] = out[i];
    }
    OCTETSTRING os(6, static_cast<const unsigned char*>(&ak[0]));
    os = OCTETSTRING(6, static_cast<const unsigned char*>(&ak[0]));
    p_ak_s = oct2bit(os);
    loggers::get_instance().log_msg("fx__f5star: p_ak: ", bit2oct(p_ak_s));

+9 −6
Original line number Diff line number Diff line
@@ -68,14 +68,14 @@ system.N2_gNBaMF_P.params := "NGAP/SCTP_FILE/IP_OFFLINE/ETH(mac_src=8c554ac1eee0
#AtsImsIot_TestControl.control

#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_01
NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_02
#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_02
#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_03
#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_04
#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_REQ_05
#NG_NAS_TestCases.TC_5GNAS_AMF_AUT_ABN_01
#NG_NAS_TestCases.TC_NGNAS_AMF_AUT_SEQ_01
#NG_NAS_TestCases.TC_5GNAS_AMF_SEC_ACC_01
NG_NAS_TestCases.TC_5GNAS_AMF_SEC_REJ_01
#NG_NAS_TestCases.TC_5GNAS_AMF_SEC_REJ_01
#NG_NAS_TestCases.TC_5GNAS_AMF_DLN_ACC_01
#NG_NAS_TestCases.TC_5GNAS_AMF_REG_ACC_01
#NG_NAS_TestCases.TC_5GNAS_AMF_REG_ACC_02
@@ -121,12 +121,15 @@ NG_NAS_TestCases.TC_5GNAS_AMF_SEC_REJ_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_12_02
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_13
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_01
#G_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_14_02
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_15_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_16_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02
########NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03
# Eurecom publiction "Security Analysis of 5G Authentication"
# https://eprint.iacr.org/2022/1623.pdf
# Verdict fail
NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_01
NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_02
NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_17_03
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_18_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_19_01
#NG_NAS_TestCases.TC_5G_AKA_CRYPTO_FUNCTIONS_TEST_20_01
+6 −6
Original line number Diff line number Diff line
@@ -2050,14 +2050,14 @@ module NG_NAS_TestCases {
            v_auth_params.XRES       := v_xres;
            v_auth_params.XRESLength := lengthof(v_xres);
            
            var B64_Type v_RESstar  := oct2bit('03F8627A00448408'O);
            var B64_Type v_XRESstar := oct2bit('6F35398F7C56DF32'O);
            var B64_Type v_RESstar  := oct2bit('53D333860BCDFA0C'O);
            var B64_Type v_XRESstar := oct2bit('55FB0452F974E0C9'O);

            var B128_Type v_res := f_NG_Authentication_A4(v_PLMN, v_auth_params, tsc_KDF_HMAC_SHA_256, v_Ks, v_NID);
            var B64_Type v_RESstar_computed := substr(v_res, 0, 64);
            var B64_Type v_XRESstar_computed := substr(v_res, 64, 64);
            log("v_RESstar_computed =", v_RESstar_computed);
            log("v_XRESstar_computed =", v_XRESstar_computed);
            log("v_RESstar_computed =", bit2oct(v_RESstar_computed));
            log("v_XRESstar_computed =", bit2oct(v_XRESstar_computed));
            if (not(match(v_RESstar_computed, v_RESstar))) {
                log("*** " & __SCOPE__ & ": ERROR: 'v_RESstar_computed' did not return the expected value. ***");
                setverdict(fail);
@@ -2085,14 +2085,14 @@ module NG_NAS_TestCases {

            // From Kontron Wireshark captures: UI=001014444333000
            var O16_Type  v_K      := '00000000000000000000000000000000'O; // The long-term key: Subscriber key
            var O16_Type  v_op     := '00000000000000000000000000000000'O; // Operator Variant Algorithm Configuration Field
            var O16_Type  v_opc    := '00000000000000000000000000000000'O; // Operator Variant Algorithm Configuration Field
            var B128_Type v_rand   := oct2bit('807df0fdd3ef28786d10f425df603f3b'O);
            var B48_Type  v_sqn_ak := oct2bit('b22bfb46d847'O);
            var B16_Type  v_amf    := oct2bit('8000'O); // AMF: Authentication Management Field
            var B64_Type v_mac_a   := oct2bit('5cd041c2fc08f6da'O);
            var NAS_PlmnId v_PLMN  := '00f110'O; // PLMN ID: 001-01

            f_set_op(v_op);
            f_force_opc(v_opc);

            var B64_Type v_mac_a_computed;
            var integer v_result := f_f1(oct2bit(v_K), v_rand, v_sqn_ak, v_amf, v_mac_a_computed);
+29 −10
Original line number Diff line number Diff line
@@ -732,31 +732,49 @@ module LIB_NG_NAS_Functions {
            return substr(p_autn, 64, 64);
        }

        /**
         * @desc Set operator variant algorithm configuration
         * @param [in] p_op Operator variant algorithm configuration
         * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 2
         */
        function f_set_op(in O16_Type p_op) {
            fx_set_op(p_op);
        }
        /**
         * @desc Get operator variant algorithm configuration
         * @param [out] p_op Operator variant algorithm configuration
         * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 2
         */
        function f_get_op(out O16_Type p_op) {
            fx_get_op(p_op);
        }
        /**
         * @desc Derived OP from from OP and K (subscriber key)
         * @param [in] p_authK The subscriber key
         * @param [out] p_opc The derived OP from from OP and K
         * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 2
         */
        function f_compute_opc(in O16_Type p_authK, out O16_Type p_opc) return integer {
            return fx_compute_opc(p_authK, p_opc);
        }
        /**
         * @desc Force the value of OPc. In this case, OP is ignored.
         * @param [in] p_opc The derived OP from from OP and K
         * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 2
         */
        function f_force_opc(in O16_Type p_opc) {
            fx_force_opc(p_opc);
        }






        /**
         * @desc Encryption according to the cryptographic kernel function Rijndael.
         * @see ETSI TS 135 207 V16.0.0 (2020-08) Clause 3
         */
        external function fx_rijndael_encrypt(in octetstring p_key, in octetstring p_plain_text, out octetstring p_cypherer_text) return integer;
        function f_rijndael_encrypt(in octetstring p_key, in octetstring p_plain_text, out octetstring p_cypherer_text) return integer {
            return fx_rijndael_encrypt(p_key, p_plain_text, p_cypherer_text);
        }






        function f_f1(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_a) return integer {
            return fx_f1(p_authK, p_rand, v_sqn, v_amf, v_mac_a);
        }
@@ -775,6 +793,7 @@ module LIB_NG_NAS_Functions {

        external function fx_set_op(in O16_Type p_op);
        external function fx_get_op(out O16_Type p_op);
        external function fx_force_opc(in O16_Type p_op);
        external function fx_compute_opc(in O16_Type p_authK, out O16_Type p_opc) return integer;
        external function fx_f1(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_a) return integer;
        external function fx_f1star(in B128_Type p_authK, in B128_Type p_rand, in B48_Type v_sqn, in B16_Type v_amf, out B64_Type v_mac_s) return integer;