Commit 82bb7aa1 authored by Yann Garcia's avatar Yann Garcia
Browse files

Bug fixed in f_f2345; Validation of security functions f1, f1*, f_2345 & f_5*

parent 3e98c50e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -11,6 +11,12 @@
		},
		{
			"path": "../5G-AKA-simulation-in-C"
		},
		{
			"path": "../free5gc"
		},
		{
			"path": "../free5gc.util"
		}
	],
	"settings": {
+72 −13
Original line number Diff line number Diff line
@@ -15,6 +15,40 @@ namespace LIB__NG__NAS__Functions {
    loggers::get_instance().log_to_hexa("<<< fx__set__op: OP: ", static_cast<const unsigned char*>(OP), 16);
  }

  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);
  }

  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)));

    rijndael r;
    r.rijndael_key_schedule(p_authK);
    opc op(r, OP);
    uint8_t op_c[16] = { 0x00 };
    op.compute_opc(op_c);
    p_opc = OCTETSTRING(16, static_cast<const unsigned char*>(op_c));

    loggers::get_instance().log_msg("<<< fx_compute_opc: OPC: ", p_opc);
    return 0;
  }

  INTEGER fx__rijndael__encrypt(const OCTETSTRING& p_key, const OCTETSTRING& p_plain_text, OCTETSTRING& p_cypherer_text) {
    loggers::get_instance().log_msg(">>> fx__rijndael__encrypt: p_key: ", p_key);
    loggers::get_instance().log_msg(">>> fx__rijndael__encrypt: p_plain_text: ", p_plain_text);

    rijndael r;
    r.rijndael_key_schedule(p_key);
    uint8_t cypherer_text[16] = { 0x00 };
    r.rijndael_encrypt(static_cast<const unsigned char*>(p_plain_text), cypherer_text);
    p_cypherer_text = OCTETSTRING(16, static_cast<const unsigned char*>(cypherer_text));

    loggers::get_instance().log_msg("<<< fx__rijndael__encrypt: p_cypherer_text: ", p_cypherer_text);
    return 0;
  }

  INTEGER fx__f1(const BITSTRING& p_authK, const BITSTRING& p_rand, const BITSTRING& p_sqn, const BITSTRING& p_amf, BITSTRING& p_mac_a) {
    loggers::get_instance().log_msg(">>> fx__f1: p_authK: ", bit2oct(p_authK));
    loggers::get_instance().log_msg(">>> fx__f1: p_rand: ", bit2oct(p_rand));
@@ -25,6 +59,7 @@ namespace LIB__NG__NAS__Functions {
    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);
    uint8_t rijndael_input[16] = { 0x00 };
@@ -33,6 +68,7 @@ namespace LIB__NG__NAS__Functions {
    } // End of 'for' statement
    uint8_t temp[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, temp);
    loggers::get_instance().log_to_hexa("fx__f1: Value after 1st encryption: ", temp, 16);

    OCTETSTRING sqn = bit2oct(p_sqn);
    uint8_t in1[16] = { 0x00 };
@@ -58,6 +94,8 @@ namespace LIB__NG__NAS__Functions {

    uint8_t out1[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, out1);
    loggers::get_instance().log_to_hexa("fx__f1: Value after 2sd encryption: ", out1, 16);

    for (int i = 0; i < 16; i++) {
      out1[i] ^= op_c[i];
    } // End of 'for' statement
@@ -83,6 +121,7 @@ namespace LIB__NG__NAS__Functions {
    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);
    uint8_t rijndael_input[16] = { 0x00 };
@@ -91,6 +130,7 @@ namespace LIB__NG__NAS__Functions {
    } // End of 'for' statement
    uint8_t temp[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, temp);
    loggers::get_instance().log_to_hexa("fx__f1star: Value after 1st encryption: ", temp, 16);

    OCTETSTRING sqn = bit2oct(p_sqn);
    uint8_t in1[16] = { 0x00 };
@@ -116,6 +156,8 @@ namespace LIB__NG__NAS__Functions {

    uint8_t out1[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, out1);
    loggers::get_instance().log_to_hexa("fx__f1: Value after 2sd encryption: ", out1, 16);

    for (int i = 0; i < 16; i++) {
      out1[i] ^= op_c[i];
    } // End of 'for' statement
@@ -141,6 +183,7 @@ namespace LIB__NG__NAS__Functions {
    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);
    uint8_t rijndael_input[16] = { 0x00 };
@@ -149,15 +192,19 @@ namespace LIB__NG__NAS__Functions {
    } // End of 'for' statement
    uint8_t temp[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, temp);
    loggers::get_instance().log_to_hexa("fx_f2345: Value after 1st encryption: ", temp, 16);

    // To obtain output block OUT2: XOR OPc and TEMP, rotate by r2=0, and XOR on the constant c2 (which is all zeroes except that the last bit is 1)
    for (int i = 0; i < 16; i++) {
	    rijndael_input[i] = temp[i] ^ op_c[i];
    } // End of 'for' statement
    rijndael_input[15] ^= 1;
    loggers::get_instance().log_to_hexa("fx_f2345: b entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", rijndael_input, 16);

    uint8_t out[16] = { 0x00 };
    r.rijndael_encrypt(rijndael_input, out);
    loggers::get_instance().log_to_hexa("fx_f2345: f2/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16);

    for (int i = 0; i < 16; i++) {
	    out[i] ^= op_c[i];
    } // End of 'for' statement
@@ -166,19 +213,23 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 8; i++) {
	    res[i] = out[i + 8];
    } // End of 'for' statement
    loggers::get_instance().log_to_hexa("fx_f2345: f2/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", res, 8);

    uint8_t ak[6] = { 0x00 };
    for (int i = 0; i < 6; i++) {
	    ak[i] = out[i];
    } // End of 'for' statement
    loggers::get_instance().log_to_hexa("fx_f2345: f5/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ak, 6);

    // To obtain output block OUT3: XOR OPc and TEMP, rotate by r3=32, and XOR on the constant c3 (which is all zeroes except that the next to last bit is 1)
    for (int i = 0; i < 16; i++) {
	    rijndael_input[(i + 12) % 16] = temp[i] ^ op_c[i];
    } // End of 'for' statement
    rijndael_input[15] ^= 2;

    loggers::get_instance().log_to_hexa("fx_f2345: f3/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16);
    r.rijndael_encrypt(rijndael_input, out);
    loggers::get_instance().log_to_hexa("fx_f2345: f3/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", out, 16);

    for (int i = 0; i < 16; i++) {
	    out[i] ^= op_c[i];
    } // End of 'for' statement
@@ -187,14 +238,17 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 16; i++) {
	    ck[i] = out[i];
    } // End of 'for' statement
    loggers::get_instance().log_to_hexa("fx_f2345: f3/e entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 5.x Test Set table: ", ck, 16);

    // To obtain output block OUT4: XOR OPc and TEMP, rotate by r4=64, and XOR on the constant c4 (which is all zeroes except that the 2nd from last bit is 1)
    for (int i = 0; i < 16; i++) {
	    rijndael_input[(i+8) % 16] = temp[i] ^ op_c[i];
    } // End of 'for' statement
    rijndael_input[15] ^= 4;

    loggers::get_instance().log_to_hexa("fx_f2345: f4/c entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", rijndael_input, 16);
    r.rijndael_encrypt(rijndael_input, out);
    loggers::get_instance().log_to_hexa("fx_f2345: f4/d entry in ETSI TS 135 207 V16.0.0 (2020-08) Clause 6.x Test Set table: ", out, 16);

    for (int i = 0; i < 16; i++) {
      out[i] ^= op_c[i];
    } // End of 'for' statement
@@ -203,24 +257,25 @@ namespace LIB__NG__NAS__Functions {
    for (int i = 0; i < 16; i++) {
      ik[i] = out[i];
    } // 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]));
    p_res = oct2bit(os);
    os = OCTETSTRING(16, static_cast<const unsigned char*>(&ik[0]));
    p_ik = oct2bit(os);
    os = OCTETSTRING(16, static_cast<const unsigned char*>(&ck[0]));
    p_ck = oct2bit(os);
    os = OCTETSTRING(16, static_cast<const unsigned char*>(&ik[0]));
    p_ik = oct2bit(os);
    os = OCTETSTRING(6, static_cast<const unsigned char*>(&ak[0]));
    p_ak = oct2bit(os);
    loggers::get_instance().log_msg("fx_f2345: p_res: ", p_res);
    loggers::get_instance().log_msg("fx_f2345: p_ck: ", p_ck);
    loggers::get_instance().log_msg("fx_f2345: p_ik: ", p_ik);
    loggers::get_instance().log_msg("fx_f2345: p_ak: ", p_ak);
    loggers::get_instance().log_msg("fx_f2345: p_res: ", bit2oct(p_res));
    loggers::get_instance().log_msg("fx_f2345: p_ck: ", bit2oct(p_ck));
    loggers::get_instance().log_msg("fx_f2345: p_ik: ", bit2oct(p_ik));
    loggers::get_instance().log_msg("fx_f2345: p_ak: ", bit2oct(p_ak));

    return 0;
  }

  INTEGER fx__f5star(const BITSTRING& p_authK, const BITSTRING& p_rand, BITSTRING& p_ak) {
  INTEGER fx__f5star(const BITSTRING& p_authK, const BITSTRING& p_rand, BITSTRING& p_ak_s) {
    loggers::get_instance().log_msg(">>> fx__f5star: p_authK: ", p_authK);
    loggers::get_instance().log_msg(">>> fx__f5star: p_rand: ", p_rand);

@@ -230,6 +285,8 @@ namespace LIB__NG__NAS__Functions {
    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);
    uint8_t rijndael_input[16] = { 0x00 };
@@ -237,6 +294,7 @@ namespace LIB__NG__NAS__Functions {
      rijndael_input[i] = rand[i].get_octet() ^ op_c[i];
    } // End of 'for' statement
    uint8_t temp[16] = { 0x00 };
    loggers::get_instance().log_to_hexa("fx__f5star: Before 1st encryption: ", rijndael_input, 16);
    r.rijndael_encrypt(rijndael_input, temp);

    // To obtain output block OUT5: XOR OPc and TEMP, rotate by r5=96, and XOR on the constant c5 (which is all zeroes except that the 3rd from last bit is 1)
@@ -244,9 +302,10 @@ namespace LIB__NG__NAS__Functions {
      rijndael_input[(i + 4) % 16] = temp[i] ^ op_c[i];
    } // End of 'for' statement
    rijndael_input[15] ^= 8;

    uint8_t out[16] = { 0x00 };
    loggers::get_instance().log_to_hexa("fx__f5star: Before 2sd encryption: ", rijndael_input, 16);
    r.rijndael_encrypt(rijndael_input, out);
    loggers::get_instance().log_to_hexa("fx__f5star: After 2sd encryption: ", out, 16);
    for (int i = 0; i < 16; i++) {
      out[i] ^= op_c[i];
    } // End of 'for' statement
@@ -256,8 +315,8 @@ namespace LIB__NG__NAS__Functions {
      ak[i] = out[i];
    }
    OCTETSTRING os(6, static_cast<const unsigned char*>(&ak[0]));
    p_ak = oct2bit(os);
    loggers::get_instance().log_msg("fx__f5star: p_ak: ", os);
    p_ak_s = oct2bit(os);
    loggers::get_instance().log_msg("fx__f5star: p_ak: ", bit2oct(p_ak_s));

    return 0;
  }
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ namespace CommonDefs {
   * @desc    This external function gets KEY
   * @return  The KEY
   * @see     fx_get...() return UInt64
   * @note    ETSI TS 133 220 V18.3.0 (2024-05) Annex B.2 Generic key derivation function
   */
   //INTEGER fx__KeyDerivationFunction(INTEGER const&, BITSTRING const&, OCTETSTRING const&){
   BITSTRING fx__KeyDerivationFunction(const INTEGER& p__KDF, const BITSTRING& p__Key, const OCTETSTRING& p__String){
+4 −8
Original line number Diff line number Diff line
#include "opc.hh"

void opc::compute_opc(uint8_t p_opc[16]) {
	if (!_computed) {
	_rijndael.rijndael_encrypt(_op, p_opc);
	for (uint8_t i = 0; i < 16; i++) {
		p_opc[i] ^= _op[i];
	} // End of 'for' statement
	} else {
		std::memcpy(p_opc, _op, 16);
	}
}
+2 −3
Original line number Diff line number Diff line
@@ -9,11 +9,10 @@ class opc {

  rijndael& _rijndael;
  uint8_t _op[16];
  bool _computed;

public:
  opc(rijndael& p_rijndael): _rijndael(p_rijndael), _op(), _computed{false} { std::memcpy(_op, OP, 16); std::memset(_op, 0x00, 16); };
  opc(rijndael& p_rijndael, uint8_t p_op[16]): _rijndael(p_rijndael), _computed{true} { std::memcpy(_op, p_op, 16); };
  opc(rijndael& p_rijndael): _rijndael(p_rijndael), _op() { std::memcpy(_op, OP, 16); std::memset(_op, 0x00, 16); };
  opc(rijndael& p_rijndael, uint8_t p_op[16]): _rijndael(p_rijndael) { std::memcpy(_op, p_op, 16); };
  virtual ~opc() {};

  void compute_opc(uint8_t p_opc[16]);
Loading