/****************************************************************************//**
  \file imageSecurity.h

  \brief security related abstraction for bootloader

  Copyright (c) 2015, Atmel Corporation. All rights reserved.
  Licensed under Atmel's Limited License Agreement (BitCloudTM).

  \internal
  History:
    29/05/14 Srinivasan G - Created *
*******************************************************************************/

#ifndef _IMG_SECURITY_H_
#define _IMG_SECURITY_H_

/******************************************************************************
                   Constants section
******************************************************************************/
#define OTAUHDR_FILEID                  0x0BEEF11E
#define OTAU_MIC_CRCOFFSET              0
#define OTAUHDR_FILEID_OFFSET 	        0
#define OTAUHDR_IMGTYPE_OFFSET 	        0x0C
#define OTAUHDR_HDRLEN_OFFSET	        0x06
#define OTAUHDR_TOTALFILESIZE_OFFSET    0x34

#define OTAUHDR_FILEID_OCTETLEN         (4U)
#define OTAUHDR_IMGTYPE_OCTETLEN        (2U)
#define OTAUHDR_HDRLEN_OCTETLEN         (2U)
#define OTAUHDR_TOTALFILESIZE_OCTETLEN  (4U)
#define OTAUHDR_INTEGRITYCODE_OCTETLEN  (16U)

#define OTAUHDR_IMGTYPE_IMGENC_MASK                     0x8000
#define OTAUHDR_IMGTYPE_INTCHKPRESENT_MASK              0x4000
#define OTAUHDR_IMGTYPE_ISINTCHKOTHERTHANCRC_MASK       0x1000
#define OTAUHDR_IMGTYPE_ISINTCHKENC_MASK                0x2000
#define OTAUHDR_IMGTYPE_MASK                            0xF000

#define OTAUHDR_IMGTYPE_ISIMGSEC_ENABLED(x)     (x & OTAUHDR_IMGTYPE_IMGENC_MASK)
#define OTAUHDR_IMGTYPE_ISINTCHKPRESENT(x)      (x & OTAUHDR_IMGTYPE_INTCHKPRESENT_MASK)
#define OTAUHDR_IMGTYPE_ISINTCHKENCRYPTED(x)    (x & OTAUHDR_IMGTYPE_ISINTCHKENC_MASK)
#define OTAUHDR_IMGTYPE_ISINTCHKOTHERTHANCRC(x) (x & OTAUHDR_IMGTYPE_ISINTCHKOTHERTHANCRC_MASK)

#define SECURED_DEFAULT_IMGTYPE_VALUE   (0x8000)

#define EEPROM_CHANGEKEYREQUESTED_VAL   (1U)

#define EEPROM_ISKEYCHANGED_OFFSET      (4U)
#define EEPROM_NEWKEY_START_OFFSET      (5U)
#define EEPROM_NEWIV_START_OFFSET       (21U)

#define EEPROM_NEWKEY_LENGTH            (16U)
#define EEPROM_NEWIV_LENGTH             (16U)

#define OTAU_MIC_BLOCK_COUNT            1
#define BLOCK_SIZE                      (16U)

#define IMGSEC_GET_DEFAULT_KEY(x) \
    x[0]    = 0x01; \
    x[1]    = 0x12; \
    x[2]    = 0x23; \
    x[3]    = 0x34; \
    x[4]    = 0x45; \
    x[5]    = 0x56; \
    x[6]    = 0x67; \
    x[7]    = 0x78; \
    x[8]    = 0x89; \
    x[9]    = 0x90; \
    x[0x0A] = 0x99; \
    x[0x0B] = 0x88; \
    x[0x0C] = 0x77; \
    x[0x0D] = 0x66; \
    x[0x0E] = 0x55; \
    x[0x0F] = 0x44;

#define IMGSEC_GET_DEFAULT_IV(iv) \
  memset(iv, 0, EEPROM_NEWIV_LENGTH);

/******************************************************************************
                     Prototypes section
******************************************************************************/
/**************************************************************************//**
\brief Initialize AES/Phy for access. Setup Key and IV
***************************************************************************/
void setupKeyAndPhyAccess(void);

/**************************************************************************//**
\brief Checks the following:
  1. Check if the in-file is OTAU or raw file. return failure
  2. Save control info and strip OTAU header
  3. Check if the payload is encrypted. Plain text in OTAU file is not valid
  3. If MAC/CRC is present, calculate MAC/CRC for the entire file
  4. MIC will always be 16 bytes. CRC will be 1 byte(rest 0xFF). MAC is 16 bytes 
  5. Decrypt CRC field if encrypted. Compare with calculated CRC. strip CRC.

File integrity check is used the following way:

OTA source side:
          OTA-hdr-added-encrypted-file
                      |
  calculate MAC/CRC for the entire file including header
                      |
            Encrypt the MAC/CRC(same key)
                      |
    Append the encrypted MAC/CRC at the end of the file
                      |
    Update the OTA hdr bit for the presence of MAC/CRC

OTA destination side:
          OTA-hdr-added-encrypted-file
                      |
  Read OTA hdr and see if MAC/CRC is present at the end
                      |
              Decrypt the MAC/CRC
                      |
  Except the MAC/CRC, calculate the MAC/CRC for the rest of the file
                      |
      Match with the value read from the file

\return
  true  - integrity is fine
  false - failure. can be due to one of : 
          (1) file is raw 
          (2) raw content within OTA file 
          (3) file length incorrect 
          (4) decryption key mismatch 
          (5) CRC/MAC mismatch(file possibly corrupted)
******************************************************************************/
bool otauCheckHdrAndIntegrity(void);

/**************************************************************************//**
\brief AES encryption/decryption call for 128-byte block.
        Key, mode should have been configured beforehand.
        Dummy ECB encryption should be done once before decryption to set
        the round key

\param cipher - encrypted cipher block
        numBlocks - count of the number of 16-byte blocks

\return
  true - encrypt/decrypt is fine \n
  false - encrypt/decrypt failed
***************************************************************************/
bool processBlock(uint8_t *cipher, uint8_t numBlocks);

/**************************************************************************//**
\brief On succesful swap, save the image-type in EEPROM for application use

\param[in] flag that indicates whether the call was before honoring the image or
           after
***************************************************************************/
void writeImgTypeToEeprom(bool isAfterFlashUpdate);

/**************************************************************************//**
\brief Configure key and IV to AES engine. Either reads from EEPROM
        or uses pre-defined key
***************************************************************************/
void setupKeyAndIv(void);

#endif /* _IMG_SECURITY_H_ */

// eof imgSecurity.h