/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

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

#include "test_util.h"

#include "conversions.h"
#include "secu_defs.h"

static
void eia1_encrypt(char* test_nameP, uint8_t direction, uint32_t count,
                  uint8_t bearer, uint8_t *key, uint32_t key_length, uint8_t *message,
                  uint32_t length, uint8_t *expected, uint32_t length_expected)
{
  nas_stream_cipher_t nas_cipher;
  uint8_t result[4];

  nas_cipher.direction  = direction;
  nas_cipher.count      = count;
  nas_cipher.key        = key;
  nas_cipher.key_length = key_length;
  nas_cipher.bearer     = bearer;
  nas_cipher.blength    = length;
  nas_cipher.message    = message;

  if (nas_stream_encrypt_eia1(&nas_cipher, result) != 0) {
    fail("%s Fail: nas_stream_encrypt_eia1\n", test_nameP);
  }

  if (compare_buffer(result, 4, expected, length_expected) != 0) {
    fail("%s Fail: eia1_encrypt\n",test_nameP);
  } else {
    success("%s Success: eia1_encrypt\n",test_nameP);
  }
}

void doit (void)
{
  /* Test suite from Specification 3GPP TS 33.401 V12.10.0 #C.4 128-EIA1 */

  /* Test set 1 #C.4.1 */
  eia1_encrypt(
    "Test set 1 #C.4.1",
    0, 0x38a6f056, 0x1f, HL("2bd6459f82c5b300952c49104881ff48"),
    H("33323462633938613734790000000000"),
    88,
    HL("731f1165")
  );
  /* Test set 2 #C.4.2 */
  eia1_encrypt(
    "Test set 2 #C.4.2",
    1, 0x36af6144, 0x18, HL("7e5e94431e11d73828d739cc6ced4573"),
    H("b3d3c9170a4e1632f60f861013d22d84b726b6a278d802d1eeaf1321ba5929dc "),
    254,
    HL("e3259f6f")
  );
  /* Test set 3 #C.4.3 */
  eia1_encrypt(
    "Test set 3 #C.4.3",
    0, 0xc7590ea9, 0x17, HL("d3419be821087acd02123a9248033359"),
    H("bbb057038809496bcff86d6fbc8ce5b135a06b166054f2d565be8ace75dc851e0bcdd8f07141c495872fb5d8c0c66a8b6da556663e4e461205d84580bee5bc7e"),
    511,
    HL("9a16c77d")
  );
  /* Test set 4 #C.4.4 */
  eia1_encrypt(
    "Test set 4 #C.4.4",
    1, 0x36af6144, 0x0f, HL("83fd23a244a74cf358da3019f1722635"),
    H("35c68716633c66fb750c266865d53c11ea05b1e9fa49c8398d48e1efa5909d3947902837f5ae96d5a05bc8d61ca8dbef1b13a4b4abfe4fb1006045b674bb5472 9304c382be53a5af05556176f6eaa2ef1d05e4b083181ee674cda5a485f74d7a"),
    768,
    HL("bba74492")
  );
  /* Test set 5 #C.4.5 */
  eia1_encrypt(
    "Test set 5 #C.4.5",
    0, 0x36af6144, 0x18, HL("6832a65cff4473621ebdd4ba26a921fe"),
    H("d3c53839626820717765667620323837636240981ba6824c1bfb1ab485472029b71d808ce33e2cc3c0b5fc1f3de8a6dc"),
    383,
    HL("4145e4b0")
  );
  /* Test set 6 #C.4.6 */
  eia1_encrypt(
    "Test set 6 #C.4.6",
    1, 0x7827fab2, 0x05, HL("5d0a80d8134ae19677824b671e838af4 "),
    H("70dedf2dc42c5cbd3a96f8a0b11418b3608d5733604a2cd36aabc70ce3193bb5153be2d3c06dfdb2d16e9c357158be6a41d6b861e491db3fbfeb518efcf048d7d58953730ff30c9ec470ffcd663dc34201c36addc0111c35b38afee7cfdb582e3731f8b4baa8d1a89c06e81199a9716227be344efcb436ddd0f096c064c3b5e2c399993fc77394f9e09720a811850ef23b2ee05d9e6173609d86e1c0c18ea51a012a00bb413b9cb8188a703cd6bae31cc67b34b1b00019e6a2b2a690f02671fe7c9ef8dec0094e533763478d58d2c5f5b827a0148c5948a96931acf84f465a64e62ce74007e991e37ea823fa0fb21923b79905b733b631e6c7d6860a3831ac351a9c730c52ff72d9d308eedbab21fde143a0ea17e23edc1f74cbb3638a2033aaa15464eaa733385dbbeb6fd73509b857e6a419dca1d8907af977fbac4dfa35ec"),
    2558,
    HL("0fa2b1ee")
  );
  /* Test set 7 #C.4.7 */
  eia1_encrypt(
    "Test set 7 #C.4.7",
    1, 0x296f393c, 0x0b, HL("b3120ffdb2cf6af4e73eaf2ef4ebec69"),
    H("[encoded data, 4112 characters]"),
    16448,
    HL("abf3e651")
  );
}
