/*
 *   AES-128 and AES-CMAC (RFC 4493).
 *
 *   Portions Copyright RISC OS Developments 2019+, credited to the RISC OS One Project.
 *   Placed in the public domain.
 *
 *   SMB 3.x signs with AES-CMAC rather than the HMAC-SHA256 that SMB 2.x
 *   uses, so only the encryption direction is needed - CMAC never
 *   decrypts - and only the 128 bit key size.  Nothing else here wants a
 *   block cipher, so this is the smallest implementation that is still
 *   readable rather than the fastest one.
 */

#ifndef __AES_H
#define __AES_H

#include <stdlib.h>

#define AES_BLOCKLEN (16)
#define AES_KEYLEN   (16)       /* 128 bit keys only */
#define AES_ROUNDS   (10)

typedef struct
{
    unsigned char round_key[(AES_ROUNDS + 1) * AES_BLOCKLEN];
} aes_key_t;

void AESSetKey(aes_key_t *k, const unsigned char key[AES_KEYLEN]);

void AESEncryptBlock(const aes_key_t *k,
                     const unsigned char in[AES_BLOCKLEN],
                     unsigned char out[AES_BLOCKLEN]);

void aes_cmac(const unsigned char key[AES_KEYLEN],
              const void *data, size_t len,
              unsigned char mac[AES_BLOCKLEN]);

void aes_ccm_encrypt(const unsigned char key[AES_KEYLEN],
                     const unsigned char *nonce, size_t nonce_len,
                     const unsigned char *aad, size_t aad_len,
                     unsigned char *data, size_t len,
                     unsigned char tag[AES_BLOCKLEN]);
/*
    Encrypt data in place and produce the tag that authenticates both it
    and the additional data.  The nonce must be shorter than a block; SMB
    3.0 and 3.0.2 use eleven bytes.
*/

int aes_ccm_decrypt(const unsigned char key[AES_KEYLEN],
                    const unsigned char *nonce, size_t nonce_len,
                    const unsigned char *aad, size_t aad_len,
                    unsigned char *data, size_t len,
                    const unsigned char tag[AES_BLOCKLEN]);
/*
    The reverse.  Returns non-zero if the tag was right; on zero the
    buffer holds whatever the wrong key produced and must be discarded.
*/

#endif
