/******************************************************************************/
// @copyright   Copyright Notification
//   No part may be reproduced except as authorized by written permission.
//   The copyright and the foregoing restriction extend to reproduction in all media.
//   (c) 2023, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC).
//   All rights reserved.
// @version: IWD_23wk37
// $Date: 2020-08-03 13:31:16 +0200 (Mon, 03 Aug 2020) $
// $Rev: 28340 $
/******************************************************************************/

module EAP_TypeDefs {

  import from CommonDefs all;

function f_HMAC_SHA_256(bitstring p_Key,
                          octetstring p_String) return B256_Type
  {
    return fx_KeyDerivationFunction(tsc_KDF_HMAC_SHA_256, p_Key, p_String);
  }

function f_ExtendedEAPAKA_PRF(bitstring p_Key,
                                octetstring p_String,
                                integer p_NumberOfOutputBits := 1664) return bitstring  // @sic R5s201020 sic@
  { /* PRF' defined for extended EAP-AKA (EAP-AKA') as according to RFC 5448 clause 3.4.1 */
    var integer v_BlockSize := 256;  // HMAC-SHA-256 returns 256 bits
    var integer N := (p_NumberOfOutputBits + v_BlockSize - 1) / v_BlockSize;
    var octetstring v_String;
    var bitstring v_T_i := ''B;
    var bitstring v_MK := ''B;
    var integer i;

    for (i := 0; i < N; i := i + 1) {
      v_String := bit2oct(v_T_i) & p_String & int2oct(i+1, 1);
      v_T_i := f_HMAC_SHA_256(p_Key, v_String);
      v_MK := v_MK & v_T_i;
    }
    return substr(v_MK, 0, p_NumberOfOutputBits);
  }
   
  /* Extensible Authentication Protocol (EAP) messages
   * according to RFC 5448 which refers in turn to RFC 4187 and RFC 3748
   */
  type union EAP_Message_Type {
   EAP_Request_Type akaId_Req, // RFC 4187 cl. 9.1
   EAP_Response_Type akaId_Rsp,  // RFC 4187 cl. 9.2
   EAP_Request_Type akaChallenge_Req, // RFC 4187 cl. 9.3
   EAP_Response_Type akaChallenge_Rsp,  // RFC 4187 cl. 9.4
   EAP_Response_Type akaAuthReject,  // RFC 4187 cl. 9.5
   EAP_Response_Type akaSynchronizationFailure, // RFC 4187 cl. 9.6
   EAP_Request_Type akaReauthentication_Req, // RFC 4187 cl. 9.7
   EAP_Response_Type akaReauthentication_Rsp, // RFC 4187 cl. 9.8
   EAP_Response_Type akaClientError, // RFC 4187 cl. 9.9
   EAP_Request_Type akaNotification_Req, // RFC 4187 cl. 9.10
   EAP_Response_Type akaNotification_Rsp,  // RFC 4187 cl. 9.11
   EAP_Success_Type  success, // RFC 3748 cl. 4.2
   EAP_Failure_Type  failure   // RFC 3748 cl. 4.2
  };
  
  type record EAP_Request_Type{
    O1_Type code ('01'O), // RFC 4187 cl. 8.1
    O1_Type id,    // RFC 3748 cl. 4
    O2_Type len, // RFC 3748 cl. 4 - To be computed by the encoder
    O1_Type type_ ('32'O), // RFC 5448 cl. 6.1
    O1_Type subtype, // To be set as in RFC 4187 cl. 11
    O2_Type reserved, // Set to 0 when sending, ignored by the receiver
    EAP_Attributes attributes
  };
   
  type record EAP_Response_Type {
    O1_Type code ('02'O), // RFC 4187 cl. 8.1
    O1_Type id,    // RFC 3748 cl. 4
    O2_Type len, // RFC 3748 cl. 4 - To be computed by the encoder
    O1_Type type_ ('32'O), // RFC 5448 cl. 6.1
    O1_Type subtype, // To be set as in RFC 4187 cl. 11
    O2_Type reserved, // Set to 0 when sending, ignored by the receiver
    EAP_Attributes attributes   optional // @sic R5-201116 sic@
  };
  
  type record EAP_Success_Type {
    O1_Type code ('03'O), // RFC 3748 cl. 4.2
    O1_Type id,
    O2_Type len ('0004'O) // RFC 3748 cl. 4.1
  };

  type record EAP_Failure_Type {
    O1_Type code ('04'O), // RFC 3748 cl. 4.2
    O1_Type id,
    O2_Type len ('0004'O) // RFC 3748 cl. 4.1
  };

  
  type set EAP_Attributes {
    EAP_AT_RAND rand optional,
    EAP_AT_AUTN autn optional,
    EAP_AT_RES res optional,
    EAP_AT_AUTS auts optional,
    EAP_AT_PADDING padd optional,
    EAP_AT_PERMANENT_ID_REQ permIdReq optional,
    EAP_AT_MAC mac optional,
    EAP_AT_NOTIFICATION notification optional,
    EAP_AT_ANY_ID_REQ anyIdReq optional,
    EAP_AT_IDENTITY id optional,
    EAP_AT_VERSION_LIST versionList optional,
    EAP_AT_SELECTED_VERSION selectedVersion optional,
    EAP_AT_FULLAUTH_ID_REQ fullauthIdReq optional,
    EAP_AT_COUNTER counter optional,
    EAP_AT_COUNTER_TOO_SMALL counterTooSmall optional,
    EAP_AT_NONCE_S nonceS optional,
    EAP_AT_CLIENT_ERROR_CODE clientErrorCode optional,
    EAP_AT_IV iv optional,
    EAP_AT_NEXT_PSEUDONYM nextPseudonym optional,
    EAP_AT_NEXT_REAUTH_ID nextReauthId optional,
    EAP_AT_CHECKCODE checkCode optional,
    EAP_AT_RESULT_IND resultInd optional,
    EAP_AT_KDF_INPUT kdfInput optional,
    EAP_AT_KDF kdf optional
  };
  
