diff options
author | Owen Kirby <osk@exegin.com> | 2014-03-23 14:10:12 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2014-03-23 14:10:12 +0100 |
commit | 42ca44984b140fe00da032b37349081aa8048b1f (patch) | |
tree | bbb8067ea1eae11b62414613ded0c7918402bb54 /ccm.h | |
parent | 609a8daee519d17b1e66aefae2ad4e81ba94539b (diff) | |
download | nettle-42ca44984b140fe00da032b37349081aa8048b1f.tar.gz |
CCM cipher mode.
Diffstat (limited to 'ccm.h')
-rw-r--r-- | ccm.h | 281 |
1 files changed, 281 insertions, 0 deletions
@@ -0,0 +1,281 @@ +/* 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 +#define ccm_update nettle_ccm_update +#define ccm_encrypt nettle_ccm_encrypt +#define ccm_decrypt nettle_ccm_decrypt +#define ccm_digest nettle_ccm_digest +#define ccm_encrypt_message nettle_ccm_encrypt_message +#define ccm_decrypt_message nettle_ccm_decrypt_message + +#define ccm_aes128_set_key nettle_ccm_aes128_set_key +#define ccm_aes128_set_nonce nettle_ccm_aes128_set_nonce +#define ccm_aes128_update nettle_ccm_aes128_update +#define ccm_aes128_encrypt nettle_ccm_aes128_encrypt +#define ccm_aes128_decrypt nettle_ccm_aes128_decrypt +#define ccm_aes128_digest nettle_ccm_aes128_digest +#define ccm_aes128_encrypt_message nettle_ccm_aes128_encrypt_message +#define ccm_aes128_decrypt_message nettle_ccm_aes128_decrypt_message + +#define ccm_aes192_set_key nettle_ccm_aes192_set_key +#define ccm_aes192_set_nonce nettle_ccm_aes192_set_nonce +#define ccm_aes192_update nettle_ccm_aes192_update +#define ccm_aes192_encrypt nettle_ccm_aes192_encrypt +#define ccm_aes192_decrypt nettle_ccm_aes192_decrypt +#define ccm_aes192_digest nettle_ccm_aes192_digest +#define ccm_aes192_encrypt_message nettle_ccm_aes192_encrypt_message +#define ccm_aes192_decrypt_message nettle_ccm_aes192_decrypt_message + +#define ccm_aes256_set_key nettle_ccm_aes256_set_key +#define ccm_aes256_set_nonce nettle_ccm_aes256_set_nonce +#define ccm_aes256_update nettle_ccm_aes256_update +#define ccm_aes256_encrypt nettle_ccm_aes256_encrypt +#define ccm_aes256_decrypt nettle_ccm_aes256_decrypt +#define ccm_aes256_digest nettle_ccm_aes256_digest +#define ccm_aes256_encrypt_message nettle_ccm_aes256_encrypt_message +#define ccm_aes256_decrypt_message nettle_ccm_aes256_decrypt_message + +/* For CCM, the block size of the block cipher shall be 128 bits. */ +#define CCM_BLOCK_SIZE 16 + +/* Per-message state */ +struct ccm_ctx { + union nettle_block16 ctr; /* Counter for CTR encryption. */ + union nettle_block16 tag; /* CBC-MAC message tag. */ + /* Length of data processed by the CBC-MAC modulus the block size */ + unsigned int blength; +}; + +/* + * CCM mode requires the adata and message lengths when building the IV, which + * prevents streaming processing and it incompatible with the AEAD API. + */ +void +ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t noncelen, const uint8_t *nonce, + size_t authlen, size_t msglen, size_t taglen); + +void +ccm_update(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data); + +void +ccm_encrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest); + +/* + * All-in-one encryption and decryption API: + * tlength = sizeof(digest) + * mlength = sizeof(cleartext) + * clength = sizeof(ciphertext) = mlength + tlength + * + * The ciphertext will contain the encrypted payload with the message digest + * appended to the end. + */ +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); + +/* + * The decryption function will write the plaintext to dst and parse the digest + * from the final tlength bytes of the ciphertext. If the digest matched the + * value computed during decryption then this will return 1, or it will return + * 0 if the digest was invalid. + */ +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); + +/* CCM Mode with AES-128 */ +struct ccm_aes128_ctx { + struct ccm_ctx ccm; + struct aes128_ctx cipher; +}; + +void +ccm_aes128_set_key(struct ccm_aes128_ctx *ctx, const uint8_t *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); + +void +ccm_aes128_update (struct ccm_aes128_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes128_encrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes128_digest(struct ccm_aes128_ctx *ctx, + size_t length, uint8_t *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); + +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); + +struct ccm_aes192_ctx { + struct ccm_ctx ccm; + struct aes192_ctx cipher; +}; + +/* CCM Mode with AES-192 */ +void +ccm_aes192_set_key(struct ccm_aes192_ctx *ctx, const uint8_t *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); + +void +ccm_aes192_update(struct ccm_aes192_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes192_encrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes192_digest(struct ccm_aes192_ctx *ctx, + size_t length, uint8_t *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); + +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); + +/* CCM Mode with AES-256 */ +struct ccm_aes256_ctx { + struct ccm_ctx ccm; + struct aes256_ctx cipher; +}; + +void +ccm_aes256_set_key(struct ccm_aes256_ctx *ctx, const uint8_t *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); + +void +ccm_aes256_update(struct ccm_aes256_ctx *ctx, + size_t length, const uint8_t *data); + +void +ccm_aes256_encrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ccm_aes256_digest(struct ccm_aes256_ctx *ctx, + size_t length, uint8_t *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); + +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); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_CCM_H_INCLUDED */ |