Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • briansmith/nettle
  • justus/nettle
  • nettle/nettle
  • michaelweiser/nettle
  • aberaud/nettle
  • npocs/nettle
  • ajlawrence/nettle
  • mhoffmann/nettle
  • lumag/nettle
  • mamonet/nettle
  • devnexen/nettle
  • babelouest/nettle
  • ueno/nettle
  • rth/nettle
  • wiml/nettle
15 results
Select Git revision
Show changes
/* cfb.c
Cipher feedback mode.
Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov
Copyright (C) 2001, 2011 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "cfb.h"
#include "memxor.h"
#include "nettle-internal.h"
void
cfb_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
uint8_t *p;
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size);
if (src != dst)
{
for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
{
f(ctx, block_size, dst, p);
memxor(dst, src, block_size);
}
}
else
{
for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
{
f(ctx, block_size, buffer, p);
memxor(dst, buffer, block_size);
}
}
if (p != iv)
memcpy(iv, p, block_size);
if (length)
{
f(ctx, block_size, buffer, iv);
memxor3(dst, buffer, src, length);
/* We do not care about updating IV here. This is the last call in
* message sequence and one has to set IV afterwards anyway */
}
}
/* Don't allocate any more space than this on the stack */
#define CFB_BUFFER_LIMIT 512
void
cfb_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
if (src != dst)
{
size_t left = length % block_size;
length -= left;
if (length > 0)
{
/* Decrypt in ECB mode */
f(ctx, block_size, dst, iv);
f(ctx, length - block_size, dst + block_size, src);
memcpy(iv, src + length - block_size, block_size);
memxor(dst, src, length);
}
if (left > 0)
{
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size);
f(ctx, block_size, buffer, iv);
memxor3(dst + length, src + length, buffer, left);
}
}
else
{
/* For in-place CFB, we decrypt into a temporary buffer of size
* at most CFB_BUFFER_LIMIT, and process that amount of data at
* a time. */
/* NOTE: We assume that block_size <= CFB_BUFFER_LIMIT */
TMP_DECL(buffer, uint8_t, CFB_BUFFER_LIMIT);
TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
size_t buffer_size;
size_t left;
buffer_size = CFB_BUFFER_LIMIT - (CFB_BUFFER_LIMIT % block_size);
TMP_ALLOC(buffer, buffer_size);
TMP_ALLOC(initial_iv, block_size);
left = length % block_size;
length -= left;
while (length > 0)
{
size_t part = length > buffer_size ? buffer_size : length;
/* length is greater that zero and is divided by block_size, so it is
* not less than block_size. So does part */
f(ctx, block_size, buffer, iv);
f(ctx, part - block_size, buffer + block_size, dst);
memcpy(iv, dst + part - block_size, block_size);
memxor(dst, buffer, part);
length -= part;
dst += part;
}
if (left > 0)
{
f(ctx, block_size, buffer, iv);
memxor(dst, buffer, left);
}
}
}
/* CFB-8 uses slight optimization: it encrypts or decrypts up to block_size
* bytes and does memcpy/memxor afterwards */
void
cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size * 2);
TMP_ALLOC(outbuf, block_size);
uint8_t pos;
memcpy(buffer, iv, block_size);
pos = 0;
while (length)
{
uint8_t t;
if (pos == block_size)
{
memcpy(buffer, buffer + block_size, block_size);
pos = 0;
}
f(ctx, block_size, outbuf, buffer + pos);
t = *(dst++) = *(src++) ^ outbuf[0];
buffer[pos + block_size] = t;
length--;
pos ++;
}
memcpy(iv, buffer + pos, block_size);
}
void
cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
TMP_DECL(outbuf, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE * 2);
TMP_ALLOC(buffer, block_size * 2);
TMP_ALLOC(outbuf, block_size * 2);
uint8_t i = 0;
memcpy(buffer, iv, block_size);
memcpy(buffer + block_size, src,
length < block_size ? length : block_size);
while (length)
{
for (i = 0; i < length && i < block_size; i++)
f(ctx, block_size, outbuf + i, buffer + i);
memxor3(dst, src, outbuf, i);
length -= i;
src += i;
dst += i;
if (i == block_size)
{
memcpy(buffer, buffer + block_size, block_size);
memcpy(buffer + block_size, src,
length < block_size ? length : block_size);
}
}
memcpy(iv, buffer + i, block_size);
}
/* cfb.h
Cipher feedback mode.
Copyright (C) 2015, 2017 Dmitry Eremin-Solenikov
Copyright (C) 2001 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CFB_H_INCLUDED
#define NETTLE_CFB_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define cfb_encrypt nettle_cfb_encrypt
#define cfb_decrypt nettle_cfb_decrypt
#define cfb8_encrypt nettle_cfb8_encrypt
#define cfb8_decrypt nettle_cfb8_decrypt
void
cfb_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
void
cfb_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
void
cfb8_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
void
cfb8_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
#define CFB_CTX(type, size) \
{ type ctx; uint8_t iv[size]; }
#define CFB_SET_IV(ctx, data) \
memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
#define CFB8_CTX CFB_CTX
#define CFB8_SET_IV CFB_SET_IV
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
#define CFB_ENCRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb_encrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#define CFB_DECRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb_decrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#define CFB8_ENCRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb8_encrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#define CFB8_DECRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb8_decrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_CFB_H_INCLUDED */
/* chacha-core-internal.c
Core functionality of the ChaCha stream cipher.
Heavily based on the Salsa20 implementation in Nettle.
Copyright (C) 2013 Joachim Strömbergson
Copyright (C) 2012 Simon Josefsson, Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* Based on:
chacha-ref.c version 2008.01.20.
D. J. Bernstein
Public domain.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "chacha.h"
#include "chacha-internal.h"
#include "bswap-internal.h"
#include "macros.h"
/* For fat builds */
#if HAVE_NATIVE_chacha_core
void
_nettle_chacha_core_c(uint32_t *dst, const uint32_t *src, unsigned rounds);
#define _nettle_chacha_core _nettle_chacha_core_c
#endif
#ifndef CHACHA_DEBUG
# define CHACHA_DEBUG 0
#endif
#if CHACHA_DEBUG
# include <stdio.h>
# define DEBUG(i) do { \
unsigned debug_j; \
for (debug_j = 0; debug_j < 16; debug_j++) \
{ \
if (debug_j == 0) \
fprintf(stderr, "%2d:", (i)); \
else if (debug_j % 4 == 0) \
fprintf(stderr, "\n "); \
fprintf(stderr, " %8x", x[debug_j]); \
} \
fprintf(stderr, "\n"); \
} while (0)
#else
# define DEBUG(i)
#endif
#define QROUND(x0, x1, x2, x3) do { \
x0 = x0 + x1; x3 = ROTL32(16, (x0 ^ x3)); \
x2 = x2 + x3; x1 = ROTL32(12, (x1 ^ x2)); \
x0 = x0 + x1; x3 = ROTL32(8, (x0 ^ x3)); \
x2 = x2 + x3; x1 = ROTL32(7, (x1 ^ x2)); \
} while(0)
void
_nettle_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds)
{
uint32_t x[_CHACHA_STATE_LENGTH];
unsigned i;
assert ( (rounds & 1) == 0);
memcpy (x, src, sizeof(x));
for (i = 0; i < rounds;i += 2)
{
DEBUG (i);
QROUND(x[0], x[4], x[8], x[12]);
QROUND(x[1], x[5], x[9], x[13]);
QROUND(x[2], x[6], x[10], x[14]);
QROUND(x[3], x[7], x[11], x[15]);
DEBUG (i+1);
QROUND(x[0], x[5], x[10], x[15]);
QROUND(x[1], x[6], x[11], x[12]);
QROUND(x[2], x[7], x[8], x[13]);
QROUND(x[3], x[4], x[9], x[14]);
}
DEBUG (i);
for (i = 0; i < _CHACHA_STATE_LENGTH; i++)
{
uint32_t t = x[i] + src[i];
dst[i] = bswap32_if_be (t);
}
}
/* chacha-crypt.c
The crypt function in the ChaCha stream cipher.
Heavily based on the Salsa20 implementation in Nettle.
Copyright (C) 2014 Niels Möller
Copyright (C) 2013 Joachim Strömbergson
Copyright (C) 2012 Simon Josefsson
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* Based on:
chacha-ref.c version 2008.01.20.
D. J. Bernstein
Public domain.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include "chacha.h"
#include "chacha-internal.h"
#include "macros.h"
#include "memxor.h"
#define CHACHA_ROUNDS 20
#if HAVE_NATIVE_chacha_4core
#define _nettle_chacha_crypt_4core chacha_crypt
#define _nettle_chacha_crypt32_4core chacha_crypt32
#elif HAVE_NATIVE_chacha_3core
#define _nettle_chacha_crypt_3core chacha_crypt
#define _nettle_chacha_crypt32_3core chacha_crypt32
#elif !(HAVE_NATIVE_fat_chacha_4core || HAVE_NATIVE_fat_chacha_3core)
#define _nettle_chacha_crypt_1core chacha_crypt
#define _nettle_chacha_crypt32_1core chacha_crypt32
#endif
#if HAVE_NATIVE_chacha_4core || HAVE_NATIVE_fat_chacha_4core
void
_nettle_chacha_crypt_4core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
uint32_t x[4*_CHACHA_STATE_LENGTH];
if (!length)
return;
while (length > 2*CHACHA_BLOCK_SIZE)
{
_nettle_chacha_4core (x, ctx->state, CHACHA_ROUNDS);
if (length <= 4*CHACHA_BLOCK_SIZE)
{
uint32_t incr = 3 + (length > 3*CHACHA_BLOCK_SIZE);
ctx->state[12] += incr;
ctx->state[13] += (ctx->state[12] < incr);
memxor3 (dst, src, x, length);
return;
}
ctx->state[12] += 4;
ctx->state[13] += (ctx->state[12] < 4);
memxor3 (dst, src, x, 4*CHACHA_BLOCK_SIZE);
length -= 4*CHACHA_BLOCK_SIZE;
dst += 4*CHACHA_BLOCK_SIZE;
src += 4*CHACHA_BLOCK_SIZE;
}
if (length > CHACHA_BLOCK_SIZE)
{
_nettle_chacha_2core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 2;
ctx->state[13] += (ctx->state[12] < 2);
}
else
{
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[13] += (++ctx->state[12] == 0);
}
memxor3 (dst, src, x, length);
}
#endif
#if HAVE_NATIVE_chacha_3core || HAVE_NATIVE_fat_chacha_3core
void
_nettle_chacha_crypt_3core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
uint32_t x[3*_CHACHA_STATE_LENGTH];
if (!length)
return;
while (length > 2*CHACHA_BLOCK_SIZE)
{
_nettle_chacha_3core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 3;
ctx->state[13] += (ctx->state[12] < 3);
if (length <= 3*CHACHA_BLOCK_SIZE)
{
memxor3 (dst, src, x, length);
return;
}
memxor3 (dst, src, x, 3*CHACHA_BLOCK_SIZE);
length -= 3*CHACHA_BLOCK_SIZE;
dst += 3*CHACHA_BLOCK_SIZE;
src += 3*CHACHA_BLOCK_SIZE;
}
if (length <= CHACHA_BLOCK_SIZE)
{
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[13] += (++ctx->state[12] == 0);
}
else
{
_nettle_chacha_3core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 2;
ctx->state[13] += (ctx->state[12] < 2);
}
memxor3 (dst, src, x, length);
}
#endif
#if !(HAVE_NATIVE_chacha_4core || HAVE_NATIVE_chacha_3core)
void
_nettle_chacha_crypt_1core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
if (!length)
return;
for (;;)
{
uint32_t x[_CHACHA_STATE_LENGTH];
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
ctx->state[13] += (++ctx->state[12] == 0);
/* stopping at 2^70 length per nonce is user's responsibility */
if (length <= CHACHA_BLOCK_SIZE)
{
memxor3 (dst, src, x, length);
return;
}
memxor3 (dst, src, x, CHACHA_BLOCK_SIZE);
length -= CHACHA_BLOCK_SIZE;
dst += CHACHA_BLOCK_SIZE;
src += CHACHA_BLOCK_SIZE;
}
}
#endif
#if HAVE_NATIVE_chacha_4core || HAVE_NATIVE_fat_chacha_4core
void
_nettle_chacha_crypt32_4core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
uint32_t x[4*_CHACHA_STATE_LENGTH];
if (!length)
return;
while (length > 2*CHACHA_BLOCK_SIZE)
{
_nettle_chacha_4core32 (x, ctx->state, CHACHA_ROUNDS);
if (length <= 4*CHACHA_BLOCK_SIZE)
{
ctx->state[12] += 3 + (length > 3*CHACHA_BLOCK_SIZE);
memxor3 (dst, src, x, length);
return;
}
ctx->state[12] += 4;
memxor3 (dst, src, x, 4*CHACHA_BLOCK_SIZE);
length -= 4*CHACHA_BLOCK_SIZE;
dst += 4*CHACHA_BLOCK_SIZE;
src += 4*CHACHA_BLOCK_SIZE;
}
if (length > CHACHA_BLOCK_SIZE)
{
_nettle_chacha_2core32 (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 2;
}
else
{
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
++ctx->state[12];
}
memxor3 (dst, src, x, length);
}
#endif
#if HAVE_NATIVE_chacha_3core || HAVE_NATIVE_fat_chacha_3core
void
_nettle_chacha_crypt32_3core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
uint32_t x[3*_CHACHA_STATE_LENGTH];
if (!length)
return;
while (length > 2*CHACHA_BLOCK_SIZE)
{
_nettle_chacha_3core32 (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 3;
if (length <= 3*CHACHA_BLOCK_SIZE)
{
memxor3 (dst, src, x, length);
return;
}
memxor3 (dst, src, x, 3*CHACHA_BLOCK_SIZE);
length -= 3*CHACHA_BLOCK_SIZE;
dst += 3*CHACHA_BLOCK_SIZE;
src += 3*CHACHA_BLOCK_SIZE;
}
if (length <= CHACHA_BLOCK_SIZE)
{
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
++ctx->state[12];
}
else
{
_nettle_chacha_3core32 (x, ctx->state, CHACHA_ROUNDS);
ctx->state[12] += 2;
}
memxor3 (dst, src, x, length);
}
#endif
#if !(HAVE_NATIVE_chacha_4core || HAVE_NATIVE_chacha_3core)
void
_nettle_chacha_crypt32_1core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src)
{
if (!length)
return;
for (;;)
{
uint32_t x[_CHACHA_STATE_LENGTH];
_nettle_chacha_core (x, ctx->state, CHACHA_ROUNDS);
++ctx->state[12];
/* stopping at 2^38 length per nonce is user's responsibility */
if (length <= CHACHA_BLOCK_SIZE)
{
memxor3 (dst, src, x, length);
return;
}
memxor3 (dst, src, x, CHACHA_BLOCK_SIZE);
length -= CHACHA_BLOCK_SIZE;
dst += CHACHA_BLOCK_SIZE;
src += CHACHA_BLOCK_SIZE;
}
}
#endif
/* chacha-internal.h
The ChaCha stream cipher.
Copyright (C) 2013 Joachim Strömbergson
Copyright (C) 2012 Simon Josefsson
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CHACHA_INTERNAL_H_INCLUDED
#define NETTLE_CHACHA_INTERNAL_H_INCLUDED
#include "nettle-types.h"
#include "chacha.h"
void
_nettle_chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds);
/* Functions available only in some configurations */
void
_nettle_chacha_2core(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_2core32(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_3core(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_3core32(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_4core(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_4core32(uint32_t *dst, const uint32_t *src, unsigned rounds);
void
_nettle_chacha_crypt_1core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
void
_nettle_chacha_crypt_3core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
void
_nettle_chacha_crypt_4core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
void
_nettle_chacha_crypt32_1core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
void
_nettle_chacha_crypt32_3core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
void
_nettle_chacha_crypt32_4core(struct chacha_ctx *ctx,
size_t length,
uint8_t *dst,
const uint8_t *src);
#endif /* NETTLE_CHACHA_INTERNAL_H_INCLUDED */
/* chacha-poly1305-meta.c
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "chacha-poly1305.h"
const struct nettle_aead nettle_chacha_poly1305 =
{ "chacha_poly1305", sizeof(struct chacha_poly1305_ctx),
CHACHA_POLY1305_BLOCK_SIZE, CHACHA_POLY1305_KEY_SIZE,
CHACHA_POLY1305_NONCE_SIZE, CHACHA_POLY1305_DIGEST_SIZE,
(nettle_set_key_func *) chacha_poly1305_set_key,
(nettle_set_key_func *) chacha_poly1305_set_key,
(nettle_set_key_func *) chacha_poly1305_set_nonce,
(nettle_hash_update_func *) chacha_poly1305_update,
(nettle_crypt_func *) chacha_poly1305_encrypt,
(nettle_crypt_func *) chacha_poly1305_decrypt,
(nettle_hash_digest_func *) chacha_poly1305_digest,
};
/* chacha-poly1305.c
AEAD mechanism based on chacha and poly1305.
Copyright (C) 2014, 2015 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* This implements chacha-poly1305 according to
draft-irtf-cfrg-chacha20-poly1305-08. The inputs to poly1305 are:
associated data
zero padding
ciphertext
zero padding
length of associated data (64-bit, little endian)
length of ciphertext (64-bit, little endian)
where the padding fields are 0-15 zero bytes, filling up to a
16-byte boundary.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "chacha-internal.h"
#include "chacha-poly1305.h"
#include "poly1305-internal.h"
#include "macros.h"
#define CHACHA_ROUNDS 20
/* FIXME: Also set nonce to zero, and implement nonce
auto-increment? */
void
chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx,
const uint8_t *key)
{
chacha_set_key (&ctx->chacha, key);
}
void
chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx,
const uint8_t *nonce)
{
union {
uint32_t x[_CHACHA_STATE_LENGTH];
uint8_t subkey[32];
} u;
chacha_set_nonce96 (&ctx->chacha, nonce);
/* Generate authentication key */
_nettle_chacha_core (u.x, ctx->chacha.state, CHACHA_ROUNDS);
_nettle_poly1305_set_key (&ctx->poly1305, u.subkey);
/* For final poly1305 processing */
memcpy (ctx->s.b, u.subkey + 16, 16);
/* Increment block count */
ctx->chacha.state[12] = 1;
ctx->auth_size = ctx->data_size = ctx->index = 0;
}
/* FIXME: Duplicated in poly1305-aes128.c */
#define COMPRESS(ctx, data) _nettle_poly1305_block(&(ctx)->poly1305, (data), 1)
static void
poly1305_update (struct chacha_poly1305_ctx *ctx,
size_t length, const uint8_t *data)
{
ctx->index = _nettle_poly1305_update (&(ctx)->poly1305,
ctx->block, ctx->index, length, data);
}
static void
poly1305_pad (struct chacha_poly1305_ctx *ctx)
{
if (ctx->index)
{
memset (ctx->block + ctx->index, 0,
POLY1305_BLOCK_SIZE - ctx->index);
_nettle_poly1305_block(&ctx->poly1305, ctx->block, 1);
ctx->index = 0;
}
}
void
chacha_poly1305_update (struct chacha_poly1305_ctx *ctx,
size_t length, const uint8_t *data)
{
assert (ctx->data_size == 0);
poly1305_update (ctx, length, data);
ctx->auth_size += length;
}
void
chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
if (!length)
return;
assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0);
poly1305_pad (ctx);
chacha_crypt32 (&ctx->chacha, length, dst, src);
poly1305_update (ctx, length, dst);
ctx->data_size += length;
}
void
chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src)
{
if (!length)
return;
assert (ctx->data_size % CHACHA_POLY1305_BLOCK_SIZE == 0);
poly1305_pad (ctx);
poly1305_update (ctx, length, src);
chacha_crypt32 (&ctx->chacha, length, dst, src);
ctx->data_size += length;
}
void
chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx,
uint8_t *digest)
{
uint8_t buf[16];
poly1305_pad (ctx);
LE_WRITE_UINT64 (buf, ctx->auth_size);
LE_WRITE_UINT64 (buf + 8, ctx->data_size);
_nettle_poly1305_block (&ctx->poly1305, buf, 1);
_nettle_poly1305_digest (&ctx->poly1305, &ctx->s);
memcpy (digest, &ctx->s.b, CHACHA_POLY1305_DIGEST_SIZE);
}
/* chacha-poly1305.h
AEAD mechanism based on chacha and poly1305.
See draft-agl-tls-chacha20poly1305-04.
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CHACHA_POLY1305_H_INCLUDED
#define NETTLE_CHACHA_POLY1305_H_INCLUDED
#include "chacha.h"
#include "poly1305.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define chacha_poly1305_set_key nettle_chacha_poly1305_set_key
#define chacha_poly1305_set_nonce nettle_chacha_poly1305_set_nonce
#define chacha_poly1305_update nettle_chacha_poly1305_update
#define chacha_poly1305_decrypt nettle_chacha_poly1305_decrypt
#define chacha_poly1305_encrypt nettle_chacha_poly1305_encrypt
#define chacha_poly1305_digest nettle_chacha_poly1305_digest
#define CHACHA_POLY1305_BLOCK_SIZE 64
/* FIXME: Any need for 128-bit variant? */
#define CHACHA_POLY1305_KEY_SIZE 32
#define CHACHA_POLY1305_NONCE_SIZE CHACHA_NONCE96_SIZE
#define CHACHA_POLY1305_DIGEST_SIZE 16
struct chacha_poly1305_ctx
{
struct chacha_ctx chacha;
struct poly1305_ctx poly1305;
union nettle_block16 s;
uint64_t auth_size;
uint64_t data_size;
/* poly1305 block */
uint8_t block[POLY1305_BLOCK_SIZE];
unsigned index;
};
void
chacha_poly1305_set_key (struct chacha_poly1305_ctx *ctx,
const uint8_t *key);
void
chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx,
const uint8_t *nonce);
void
chacha_poly1305_update (struct chacha_poly1305_ctx *ctx,
size_t length, const uint8_t *data);
void
chacha_poly1305_encrypt (struct chacha_poly1305_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src);
void
chacha_poly1305_decrypt (struct chacha_poly1305_ctx *ctx,
size_t length, uint8_t *dst, const uint8_t *src);
void
chacha_poly1305_digest (struct chacha_poly1305_ctx *ctx,
uint8_t *digest);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_CHACHA_POLY1305_H_INCLUDED */
/* chacha-set-key.c
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "chacha.h"
#include "macros.h"
void
chacha_set_key(struct chacha_ctx *ctx, const uint8_t *key)
{
static const uint32_t sigma[4] = {
/* "expand 32-byte k" */
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
};
ctx->state[4] = LE_READ_UINT32(key + 0);
ctx->state[5] = LE_READ_UINT32(key + 4);
ctx->state[6] = LE_READ_UINT32(key + 8);
ctx->state[7] = LE_READ_UINT32(key + 12);
ctx->state[8] = LE_READ_UINT32(key + 16);
ctx->state[9] = LE_READ_UINT32(key + 20);
ctx->state[10] = LE_READ_UINT32(key + 24);
ctx->state[11] = LE_READ_UINT32(key + 28);
memcpy (ctx->state, sigma, sizeof(sigma));
}
/* chacha-set-nonce.c
Setting the nonce the ChaCha stream cipher.
Based on the Salsa20 implementation in Nettle.
Copyright (C) 2013 Joachim Strömbergon
Copyright (C) 2012 Simon Josefsson
Copyright (C) 2012, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
/* Based on:
ChaCha specification (doc id: 4027b5256e17b9796842e6d0f68b0b5e) and reference
implementation dated 2008.01.20
D. J. Bernstein
Public domain.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "chacha.h"
#include "macros.h"
void
chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce)
{
ctx->state[12] = 0;
ctx->state[13] = 0;
ctx->state[14] = LE_READ_UINT32(nonce + 0);
ctx->state[15] = LE_READ_UINT32(nonce + 4);
}
void
chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce)
{
ctx->state[12] = 0;
ctx->state[13] = LE_READ_UINT32(nonce + 0);
ctx->state[14] = LE_READ_UINT32(nonce + 4);
ctx->state[15] = LE_READ_UINT32(nonce + 8);
}
void
chacha_set_counter(struct chacha_ctx *ctx, const uint8_t *counter)
{
ctx->state[12] = LE_READ_UINT32(counter + 0);
ctx->state[13] = LE_READ_UINT32(counter + 4);
}
void
chacha_set_counter32(struct chacha_ctx *ctx, const uint8_t *counter)
{
ctx->state[12] = LE_READ_UINT32(counter + 0);
}
/* chacha.h
The ChaCha stream cipher.
Copyright (C) 2013 Joachim Strömbergson
Copyright (C) 2012 Simon Josefsson
Copyright (C) 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CHACHA_H_INCLUDED
#define NETTLE_CHACHA_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define chacha_set_key nettle_chacha_set_key
#define chacha_set_nonce nettle_chacha_set_nonce
#define chacha_set_nonce96 nettle_chacha_set_nonce96
#define chacha_set_counter nettle_chacha_set_counter
#define chacha_set_counter32 nettle_chacha_set_counter32
#define chacha_crypt nettle_chacha_crypt
#define chacha_crypt32 nettle_chacha_crypt32
/* Currently, only 256-bit keys are supported. */
#define CHACHA_KEY_SIZE 32
#define CHACHA_BLOCK_SIZE 64
#define CHACHA_NONCE_SIZE 8
#define CHACHA_NONCE96_SIZE 12
#define CHACHA_COUNTER_SIZE 8
#define CHACHA_COUNTER32_SIZE 4
#define _CHACHA_STATE_LENGTH 16
struct chacha_ctx
{
/* Indices 0-3 holds a constant (SIGMA or TAU).
Indices 4-11 holds the key.
Indices 12-13 holds the block counter.
Indices 14-15 holds the IV:
This creates the state matrix:
C C C C
K K K K
K K K K
B B I I
*/
uint32_t state[_CHACHA_STATE_LENGTH];
};
void
chacha_set_key(struct chacha_ctx *ctx, const uint8_t *key);
void
chacha_set_nonce(struct chacha_ctx *ctx, const uint8_t *nonce);
void
chacha_set_nonce96(struct chacha_ctx *ctx, const uint8_t *nonce);
void
chacha_set_counter(struct chacha_ctx *ctx, const uint8_t *counter);
void
chacha_set_counter32(struct chacha_ctx *ctx, const uint8_t *counter);
void
chacha_crypt(struct chacha_ctx *ctx, size_t length,
uint8_t *dst, const uint8_t *src);
void
chacha_crypt32(struct chacha_ctx *ctx, size_t length,
uint8_t *dst, const uint8_t *src);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_CHACHA_H_INCLUDED */
/* cmac-aes128-meta.c
Copyright (C) 2013, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "cmac.h"
const struct nettle_mac nettle_cmac_aes128 =
{
"cmac_aes128",
sizeof(struct cmac_aes128_ctx),
CMAC128_DIGEST_SIZE,
AES128_KEY_SIZE,
(nettle_set_key_func*) cmac_aes128_set_key,
(nettle_hash_update_func*) cmac_aes128_update,
(nettle_hash_digest_func*) cmac_aes128_digest
};
/* cmac-aes128.c
CMAC using AES128 as the underlying cipher.
Copyright (C) 2017 Red Hat, Inc.
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "cmac.h"
void
cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key)
{
CMAC128_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key);
}
void
cmac_aes128_update (struct cmac_aes128_ctx *ctx,
size_t length, const uint8_t *data)
{
CMAC128_UPDATE (ctx, aes128_encrypt, length, data);
}
void
cmac_aes128_digest(struct cmac_aes128_ctx *ctx,
uint8_t *digest)
{
CMAC128_DIGEST(ctx, aes128_encrypt, digest);
}
/* cmac-aes256-meta.c
Copyright (C) 2013, 2014 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "cmac.h"
const struct nettle_mac nettle_cmac_aes256 =
{
"cmac_aes256",
sizeof(struct cmac_aes256_ctx),
CMAC128_DIGEST_SIZE,
AES256_KEY_SIZE,
(nettle_set_key_func*) cmac_aes256_set_key,
(nettle_hash_update_func*) cmac_aes256_update,
(nettle_hash_digest_func*) cmac_aes256_digest
};
/* cmac-aes256.c
CMAC using AES256 as the underlying cipher.
Copyright (C) 2017 Red Hat, Inc.
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "cmac.h"
void
cmac_aes256_set_key(struct cmac_aes256_ctx *ctx, const uint8_t *key)
{
CMAC128_SET_KEY(ctx, aes256_set_encrypt_key, aes256_encrypt, key);
}
void
cmac_aes256_update (struct cmac_aes256_ctx *ctx,
size_t length, const uint8_t *data)
{
CMAC128_UPDATE (ctx, aes256_encrypt, length, data);
}
void
cmac_aes256_digest(struct cmac_aes256_ctx *ctx,
uint8_t *digest)
{
CMAC128_DIGEST(ctx, aes256_encrypt, digest);
}
/* cmac-des3-meta.c
Copyright (C) 2020 Dmitry Baryshkov
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "nettle-meta.h"
#include "cmac.h"
const struct nettle_mac nettle_cmac_des3 =
{
"cmac_des3",
sizeof(struct cmac_des3_ctx),
CMAC64_DIGEST_SIZE,
DES3_KEY_SIZE,
(nettle_set_key_func*) cmac_des3_set_key,
(nettle_hash_update_func*) cmac_des3_update,
(nettle_hash_digest_func*) cmac_des3_digest
};
/* cmac-des3.c
CMAC using TripleDES as the underlying cipher.
Copyright (C) 2019 Dmitry Eremin-Solenikov
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "cmac.h"
void
cmac_des3_set_key (struct cmac_des3_ctx *ctx, const uint8_t *key)
{
CMAC64_SET_KEY (ctx, des3_set_key, des3_encrypt, key);
}
void
cmac_des3_update (struct cmac_des3_ctx *ctx,
size_t length, const uint8_t *data)
{
CMAC64_UPDATE (ctx, des3_encrypt, length, data);
}
void
cmac_des3_digest (struct cmac_des3_ctx *ctx,
uint8_t *digest)
{
CMAC64_DIGEST (ctx, des3_encrypt, digest);
}
/*
AES-CMAC-128 (rfc 4493)
Copyright (C) Stefan Metzmacher 2012
Copyright (C) Jeremy Allison 2012
Copyright (C) Michael Adam 2012
Copyright (C) 2017, Red Hat Inc.
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "cmac.h"
#include "memxor.h"
#include "nettle-internal.h"
#include "block-internal.h"
#include "macros.h"
void
cmac128_set_key(struct cmac128_key *key, const void *cipher,
nettle_cipher_func *encrypt)
{
static const union nettle_block16 zero_block;
union nettle_block16 L;
/* step 1 - generate subkeys k1 and k2 */
encrypt(cipher, 16, L.b, zero_block.b);
block16_mulx_be(&key->K1, &L);
block16_mulx_be(&key->K2, &key->K1);
}
void
cmac128_init(struct cmac128_ctx *ctx)
{
memset(&ctx->X, 0, sizeof(ctx->X));
ctx->index = 0;
}
#define MIN(x,y) ((x)<(y)?(x):(y))
void
cmac128_update(struct cmac128_ctx *ctx, const void *cipher,
nettle_cipher_func *encrypt,
size_t msg_len, const uint8_t *msg)
{
union nettle_block16 Y;
/*
* check if we expand the block
*/
if (ctx->index < 16)
{
size_t len = MIN(16 - ctx->index, msg_len);
memcpy(&ctx->block.b[ctx->index], msg, len);
msg += len;
msg_len -= len;
ctx->index += len;
}
if (msg_len == 0) {
/* if it is still the last block, we are done */
return;
}
/*
* now checksum everything but the last block
*/
block16_xor3(&Y, &ctx->X, &ctx->block);
encrypt(cipher, 16, ctx->X.b, Y.b);
while (msg_len > 16)
{
block16_xor_bytes (&Y, &ctx->X, msg);
encrypt(cipher, 16, ctx->X.b, Y.b);
msg += 16;
msg_len -= 16;
}
/*
* copy the last block, it will be processed in
* cmac128_digest().
*/
memcpy(ctx->block.b, msg, msg_len);
ctx->index = msg_len;
}
void
cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key,
const void *cipher, nettle_cipher_func *encrypt,
uint8_t *dst)
{
union nettle_block16 Y;
/* re-use ctx->block for memxor output */
if (ctx->index < 16)
{
ctx->block.b[ctx->index] = 0x80;
memset(ctx->block.b + ctx->index + 1, 0, 16 - 1 - ctx->index);
block16_xor (&ctx->block, &key->K2);
}
else
{
block16_xor (&ctx->block, &key->K1);
}
block16_xor3 (&Y, &ctx->block, &ctx->X);
encrypt(cipher, 16, dst, Y.b);
/* reset state for re-use */
cmac128_init(ctx);
}
/* cmac.h
CMAC mode, as specified in RFC4493
Copyright (C) 2017 Red Hat, Inc.
Contributed by Nikos Mavrogiannopoulos
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CMAC_H_INCLUDED
#define NETTLE_CMAC_H_INCLUDED
#include "aes.h"
#include "des.h"
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CMAC128_DIGEST_SIZE 16
#define CMAC64_DIGEST_SIZE 8
#define cmac128_set_key nettle_cmac128_set_key
#define cmac128_init nettle_cmac128_init
#define cmac128_update nettle_cmac128_update
#define cmac128_digest nettle_cmac128_digest
#define cmac_aes128_set_key nettle_cmac_aes128_set_key
#define cmac_aes128_update nettle_cmac_aes128_update
#define cmac_aes128_digest nettle_cmac_aes128_digest
#define cmac_aes256_set_key nettle_cmac_aes256_set_key
#define cmac_aes256_update nettle_cmac_aes256_update
#define cmac_aes256_digest nettle_cmac_aes256_digest
#define cmac64_set_key nettle_cmac64_set_key
#define cmac64_init nettle_cmac64_init
#define cmac64_update nettle_cmac64_update
#define cmac64_digest nettle_cmac64_digest
#define cmac_des3_set_key nettle_cmac_des3_set_key
#define cmac_des3_update nettle_cmac_des3_update
#define cmac_des3_digest nettle_cmac_des3_digest
struct cmac128_key
{
union nettle_block16 K1;
union nettle_block16 K2;
};
struct cmac128_ctx
{
/* MAC state */
union nettle_block16 X;
/* Block buffer */
union nettle_block16 block;
size_t index;
};
struct cmac64_key
{
union nettle_block8 K1;
union nettle_block8 K2;
};
struct cmac64_ctx
{
/* MAC state */
union nettle_block8 X;
/* Block buffer */
union nettle_block8 block;
size_t index;
};
void
cmac128_set_key(struct cmac128_key *key, const void *cipher,
nettle_cipher_func *encrypt);
void
cmac128_init(struct cmac128_ctx *ctx);
void
cmac128_update(struct cmac128_ctx *ctx, const void *cipher,
nettle_cipher_func *encrypt,
size_t msg_len, const uint8_t *msg);
void
cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key,
const void *cipher, nettle_cipher_func *encrypt,
uint8_t *digest);
#define CMAC128_CTX(type) \
{ struct cmac128_key key; struct cmac128_ctx ctx; type cipher; }
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
#define CMAC128_SET_KEY(self, set_key, encrypt, cmac_key) \
do { \
(set_key)(&(self)->cipher, (cmac_key)); \
if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0); \
cmac128_set_key(&(self)->key, &(self)->cipher, \
(nettle_cipher_func *) (encrypt)); \
cmac128_init(&(self)->ctx); \
} while (0)
#define CMAC128_UPDATE(self, encrypt, length, src) \
(0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0) \
: cmac128_update(&(self)->ctx, &(self)->cipher, \
(nettle_cipher_func *)encrypt, \
(length), (src)))
#define CMAC128_DIGEST(self, encrypt, digest) \
(0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0) \
: cmac128_digest(&(self)->ctx, &(self)->key, \
&(self)->cipher, \
(nettle_cipher_func *) (encrypt), \
(digest)))
void
cmac64_set_key(struct cmac64_key *key, const void *cipher,
nettle_cipher_func *encrypt);
void
cmac64_init(struct cmac64_ctx *ctx);
void
cmac64_update(struct cmac64_ctx *ctx, const void *cipher,
nettle_cipher_func *encrypt,
size_t msg_len, const uint8_t *msg);
void
cmac64_digest(struct cmac64_ctx *ctx, const struct cmac64_key *key,
const void *cipher, nettle_cipher_func *encrypt,
uint8_t *digest);
#define CMAC64_CTX(type) \
{ struct cmac64_key key; struct cmac64_ctx ctx; type cipher; }
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
#define CMAC64_SET_KEY(self, set_key, encrypt, cmac_key) \
do { \
(set_key)(&(self)->cipher, (cmac_key)); \
if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0); \
cmac64_set_key(&(self)->key, &(self)->cipher, \
(nettle_cipher_func *) (encrypt)); \
cmac64_init(&(self)->ctx); \
} while (0)
#define CMAC64_UPDATE(self, encrypt, length, src) \
(0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0) \
: cmac64_update(&(self)->ctx, &(self)->cipher, \
(nettle_cipher_func *)encrypt, \
(length), (src)))
#define CMAC64_DIGEST(self, encrypt, digest) \
(0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0) \
: cmac64_digest(&(self)->ctx, &(self)->key, \
&(self)->cipher, \
(nettle_cipher_func *) (encrypt), \
(digest)))
struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx);
void
cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key);
void
cmac_aes128_update(struct cmac_aes128_ctx *ctx,
size_t length, const uint8_t *data);
void
cmac_aes128_digest(struct cmac_aes128_ctx *ctx,
uint8_t *digest);
struct cmac_aes256_ctx CMAC128_CTX(struct aes256_ctx);
void
cmac_aes256_set_key(struct cmac_aes256_ctx *ctx, const uint8_t *key);
void
cmac_aes256_update(struct cmac_aes256_ctx *ctx,
size_t length, const uint8_t *data);
void
cmac_aes256_digest(struct cmac_aes256_ctx *ctx,
uint8_t *digest);
struct cmac_des3_ctx CMAC64_CTX(struct des3_ctx);
void
cmac_des3_set_key(struct cmac_des3_ctx *ctx, const uint8_t *key);
void
cmac_des3_update(struct cmac_des3_ctx *ctx,
size_t length, const uint8_t *data);
void
cmac_des3_digest(struct cmac_des3_ctx *ctx,
uint8_t *digest);
#ifdef __cplusplus
}
#endif
#endif /* CMAC_H_INCLUDED */
/*
CMAC-64, NIST SP 800-38B
Copyright (C) Stefan Metzmacher 2012
Copyright (C) Jeremy Allison 2012
Copyright (C) Michael Adam 2012
Copyright (C) 2017, Red Hat Inc.
Copyright (C) 2019, Dmitry Eremin-Solenikov
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle 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
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "cmac.h"
#include "nettle-internal.h"
#include "block-internal.h"
#include "macros.h"
void
cmac64_set_key(struct cmac64_key *key, const void *cipher,
nettle_cipher_func *encrypt)
{
static const union nettle_block8 zero_block;
union nettle_block8 L;
/* step 1 - generate subkeys k1 and k2 */
encrypt(cipher, 8, L.b, zero_block.b);
block8_mulx_be(&key->K1, &L);
block8_mulx_be(&key->K2, &key->K1);
}
void
cmac64_init(struct cmac64_ctx *ctx)
{
memset(&ctx->X, 0, sizeof(ctx->X));
ctx->index = 0;
}
#define MIN(x,y) ((x)<(y)?(x):(y))
void
cmac64_update(struct cmac64_ctx *ctx, const void *cipher,
nettle_cipher_func *encrypt,
size_t msg_len, const uint8_t *msg)
{
union nettle_block8 Y;
/*
* check if we expand the block
*/
if (ctx->index < 8)
{
size_t len = MIN(8 - ctx->index, msg_len);
memcpy(&ctx->block.b[ctx->index], msg, len);
msg += len;
msg_len -= len;
ctx->index += len;
}
if (msg_len == 0) {
/* if it is still the last block, we are done */
return;
}
/*
* now checksum everything but the last block
*/
block8_xor3(&Y, &ctx->X, &ctx->block);
encrypt(cipher, 8, ctx->X.b, Y.b);
while (msg_len > 8)
{
block8_xor_bytes(&Y, &ctx->X, msg);
encrypt(cipher, 8, ctx->X.b, Y.b);
msg += 8;
msg_len -= 8;
}
/*
* copy the last block, it will be processed in
* cmac64_digest().
*/
memcpy(ctx->block.b, msg, msg_len);
ctx->index = msg_len;
}
void
cmac64_digest(struct cmac64_ctx *ctx, const struct cmac64_key *key,
const void *cipher, nettle_cipher_func *encrypt,
uint8_t *dst)
{
union nettle_block8 Y;
memset(ctx->block.b+ctx->index, 0, sizeof(ctx->block.b)-ctx->index);
/* re-use ctx->block for memxor output */
if (ctx->index < 8)
{
ctx->block.b[ctx->index] = 0x80;
block8_xor(&ctx->block, &key->K2);
}
else
{
block8_xor(&ctx->block, &key->K1);
}
block8_xor3(&Y, &ctx->block, &ctx->X);
encrypt(cipher, 8, dst, Y.b);
/* reset state for re-use */
memset(&ctx->X, 0, sizeof(ctx->X));
ctx->index = 0;
}