/*
 * (c) Copyright 2015 Samsung Research America, Inc.
 *                  All rights reserved
 *
 *  MPS Lab
 *
 * File         : aes_hsha2_aead.h
 * Author       : r.kothari@samsung.com
 * Creation Date: Apr 15, 2016
 * Co-Author: zheng.z@samsung.com
 * Improved Date: Sep 6, 2016
 *
 * Description  : Implementation of AES_CBC_HMAC_SHA2 Algorithms as described
 *                in RFC 7518 JSON Web Algorithm (JWA) Section 5.2
 *                 https://tools.ietf.org/pdf/rfc7518.pdf
 *
 */
/*
 * Copyright (C) 2016 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Mobile Communication Division,
 * Digital Media & Communications Business, Samsung Electronics Co., Ltd.
 *
 * This software and its documentation are confidential and proprietary
 * information of Samsung Electronics Co., Ltd.  No part of the software and
 * documents may be copied, reproduced, transmitted, translated, or reduced to
 * any electronic medium or machine-readable form without the prior written
 * consent of Samsung Electronics.
 *
 * Samsung Electronics makes no representations with respect to the contents,
 * and assumes no responsibility for any errors that might appear in the
 * software and documents. This publication and the contents hereof are subject
 * to change without notice.
 */
#ifndef AES_HSHA2_AEAD_H
#define AES_HSHA2_AEAD_H

//#define DEBUG_AES_HSHA2_AEAD 1

#define A128CBC_HS256_KEY_SIZE 32
#define A192CBC_HS384_KEY_SIZE 48
#define A256CBC_HS512_KEY_SIZE 64

#define A128CBC_HS256_TAG_SIZE 16
#define A192CBC_HS384_TAG_SIZE 24
#define A256CBC_HS512_TAG_SIZE 32

#define AES_HSHA2_MIN_TAG_SIZE A128CBC_HS256_TAG_SIZE
#define AES_HSHA2_MAX_TAG_SIZE A256CBC_HS512_TAG_SIZE

#define AES_HSHA2_IV_SIZE      16
#define AES_GCM_IV_SIZE        12
#define AES_HSHA2_MAX_BUF_SIZE 1024*32

#define AES_HSHA2_AL_SIZE 8


#define AES_OK                            0x00000000

/* General Errors */
#define AES_GEN_ERROR_INTERNAL                      0x00000101
#define AES_GEN_ERROR_INVALID_INPUT_PARAM               0x00000102
#define AES_GEN_ERROR_INVALID_INPUT_SIZE            0x00000103
#define AES_GEN_ERROR_INVALID_OUTPUT_PARAM_SIZE         0x00000104
#define AES_GEN_ERROR_BUFFER_OVERFLOW                   0x00000105
#define AES_GEN_ERROR_BUFFER_NULL               0x00000106
#define AES_GEN_ERROR_INSUFFICIENT_BUFFER           0x00000107
#define AES_GEN_ERROR_MISSING_DATA              0x00000108

/* Cryptography (Cert & AES) Errors */
#define AES_CRYPT_ERROR_VERIFY_CERT                 0x00000121
#define AES_CRYPT_ERROR_CERT_PARSE_FAILED           0x00000122
#define AES_CRYPT_ERROR_KEY_PARSE_FAILED            0x00000123
#define AES_CRYPT_ERROR_UNWRAP_FAILED               0x00000124
#define AES_CRYPT_ERROR_WRAP_FAILED                 0x00000125
#define AES_CRYPT_ERROR_UNEXPECTED_DATA             0x00000126
#define AES_CRYPT_ERROR_MODULUS_ERROR               0x00000127
#define AES_CRYPT_ERROR_EXPONENT_ERROR              0x00000128
#define AES_CRYPT_ERROR_ENCRYPT_ERROR               0x00000129
#define AES_CRYPT_ERROR_HMAC_ERROR                      0x00000130
#define AES_CRYPT_ERROR_BASE64_DECODE_FAILED            0x00000131
#define AES_CRYPT_ERROR_BASE64_ENCODE_FAILED            0x00000132
#define AES_CRYPT_ERROR_GET_RANDOM_FAILED               0x00000133
#define AES_CRYPT_ERROR_DECRYPT_ERROR               0x00000134

typedef enum
{
    A128CBC_HS256,
    A192CBC_HS384, //Not supported
    A256CBC_HS512  //Not supported
} aead_algo_type;

typedef struct
{
    uint8_t *key;
    uint32_t key_len;
    uint8_t *iv;
    uint32_t iv_len;
    uint8_t *aad;
    uint32_t aad_len;
    uint8_t *plain_text;
    uint32_t plain_text_len;

} aead_enc_in_params;

typedef struct
{
    uint8_t  *cipher_text;
    uint32_t *cipher_text_len;
    uint8_t  *tag;
    uint32_t *tag_len;

} aead_enc_out_params;

uint32_t
aes_hsha2_aead_encrypt (aead_algo_type algo,
                        aead_enc_in_params  *in,
                        aead_enc_out_params *out);

typedef struct
{
    uint8_t *key;
    uint32_t key_len;
    uint8_t *iv;
    uint32_t iv_len;
    uint8_t *aad;
    uint32_t aad_len;
    uint8_t *tag;
    uint32_t tag_len;
    uint8_t *cipher_text;
    uint32_t cipher_text_len;

} aead_dec_in_params;

typedef struct
{
    uint8_t *plain_text;
    uint32_t *plain_text_len;

} aead_dec_out_params;

uint32_t
aes_hsha2_aead_decrypt (aead_algo_type algo,
                        aead_dec_in_params  *in,
                        aead_dec_out_params *out);

#endif