  type record EAP_AT_PERMANENT_ID_REQ {
    // RFC 4187 cl. 10.2
    O1_Type attributeType ('0A'O),
    O1_Type len ('01'O),
    O2_Type reserved
  };
  type record EAP_AT_ANY_ID_REQ {
    // RFC 4187 cl. 10.3
    O1_Type attributeType ('0D'O),
    O1_Type len ('01'O),
    O2_Type reserved
  };
  type record EAP_AT_FULLAUTH_ID_REQ {
    // RFC 4187 cl. 10.4
    O1_Type attributeType ('11'O),
    O1_Type len ('01'O),
    O2_Type reserved
  };
  type record EAP_AT_IDENTITY {
    // RFC 4187 cl. 10.5
    O1_Type attributeType ('0E'O),
    O1_Type len,
    O2_Type actualIdlen,
    octetstring id
  };
  type record EAP_AT_RAND {
    // RFC 4187 cl. 10.6
    O1_Type attributeType ('01'O),
    O1_Type len ('05'O),
    O2_Type reserved,
    O16_Type rand
  };
  type record EAP_AT_AUTN {
    // RFC 4187 cl. 10.7
    O1_Type attributeType ('02'O),
    O1_Type len ('05'O),
    O2_Type reserved,
    O16_Type autn
  };
  type record EAP_AT_RES {
    // RFC 4187 cl. 10.8
    O1_Type attributeType ('03'O),
    O1_Type len,
    O2_Type reslen,
    octetstring res
  };
  type record EAP_AT_AUTS {
    // RFC 4187 cl. 10.9
    O1_Type attributeType ('04'O),
    O1_Type len ('04'O),
    O14_Type auts
  };
  type record EAP_AT_NEXT_PSEUDONYM {
    // RFC 4187 cl. 10.10
    O1_Type attributeType ('84'O),
    O1_Type len,
    O2_Type actualPseudonymlen,
    octetstring nextPseudonym
  };
  type record EAP_AT_NEXT_REAUTH_ID {
    // RFC 4187 cl. 10.11
    O1_Type attributeType ('85'O),
    O1_Type len,
    O2_Type actualReAuthIdlen,
    octetstring actualReAuthId
  };
  type record EAP_AT_IV {
    // RFC 4187 cl. 10.12
    O1_Type attributeType ('81'O),
    O1_Type len ('05'O),
    O2_Type reserved,
    O16_Type autn
  };
  type record EAP_AT_ENCR_DATA {
    // RFC 4187 cl. 10.12
    O1_Type attributeType ('82'O),
    O1_Type len,
    O2_Type reserved,
    octetstring encrData
  };
  type record EAP_AT_PADDING {
    // RFC 4187 cl. 10.12
    O1_Type attributeType ('06'O),
    O1_Type len,
    octetstring padding
  };
  type record EAP_AT_CHECKCODE {
    // RFC 4187 cl. 10.13
    O1_Type attributeType ('86'O),
    O1_Type len,
    O2_Type reserved,
    octetstring checkCode optional
  };
  type record EAP_AT_RESULT_IND {
    // RFC 4187 cl. 10.14
    O1_Type attributeType ('87'O),
    O1_Type len ('01'O),
    O2_Type reserved
  };
  type record EAP_AT_MAC {
    // RFC 4187 cl. 10.15
    O1_Type attributeType ('0B'O),
    O1_Type len ('05'O),
    O2_Type reserved,
    O16_Type mac
  };
  type record EAP_AT_COUNTER {
    // RFC 4187 cl. 10.16
    O1_Type attributeType ('13'O),
    O1_Type len ('01'O),
    O2_Type counter
  };
  type record EAP_AT_COUNTER_TOO_SMALL {
    // RFC 4187 cl. 10.17
    O1_Type attributeType ('14'O),
    O1_Type len ('01'O),
    O2_Type reserved
  };
    type record EAP_AT_NONCE_S {
    // RFC 4187 cl. 10.18
    O1_Type attributeType ('15'O),
    O1_Type len ('05'O),
    O2_Type reserved,
    O16_Type nonceS
  };
  type record EAP_AT_NOTIFICATION {
    // RFC 4187 cl. 10.19
    O1_Type attributeType ('0C'O),
    O1_Type len ('01'O),
    B1_Type s,
    B1_Type p,
    B14_Type notificationCode
  };
  type record EAP_AT_CLIENT_ERROR_CODE {
    // RFC 4187 cl. 10.20
    O1_Type attributeType ('16'O),
    O1_Type len ('01'O),
    O2_Type clientErrorCode
  };
  type record EAP_AT_VERSION_LIST {
    // RFC 4187 cl. 11
    O1_Type attributeType ('0F'O),
    O1_Type len,
    octetstring versionList
  };
  type record EAP_AT_SELECTED_VERSION {
    // RFC 4187 cl. 11
    O1_Type attributeType ('10'O),
    O1_Type len,
    octetstring selectedVersion
  };
 
   type record EAP_AT_KDF_INPUT {
    // RFC 5448 cl. 3.1
    O1_Type attributeType ('17'O),
    O1_Type len,
    O2_Type actualNetworkNamelen,
    octetstring networkName
  };
  
   type record EAP_AT_KDF {
    // RFC 5448 cl. 3.2
    O1_Type attributeType ('18'O),
    O1_Type len ('01'O),
    O2_Type keyDerivationFunction // Should be '01'O for EAP-AKA' which is the one used in this protocol
  };

} with { encode "EAP Types"}
