Commit 42ca4498 authored by Owen Kirby's avatar Owen Kirby Committed by Niels Möller

CCM cipher mode.

parent 609a8dae
2014-03-23 Niels Möller <nisse@lysator.liu.se>
From Owen Kirby:
* ccm.c: New file.
* ccm.h: New file.
* ccm-aes128.c: New file.
* ccm-aes192.c: New file.
* ccm-aes256.c: New file.
* Makefile.in (nettle_SOURCES): Added ccm source files.
(HEADERS): Added ccm.h.
* testsuite/ccm-test.c: New file.
* testsuite/Makefile.in (TS_NETTLE_SOURCES): Added ccm-test.c.
2014-03-20 Niels Möller <nisse@lysator.liu.se>
From Joachim Strömbergson:
......
......@@ -87,6 +87,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
camellia256-set-decrypt-key.c \
camellia256-meta.c \
cast128.c cast128-meta.c cbc.c \
ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c \
chacha-crypt.c chacha-core-internal.c \
chacha-poly1305.c chacha-poly1305-meta.c \
chacha-set-key.c chacha-set-nonce.c \
......@@ -167,7 +168,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
base16.h base64.h buffer.h camellia.h cast128.h \
cbc.h chacha.h chacha-poly1305.h ctr.h \
cbc.h ccm.h chacha.h chacha-poly1305.h ctr.h \
des.h des-compat.h dsa.h eax.h ecc-curve.h ecc.h ecdsa.h \
gcm.h gosthash94.h hmac.h \
knuth-lfib.h \
......
/* ccm-aes128.c
*
* Counter with CBC-MAC mode using AES128 as the underlying cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2014 Exegin Technologies Limited
* Copyright (C) 2014 Owen Kirby
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes.h"
#include "ccm.h"
void
ccm_aes128_set_key(struct ccm_aes128_ctx *ctx, const uint8_t *key)
{
aes128_set_encrypt_key(&ctx->cipher, key);
}
void
ccm_aes128_set_nonce(struct ccm_aes128_ctx *ctx,
size_t length, const uint8_t *nonce,
size_t authlen, size_t msglen, size_t taglen)
{
ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
length, nonce, authlen, msglen, taglen);
}
void
ccm_aes128_update(struct ccm_aes128_ctx *ctx,
size_t length, const uint8_t *data)
{
ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
length, data);
}
void
ccm_aes128_encrypt(struct ccm_aes128_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
length, dst, src);
}
void
ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
length, dst, src);
}
void
ccm_aes128_digest(struct ccm_aes128_ctx *ctx,
size_t length, uint8_t *digest)
{
ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
length, digest);
}
void
ccm_aes128_encrypt_message(struct ccm_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
int
ccm_aes128_decrypt_message(struct ccm_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
return ccm_decrypt_message(&ctx->cipher,
(nettle_cipher_func *) aes128_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
/* ccm-aes192.c
*
* Counter with CBC-MAC mode using AES192 as the underlying cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2014 Exegin Technologies Limited
* Copyright (C) 2014 Owen Kirby
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes.h"
#include "ccm.h"
void
ccm_aes192_set_key(struct ccm_aes192_ctx *ctx, const uint8_t *key)
{
aes192_set_encrypt_key(&ctx->cipher, key);
}
void
ccm_aes192_set_nonce(struct ccm_aes192_ctx *ctx, size_t length, const uint8_t *nonce,
size_t authlen, size_t msglen, size_t taglen)
{
ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
length, nonce, authlen, msglen, taglen);
}
void
ccm_aes192_update(struct ccm_aes192_ctx *ctx,
size_t length, const uint8_t *data)
{
ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
length, data);
}
void
ccm_aes192_encrypt(struct ccm_aes192_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
length, dst, src);
}
void
ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
length, dst, src);
}
void
ccm_aes192_digest(struct ccm_aes192_ctx *ctx,
size_t length, uint8_t *digest)
{
ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
length, digest);
}
void
ccm_aes192_encrypt_message(struct ccm_aes192_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
int
ccm_aes192_decrypt_message(struct ccm_aes192_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
return ccm_decrypt_message(&ctx->cipher,
(nettle_cipher_func *) aes192_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
/* ccm-aes256.c
*
* Counter with CBC-MAC mode using AES256 as the underlying cipher.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2014 Exegin Technologies Limited
* Copyright (C) 2014 Owen Kirby
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "aes.h"
#include "ccm.h"
void
ccm_aes256_set_key(struct ccm_aes256_ctx *ctx, const uint8_t *key)
{
aes256_set_encrypt_key(&ctx->cipher, key);
}
void
ccm_aes256_set_nonce(struct ccm_aes256_ctx *ctx,
size_t length, const uint8_t *nonce,
size_t authlen, size_t msglen, size_t taglen)
{
ccm_set_nonce(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
length, nonce, authlen, msglen, taglen);
}
void
ccm_aes256_update(struct ccm_aes256_ctx *ctx,
size_t length, const uint8_t *data)
{
ccm_update(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
length, data);
}
void
ccm_aes256_encrypt(struct ccm_aes256_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
length, dst, src);
}
void
ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_decrypt(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
length, dst, src);
}
void
ccm_aes256_digest(struct ccm_aes256_ctx *ctx,
size_t length, uint8_t *digest)
{
ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
length, digest);
}
void
ccm_aes256_encrypt_message(struct ccm_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
int
ccm_aes256_decrypt_message(struct ccm_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
return ccm_decrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
nlength, nonce, alength, adata,
tlength, clength, dst, src);
}
/* ccm.c
*
* Counter with CBC-MAC mode, specified by NIST,
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
*
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2014 Exegin Technologies Limited
* Copyright (C) 2014 Owen Kirby
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "ccm.h"
#include "ctr.h"
#include "memxor.h"
#include "nettle-internal.h"
#include "macros.h"
/*
* The format of the CCM IV (for both CTR and CBC-MAC) is: flags | nonce | count
* flags = 1 octet
* nonce = N octets
* count >= 1 octet
*
* such that:
* sizeof(flags) + sizeof(nonce) + sizeof(count) == 1 block
*/
#define CCM_FLAG_L 0x07
#define CCM_FLAG_M 0x38
#define CCM_FLAG_ADATA 0x40
#define CCM_FLAG_RESERVED 0x80
#define CCM_FLAG_GET_L(_x_) (((_x_) & CCM_FLAG_L) + 1)
#define CCM_FLAG_SET_L(_x_) (((_x_) - 1) & CCM_FLAG_L)
#define CCM_FLAG_SET_M(_x_) ((((_x_) - 2) << 2) & CCM_FLAG_M)
#define CCM_OFFSET_FLAGS 0
#define CCM_OFFSET_NONCE 1
#define CCM_L_SIZE(_nlen_) (CCM_BLOCK_SIZE - CCM_OFFSET_NONCE - (_nlen_))
#define CCM_L_MAX_SIZE (CCM_FLAG_L+1)
#define CCM_IV_MAX_SIZE (CCM_BLOCK_SIZE - CCM_OFFSET_NONCE - 1)
#define CCM_IV_MIN_SIZE (CCM_BLOCK_SIZE - CCM_OFFSET_NONCE - CCM_L_MAX_SIZE)
/*
* The data input to the CBC-MAC: L(a) | adata | padding | plaintext | padding
*
* blength is the length of data that has been added to the CBC-MAC modulus the
* cipher block size. If the value of blength is non-zero then some data has
* been XOR'ed into the CBC-MAC, and we will need to pad the block (XOR with 0),
* and iterate the cipher one more time.
*
* The end of adata is detected implicitly by the first call to the encrypt()
* and decrypt() functions, and will call ccm_pad() to insert the padding if
* necessary. Because of the underlying CTR encryption, the encrypt() and
* decrypt() functions must be called with a multiple of the block size and
* therefore blength should be zero on all but the first call.
*
* Likewise, the end of the plaintext is implicitly determined by the first call
* to the digest() function, which will pad if the final CTR encryption was not
* a multiple of the block size.
*/
static void
ccm_pad(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f)
{
if (ctx->blength) f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
ctx->blength = 0;
}
static void
ccm_build_iv(uint8_t *iv, size_t noncelen, const uint8_t *nonce,
uint8_t flags, size_t count)
{
unsigned int i;
/* Sanity check the nonce length. */
assert(noncelen >= CCM_IV_MIN_SIZE);
assert(noncelen <= CCM_IV_MAX_SIZE);
/* Generate the IV */
iv[CCM_OFFSET_FLAGS] = flags | CCM_FLAG_SET_L(CCM_L_SIZE(noncelen));
memcpy(&iv[CCM_OFFSET_NONCE], nonce, noncelen);
for (i=(CCM_BLOCK_SIZE - 1); i >= (CCM_OFFSET_NONCE + noncelen); i--) {
iv[i] = count & 0xff;
count >>= 8;
}
/* Ensure the count was not truncated. */
assert(!count);
}
void
ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
size_t length, const uint8_t *nonce,
size_t authlen, size_t msglen, size_t taglen)
{
/* Generate the IV for the CTR and CBC-MAC */
ctx->blength = 0;
ccm_build_iv(ctx->tag.b, length, nonce, CCM_FLAG_SET_M(taglen), msglen);
ccm_build_iv(ctx->ctr.b, length, nonce, 0, 1);
/* If no auth data, encrypt B0 and skip L(a) */
if (!authlen) {
f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
return;
}
/* Encrypt B0 (with the adata flag), and input L(a) to the CBC-MAC. */
ctx->tag.b[CCM_OFFSET_FLAGS] |= CCM_FLAG_ADATA;
f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
if (authlen >= (0x01ULL << 32)) {
/* Encode L(a) as 0xff || 0xff || <64-bit integer> */
ctx->tag.b[ctx->blength++] ^= 0xff;
ctx->tag.b[ctx->blength++] ^= 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 56) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 48) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 40) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 32) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff;
}
else if (authlen >= ((0x1ULL << 16) - (0x1ULL << 8))) {
/* Encode L(a) as 0xff || 0xfe || <32-bit integer> */
ctx->tag.b[ctx->blength++] ^= 0xff;
ctx->tag.b[ctx->blength++] ^= 0xfe;
ctx->tag.b[ctx->blength++] ^= (authlen >> 24) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 16) & 0xff;
}
ctx->tag.b[ctx->blength++] ^= (authlen >> 8) & 0xff;
ctx->tag.b[ctx->blength++] ^= (authlen >> 0) & 0xff;
}
void
ccm_update(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
size_t length, const uint8_t *data)
{
const uint8_t *end = data + length;
/* If we don't have enough to fill a block, save the data for later. */
if ((ctx->blength + length) < CCM_BLOCK_SIZE) {
memxor(&ctx->tag.b[ctx->blength], data, length);
ctx->blength += length;
return;
}
/* Process a partially filled block. */
if (ctx->blength) {
memxor(&ctx->tag.b[ctx->blength], data, CCM_BLOCK_SIZE - ctx->blength);
data += (CCM_BLOCK_SIZE - ctx->blength);
f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
}
/* Process full blocks. */
while ((data + CCM_BLOCK_SIZE) < end) {
memxor(ctx->tag.b, data, CCM_BLOCK_SIZE);
f(cipher, CCM_BLOCK_SIZE, ctx->tag.b, ctx->tag.b);
data += CCM_BLOCK_SIZE;
} /* while */
/* Save leftovers for later. */
ctx->blength = (end - data);
if (ctx->blength) memxor(&ctx->tag.b, data, ctx->blength);
}
/*
* Because of the underlying CTR mode encryption, when called multiple times
* the data in intermediate calls must be provided in multiples of the block
* size.
*/
void
ccm_encrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
size_t length, uint8_t *dst, const uint8_t *src)
{
ccm_pad(ctx, cipher, f);
ccm_update(ctx, cipher, f, length, src);
ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
}
/*
* Because of the underlying CTR mode decryption, when called multiple times
* the data in intermediate calls must be provided in multiples of the block
* size.
*/
void
ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
size_t length, uint8_t *dst, const uint8_t *src)
{
ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
ccm_pad(ctx, cipher, f);
ccm_update(ctx, cipher, f, length, dst);
}
void
ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
size_t length, uint8_t *digest)
{
int i = CCM_BLOCK_SIZE - CCM_FLAG_GET_L(ctx->ctr.b[CCM_OFFSET_FLAGS]);
assert(length <= CCM_BLOCK_SIZE);
while (i < CCM_BLOCK_SIZE) ctx->ctr.b[i++] = 0;
ccm_pad(ctx, cipher, f);
ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, digest, ctx->tag.b);
}
void
ccm_encrypt_message(const void *cipher, nettle_cipher_func *f,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata, size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
struct ccm_ctx ctx;
uint8_t *tag = dst + (clength-tlength);
assert(clength >= tlength);
ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, clength-tlength, tlength);
ccm_update(&ctx, cipher, f, alength, adata);
ccm_encrypt(&ctx, cipher, f, clength-tlength, dst, src);
ccm_digest(&ctx, cipher, f, tlength, tag);
}
int
ccm_decrypt_message(const void *cipher, nettle_cipher_func *f,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata, size_t tlength,
size_t clength, uint8_t *dst, const uint8_t *src)
{
struct ccm_ctx ctx;
uint8_t tag[CCM_BLOCK_SIZE];
assert(clength >= tlength);
ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, clength-tlength, tlength);
ccm_update(&ctx, cipher, f, alength, adata);
ccm_decrypt(&ctx, cipher, f, clength-tlength, dst, src);
ccm_digest(&ctx, cipher, f, tlength, tag);
return (memcmp(tag, src + (clength-tlength), tlength) == 0);
}
/* ccm.h
*
* Counter with CBC-MAC mode, specified by NIST,
* http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
*
* NIST SP800-38C doesn't specify the particular formatting and counter generation
* algorithm for CCM, but it does include an example algorithm. This example
* has become the de-factor standard, and has been adopted by both the IETF and
* IEEE across a wide variety of protocols.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2014 Exegin Technologies Limited
* Copyright (C) 2014 Owen Kirby
*
* Contributed by Owen Kirby
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#ifndef NETTLE_CCM_H_INCLUDED
#define NETTLE_CCM_H_INCLUDED
#include "aes.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define ccm_set_nonce nettle_ccm_set_nonce