/*
 * Licensed to Open Source Radio Access Network(OS-RAN) Alliance and OAI
 * Software Alliance under one or more contributor license agreements. The
 * initial OpenXG series projects are derided from OAI projects, the files from
 * OAI projects are all in compliance with OAI Public License, Version 1.1.
 * codes and files developed from OpenXG projects and from OS-RAN Alliance
 * are all under OS-RAN licenses; you may not use this file except in compliance
 * with the license.  You may get a copy of the license at:
 *	http://www.openxg.org.cn/?falu_69.html
 * For more information about OpenXG, please contact:
 * contact@openxg.org.cn
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include "security_types.h"
#include "secu_defs.h"
#include "secu_defs.h"

/*!
 @brief Derive the kNASenc from kasme and perform truncate on the generated key
 to reduce his size to 128 bits. Definition of the derivation function can be
 found in 3GPP TS.33401 #A.7
 @param[in] nas_alg_type NAS algorithm distinguisher
 @param[in] nas_enc_alg_id NAS encryption/integrity algorithm identifier.
 Possible values are:
 - 0 for EIA0 algorithm (Null Integrity Protection algorithm)
 - 1 for 128-EIA1 SNOW 3G
 - 2 for 128-EIA2 AES
 @param[in] kasme Key for MME as provided by AUC
 @param[out] knas Pointer to reference where output of KDF will be stored.
 NOTE: knas is dynamically allocated by the KDF function
 */
int derive_key_nas(
    algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
    const uint8_t* kasme_32, uint8_t* knas) {
  uint8_t s[7]    = {0};
  uint8_t out[32] = {0};

  /*
   * FC
   */
  s[0] = FC_ALG_KEY_DER;
  /*
   * P0 = algorithm type distinguisher
   */
  s[1] = (uint8_t)(nas_alg_type & 0xFF);
  /*
   * L0 = length(P0) = 1
   */
  s[2] = 0x00;
  s[3] = 0x01;
  /*
   * P1
   */
  s[4] = nas_enc_alg_id;
  /*
   * L1 = length(P1) = 1
   */
  s[5] = 0x00;
  s[6] = 0x01;
  kdf(kasme_32, 32, &s[0], 7, &out[0], 32);
  memcpy(knas, &out[31 - 16 + 1], 16);
  return 0;
}
