mirror of
https://github.com/libtom/libtomcrypt
synced 2026-08-25 20:26:07 -04:00
Merge pull request #759 from libtom/pr/KMAC128-256
KMAC as defined in NIST SP 800-185
This commit is contained in:
commit
8512e3e891
18 changed files with 708 additions and 20 deletions
106
doc/crypt.tex
106
doc/crypt.tex
|
|
@ -3981,6 +3981,112 @@ int blake2bmac_file( const char *fname,
|
|||
Which will BLAKE2s/b--MAC the entire contents of the file specified by \textit{fname} using the key \textit{key} of
|
||||
length \textit{keylen} bytes. It will store the MAC in \textit{mac} with the same rules as blake2smac\_done().
|
||||
|
||||
\mysection{KMAC}
|
||||
|
||||
KMAC is a keyed message authentication code based on the Keccak permutation, standardised by NIST in
|
||||
SP 800--185. The library provides KMAC128 and KMAC256, each available in fixed--length and
|
||||
extendable--output (XOF) variants.
|
||||
|
||||
The desired flavour is selected through the \textit{variant} argument, which must be exactly one of the
|
||||
following four named constants:
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{ll}
|
||||
\hline
|
||||
\textit{variant} & resulting algorithm \\
|
||||
\hline
|
||||
\texttt{LTC\_KMAC128} & KMAC128 \\
|
||||
\texttt{LTC\_KMAC256} & KMAC256 \\
|
||||
\texttt{LTC\_KMAC128\_XOF} & KMACXOF128 \\
|
||||
\texttt{LTC\_KMAC256\_XOF} & KMACXOF256 \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
Any other value passed in \textit{variant} causes the init function to return \textbf{CRYPT\_INVALID\_ARG}.
|
||||
|
||||
A KMAC state is initialised with the following function:
|
||||
\index{kmac\_init()}
|
||||
\begin{verbatim}
|
||||
int kmac_init( kmac_state *st,
|
||||
int variant,
|
||||
const unsigned char *key,
|
||||
unsigned long keylen,
|
||||
const unsigned char *cust,
|
||||
unsigned long custlen);
|
||||
\end{verbatim}
|
||||
This will initialise the KMAC state \textit{st} with the key in \textit{key} of length \textit{keylen} octets
|
||||
and the optional customisation string in \textit{cust} of length \textit{custlen} octets. The customisation
|
||||
string may be empty: pass \textbf{NULL} as \textit{cust} together with \textit{custlen} equal to zero.
|
||||
|
||||
To process data through KMAC use the following function:
|
||||
\index{kmac\_process()}
|
||||
\begin{verbatim}
|
||||
int kmac_process( kmac_state *st,
|
||||
const unsigned char *in,
|
||||
unsigned long inlen);
|
||||
\end{verbatim}
|
||||
This will add the message octets pointed to by \textit{in} of length \textit{inlen} to the KMAC state pointed
|
||||
to by \textit{st}.
|
||||
|
||||
To compute the MAC tag use:
|
||||
\index{kmac\_done()}
|
||||
\begin{verbatim}
|
||||
int kmac_done( kmac_state *st,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen);
|
||||
\end{verbatim}
|
||||
On entry \textit{outlen} holds the requested output size in octets; on exit it holds the number of octets
|
||||
actually written to \textit{out}. For the fixed--length variants the requested length is bound into the
|
||||
authentication tag, so callers must commit to it before calling kmac\_done(). For the XOF variants the
|
||||
requested length is independent of the tag computation and any output length may be asked for.
|
||||
|
||||
Helper functions are provided to make hashing memory buffers and files easier:
|
||||
\index{kmac\_memory()}
|
||||
\begin{verbatim}
|
||||
int kmac_memory( int variant,
|
||||
const unsigned char *key,
|
||||
unsigned long keylen,
|
||||
const unsigned char *cust,
|
||||
unsigned long custlen,
|
||||
const unsigned char *in,
|
||||
unsigned long inlen,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen);
|
||||
\end{verbatim}
|
||||
This will compute the KMAC of \textit{inlen} bytes of \textit{in} using the key \textit{key} of length
|
||||
\textit{keylen} bytes and the customisation string \textit{cust} of length \textit{custlen} bytes. The result
|
||||
is stored in \textit{out} following the same rules as kmac\_done().
|
||||
|
||||
\index{kmac\_memory\_multi()}
|
||||
\begin{verbatim}
|
||||
int kmac_memory_multi( int variant,
|
||||
const unsigned char *key,
|
||||
unsigned long keylen,
|
||||
const unsigned char *cust,
|
||||
unsigned long custlen,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen,
|
||||
const unsigned char *in,
|
||||
unsigned long inlen, ...);
|
||||
\end{verbatim}
|
||||
The variadic form accepts an arbitrary number of (data, length) pairs, terminated by a \textbf{NULL} pointer.
|
||||
|
||||
To KMAC a file use:
|
||||
\index{kmac\_file()}
|
||||
\begin{verbatim}
|
||||
int kmac_file( int variant,
|
||||
const unsigned char *key,
|
||||
unsigned long keylen,
|
||||
const unsigned char *cust,
|
||||
unsigned long custlen,
|
||||
const char *fname,
|
||||
unsigned char *out,
|
||||
unsigned long *outlen);
|
||||
\end{verbatim}
|
||||
Which will KMAC the entire contents of the file named \textit{fname} and store the tag in \textit{out}
|
||||
following the same rules as kmac\_done().
|
||||
|
||||
\chapter{Pseudo-Random Number Generators}
|
||||
\mysection{Core Functions}
|
||||
The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is
|
||||
|
|
|
|||
|
|
@ -1159,6 +1159,30 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="kmac"
|
||||
>
|
||||
<File
|
||||
RelativePath="src\mac\kmac\kmac.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\mac\kmac\kmac_file.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\mac\kmac\kmac_memory.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\mac\kmac\kmac_memory_multi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\mac\kmac\kmac_test.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="omac"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -77,11 +77,12 @@ src/mac/blake2/blake2smac_memory_multi.o src/mac/blake2/blake2smac_test.o src/ma
|
|||
src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o src/mac/f9/f9_memory_multi.o \
|
||||
src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \
|
||||
src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o src/mac/hmac/hmac_memory_multi.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \
|
||||
src/mac/omac/omac_init.o src/mac/omac/omac_memory.o src/mac/omac/omac_memory_multi.o \
|
||||
src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \
|
||||
src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \
|
||||
src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/kmac/kmac.o src/mac/kmac/kmac_file.o \
|
||||
src/mac/kmac/kmac_memory.o src/mac/kmac/kmac_memory_multi.o src/mac/kmac/kmac_test.o \
|
||||
src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
|
||||
src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
|
||||
src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
|
||||
src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
|
||||
src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \
|
||||
src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \
|
||||
|
|
|
|||
|
|
@ -70,11 +70,12 @@ src/mac/blake2/blake2smac_memory_multi.obj src/mac/blake2/blake2smac_test.obj sr
|
|||
src/mac/f9/f9_file.obj src/mac/f9/f9_init.obj src/mac/f9/f9_memory.obj src/mac/f9/f9_memory_multi.obj \
|
||||
src/mac/f9/f9_process.obj src/mac/f9/f9_test.obj src/mac/hmac/hmac_done.obj src/mac/hmac/hmac_file.obj \
|
||||
src/mac/hmac/hmac_init.obj src/mac/hmac/hmac_memory.obj src/mac/hmac/hmac_memory_multi.obj \
|
||||
src/mac/hmac/hmac_process.obj src/mac/hmac/hmac_test.obj src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj \
|
||||
src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj src/mac/omac/omac_memory_multi.obj \
|
||||
src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj src/mac/pelican/pelican.obj \
|
||||
src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj src/mac/pmac/pmac_done.obj \
|
||||
src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \
|
||||
src/mac/hmac/hmac_process.obj src/mac/hmac/hmac_test.obj src/mac/kmac/kmac.obj src/mac/kmac/kmac_file.obj \
|
||||
src/mac/kmac/kmac_memory.obj src/mac/kmac/kmac_memory_multi.obj src/mac/kmac/kmac_test.obj \
|
||||
src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj \
|
||||
src/mac/omac/omac_memory_multi.obj src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj \
|
||||
src/mac/pelican/pelican.obj src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj \
|
||||
src/mac/pmac/pmac_done.obj src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \
|
||||
src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj src/mac/pmac/pmac_process.obj \
|
||||
src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/mac/poly1305/poly1305.obj \
|
||||
src/mac/poly1305/poly1305_file.obj src/mac/poly1305/poly1305_memory.obj \
|
||||
|
|
|
|||
|
|
@ -91,11 +91,12 @@ src/mac/blake2/blake2smac_memory_multi.o src/mac/blake2/blake2smac_test.o src/ma
|
|||
src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o src/mac/f9/f9_memory_multi.o \
|
||||
src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \
|
||||
src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o src/mac/hmac/hmac_memory_multi.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \
|
||||
src/mac/omac/omac_init.o src/mac/omac/omac_memory.o src/mac/omac/omac_memory_multi.o \
|
||||
src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \
|
||||
src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \
|
||||
src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/kmac/kmac.o src/mac/kmac/kmac_file.o \
|
||||
src/mac/kmac/kmac_memory.o src/mac/kmac/kmac_memory_multi.o src/mac/kmac/kmac_test.o \
|
||||
src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
|
||||
src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
|
||||
src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
|
||||
src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
|
||||
src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \
|
||||
src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \
|
||||
|
|
|
|||
|
|
@ -262,11 +262,12 @@ src/mac/blake2/blake2smac_memory_multi.o src/mac/blake2/blake2smac_test.o src/ma
|
|||
src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o src/mac/f9/f9_memory_multi.o \
|
||||
src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o \
|
||||
src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o src/mac/hmac/hmac_memory_multi.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/omac/omac_done.o src/mac/omac/omac_file.o \
|
||||
src/mac/omac/omac_init.o src/mac/omac/omac_memory.o src/mac/omac/omac_memory_multi.o \
|
||||
src/mac/omac/omac_process.o src/mac/omac/omac_test.o src/mac/pelican/pelican.o \
|
||||
src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o src/mac/pmac/pmac_done.o \
|
||||
src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o src/mac/kmac/kmac.o src/mac/kmac/kmac_file.o \
|
||||
src/mac/kmac/kmac_memory.o src/mac/kmac/kmac_memory_multi.o src/mac/kmac/kmac_test.o \
|
||||
src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
|
||||
src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
|
||||
src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
|
||||
src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
|
||||
src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
|
||||
src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/poly1305/poly1305.o \
|
||||
src/mac/poly1305/poly1305_file.o src/mac/poly1305/poly1305_memory.o \
|
||||
|
|
|
|||
|
|
@ -146,6 +146,11 @@ src/mac/hmac/hmac_memory.c
|
|||
src/mac/hmac/hmac_memory_multi.c
|
||||
src/mac/hmac/hmac_process.c
|
||||
src/mac/hmac/hmac_test.c
|
||||
src/mac/kmac/kmac.c
|
||||
src/mac/kmac/kmac_file.c
|
||||
src/mac/kmac/kmac_memory.c
|
||||
src/mac/kmac/kmac_memory_multi.c
|
||||
src/mac/kmac/kmac_test.c
|
||||
src/mac/omac/omac_done.c
|
||||
src/mac/omac/omac_file.c
|
||||
src/mac/omac/omac_init.c
|
||||
|
|
|
|||
|
|
@ -446,6 +446,13 @@ int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen)
|
|||
return s_sha3_shake_done(&md->sha3, out, outlen, 0x1f, s_keccakf);
|
||||
}
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
int sha3_shake_done_ex(hash_state *md, unsigned char *out, unsigned long outlen, unsigned char domain)
|
||||
{
|
||||
return s_sha3_shake_done(&md->sha3, out, outlen, domain, s_keccakf);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sha3_shake128_done(hash_state *md, unsigned char *out)
|
||||
{
|
||||
return sha3_shake_done(md, out, 32);
|
||||
|
|
|
|||
|
|
@ -301,6 +301,7 @@
|
|||
#define LTC_POLY1305
|
||||
#define LTC_BLAKE2SMAC
|
||||
#define LTC_BLAKE2BMAC
|
||||
#define LTC_KMAC
|
||||
|
||||
/* ---> Encrypt + Authenticate Modes <--- */
|
||||
|
||||
|
|
@ -735,6 +736,10 @@
|
|||
#error LTC_BLAKE2BMAC requires LTC_BLAKE2B
|
||||
#endif
|
||||
|
||||
#if defined(LTC_KMAC) && !defined(LTC_SHA3)
|
||||
#error LTC_KMAC requires LTC_SHA3
|
||||
#endif
|
||||
|
||||
#if defined(LTC_SPRNG) && !defined(LTC_RNG_GET_BYTES)
|
||||
#error LTC_SPRNG requires LTC_RNG_GET_BYTES
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -135,6 +135,42 @@ int blake2smac_file(const char *fname, const unsigned char *key, unsigned long k
|
|||
int blake2smac_test(void);
|
||||
#endif /* LTC_BLAKE2SMAC */
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
/* values for the `variant` argument of kmac_init() and friends */
|
||||
#define LTC_KMAC128 1
|
||||
#define LTC_KMAC256 2
|
||||
#define LTC_KMAC128_XOF 3
|
||||
#define LTC_KMAC256_XOF 4
|
||||
|
||||
typedef struct Kmac_state {
|
||||
hash_state sha3;
|
||||
int xof;
|
||||
} kmac_state;
|
||||
|
||||
int kmac_init(kmac_state *st, int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen);
|
||||
int kmac_process(kmac_state *st, const unsigned char *in, unsigned long inlen);
|
||||
int kmac_done(kmac_state *st, unsigned char *out, unsigned long *outlen);
|
||||
int kmac_memory(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int kmac_memory_multi(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...)
|
||||
LTC_NULL_TERMINATED;
|
||||
int kmac_file(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
const char *fname,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int kmac_test(void);
|
||||
#endif /* LTC_KMAC */
|
||||
|
||||
#ifdef LTC_BLAKE2BMAC
|
||||
typedef hash_state blake2bmac_state;
|
||||
int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,10 @@ int sha224_test_desc(const struct ltc_hash_descriptor *desc, const char *name);
|
|||
int sha256_test_desc(const struct ltc_hash_descriptor *desc, const char *name);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
int sha3_shake_done_ex(hash_state *md, unsigned char *out, unsigned long outlen, unsigned char domain);
|
||||
#endif
|
||||
|
||||
/* tomcrypt_mac.h */
|
||||
|
||||
int ocb3_int_ntz(unsigned long x);
|
||||
|
|
|
|||
171
src/mac/kmac/kmac.c
Normal file
171
src/mac/kmac/kmac.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file kmac.c
|
||||
KMAC as defined in NIST SP 800-185
|
||||
*/
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
|
||||
/* Encoding helpers from NIST SP 800-185 2.3 - encoded output never exceeds 9 bytes (8 byte payload + 1 length byte) */
|
||||
static unsigned long s_left_encode(ulong64 x, unsigned char *out)
|
||||
{
|
||||
int i, n = 1;
|
||||
for (i = 7; i > 0; --i) {
|
||||
if ((x >> (i * 8)) & 0xff) {
|
||||
n = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out[0] = (unsigned char)n;
|
||||
for (i = 0; i < n; ++i) {
|
||||
out[1 + i] = (unsigned char)(x >> ((n - 1 - i) * 8));
|
||||
}
|
||||
return (unsigned long)(n + 1);
|
||||
}
|
||||
|
||||
static unsigned long s_right_encode(ulong64 x, unsigned char *out)
|
||||
{
|
||||
int i, n = 1;
|
||||
for (i = 7; i > 0; --i) {
|
||||
if ((x >> (i * 8)) & 0xff) {
|
||||
n = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
out[i] = (unsigned char)(x >> ((n - 1 - i) * 8));
|
||||
}
|
||||
out[n] = (unsigned char)n;
|
||||
return (unsigned long)(n + 1);
|
||||
}
|
||||
|
||||
static int s_feed_encode_string(hash_state *md, const unsigned char *s, unsigned long slen, unsigned long *total)
|
||||
{
|
||||
unsigned char enc[9];
|
||||
unsigned long enclen;
|
||||
int err;
|
||||
enclen = s_left_encode((ulong64)slen * 8, enc);
|
||||
if ((err = sha3_process(md, enc, enclen)) != CRYPT_OK) return err;
|
||||
*total += enclen;
|
||||
if (slen != 0) {
|
||||
if ((err = sha3_process(md, s, slen)) != CRYPT_OK) return err;
|
||||
*total += slen;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static int s_feed_bytepad_zero_fill(hash_state *md, unsigned long rate, unsigned long total)
|
||||
{
|
||||
unsigned long pad = (rate - (total % rate)) % rate;
|
||||
if (pad != 0) {
|
||||
unsigned char zeros[168]; /* >= max SHAKE rate */
|
||||
XMEMSET(zeros, 0, sizeof(zeros));
|
||||
return sha3_process(md, zeros, pad);
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static int s_feed_bytepad_prefix(hash_state *md, unsigned long rate, unsigned long *total)
|
||||
{
|
||||
unsigned char enc[9];
|
||||
unsigned long enclen = s_left_encode(rate, enc);
|
||||
int err = sha3_process(md, enc, enclen);
|
||||
if (err == CRYPT_OK) *total = enclen;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize a KMAC context
|
||||
|
||||
@param st The KMAC state
|
||||
@param variant one of LTC_KMAC128, LTC_KMAC256, LTC_KMAC128_XOF, LTC_KMAC256_XOF
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param cust Optional customization string (may be NULL when custlen == 0)
|
||||
@param custlen Length of the customization string (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int kmac_init(kmac_state *st, int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen)
|
||||
{
|
||||
static const unsigned char kmac_name[4] = { 'K', 'M', 'A', 'C' };
|
||||
int err, num;
|
||||
unsigned long rate, total;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(key != NULL || keylen == 0);
|
||||
LTC_ARGCHK(cust != NULL || custlen == 0);
|
||||
|
||||
switch (variant) {
|
||||
case LTC_KMAC128: num = 128; st->xof = 0; rate = 168; break;
|
||||
case LTC_KMAC256: num = 256; st->xof = 0; rate = 136; break;
|
||||
case LTC_KMAC128_XOF: num = 128; st->xof = 1; rate = 168; break;
|
||||
case LTC_KMAC256_XOF: num = 256; st->xof = 1; rate = 136; break;
|
||||
default: return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((err = sha3_shake_init(&st->sha3, num)) != CRYPT_OK) return err;
|
||||
|
||||
/* bytepad(encode_string("KMAC") || encode_string(cust), rate) */
|
||||
if ((err = s_feed_bytepad_prefix(&st->sha3, rate, &total)) != CRYPT_OK) return err;
|
||||
if ((err = s_feed_encode_string(&st->sha3, kmac_name, sizeof(kmac_name), &total)) != CRYPT_OK) return err;
|
||||
if ((err = s_feed_encode_string(&st->sha3, cust, custlen, &total)) != CRYPT_OK) return err;
|
||||
if ((err = s_feed_bytepad_zero_fill(&st->sha3, rate, total)) != CRYPT_OK) return err;
|
||||
|
||||
/* bytepad(encode_string(key), rate) */
|
||||
if ((err = s_feed_bytepad_prefix(&st->sha3, rate, &total)) != CRYPT_OK) return err;
|
||||
if ((err = s_feed_encode_string(&st->sha3, key, keylen, &total)) != CRYPT_OK) return err;
|
||||
if ((err = s_feed_bytepad_zero_fill(&st->sha3, rate, total)) != CRYPT_OK) return err;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Process data through KMAC
|
||||
|
||||
@param st The KMAC state
|
||||
@param in The data to authenticate
|
||||
@param inlen The length of the data (octets)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int kmac_process(kmac_state *st, const unsigned char *in, unsigned long inlen)
|
||||
{
|
||||
if (inlen == 0) return CRYPT_OK;
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
return sha3_process(&st->sha3, in, inlen);
|
||||
}
|
||||
|
||||
/**
|
||||
Terminate a KMAC session
|
||||
|
||||
@param st The KMAC state
|
||||
@param out [out] The destination of the MAC
|
||||
@param outlen [in/out] The requested length on entry, the produced length on return
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int kmac_done(kmac_state *st, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned char enc[9];
|
||||
unsigned long enclen;
|
||||
int err;
|
||||
ulong64 L;
|
||||
|
||||
LTC_ARGCHK(st != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* SP 800-185 4: append right_encode(L) where L is the requested output length in bits or right_encode(0) for the XOF flavour */
|
||||
L = st->xof ? 0 : (ulong64)(*outlen) * 8;
|
||||
enclen = s_right_encode(L, enc);
|
||||
if ((err = sha3_process(&st->sha3, enc, enclen)) != CRYPT_OK) return err;
|
||||
|
||||
return sha3_shake_done_ex(&st->sha3, out, *outlen, 0x04);
|
||||
}
|
||||
|
||||
#endif
|
||||
90
src/mac/kmac/kmac_file.c
Normal file
90
src/mac/kmac/kmac_file.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
|
||||
/**
|
||||
KMAC a file
|
||||
|
||||
@param variant 128 or 256 (optionally OR-ed with LTC_KMAC_XOF)
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param cust Optional customization string (may be NULL when custlen == 0)
|
||||
@param custlen Length of the customization string (octets)
|
||||
@param fname The name of the file you wish to MAC
|
||||
@param out [out] Destination of the MAC
|
||||
@param outlen [in/out] Requested length on entry, produced length on return
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled
|
||||
*/
|
||||
int kmac_file(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
const char *fname,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
#ifdef LTC_NO_FILE
|
||||
LTC_UNUSED_PARAM(variant);
|
||||
LTC_UNUSED_PARAM(key);
|
||||
LTC_UNUSED_PARAM(keylen);
|
||||
LTC_UNUSED_PARAM(cust);
|
||||
LTC_UNUSED_PARAM(custlen);
|
||||
LTC_UNUSED_PARAM(fname);
|
||||
LTC_UNUSED_PARAM(out);
|
||||
LTC_UNUSED_PARAM(outlen);
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
kmac_state st;
|
||||
FILE *in;
|
||||
unsigned char *buf;
|
||||
size_t x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(fname != NULL);
|
||||
LTC_ARGCHK(key != NULL || keylen == 0);
|
||||
LTC_ARGCHK(cust != NULL || custlen == 0);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = kmac_init(&st, variant, key, keylen, cust, custlen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
in = fopen(fname, "rb");
|
||||
if (in == NULL) {
|
||||
err = CRYPT_FILE_NOTFOUND;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
do {
|
||||
x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
|
||||
if ((err = kmac_process(&st, buf, (unsigned long)x)) != CRYPT_OK) {
|
||||
fclose(in);
|
||||
goto LBL_CLEANBUF;
|
||||
}
|
||||
} while (x == LTC_FILE_READ_BUFSIZE);
|
||||
|
||||
if (fclose(in) != 0) {
|
||||
err = CRYPT_ERROR;
|
||||
goto LBL_CLEANBUF;
|
||||
}
|
||||
|
||||
err = kmac_done(&st, out, outlen);
|
||||
|
||||
LBL_CLEANBUF:
|
||||
zeromem(buf, LTC_FILE_READ_BUFSIZE);
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(&st, sizeof(st));
|
||||
#endif
|
||||
XFREE(buf);
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
47
src/mac/kmac/kmac_memory.c
Normal file
47
src/mac/kmac/kmac_memory.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
|
||||
/**
|
||||
KMAC a block of memory to produce the authentication tag
|
||||
|
||||
@param variant 128 or 256 (optionally OR-ed with LTC_KMAC_XOF)
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param cust Optional customization string (may be NULL when custlen == 0)
|
||||
@param custlen Length of the customization string (octets)
|
||||
@param in The data to authenticate
|
||||
@param inlen The length of the data (octets)
|
||||
@param out [out] Destination of the MAC
|
||||
@param outlen [in/out] Requested length on entry, produced length on return
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int kmac_memory(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
kmac_state st;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL || keylen == 0);
|
||||
LTC_ARGCHK(cust != NULL || custlen == 0);
|
||||
LTC_ARGCHK(in != NULL || inlen == 0);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = kmac_init(&st, variant, key, keylen, cust, custlen)) != CRYPT_OK) goto LBL_ERR;
|
||||
if ((err = kmac_process(&st, in, inlen)) != CRYPT_OK) goto LBL_ERR;
|
||||
err = kmac_done(&st, out, outlen);
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(&st, sizeof(st));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
60
src/mac/kmac/kmac_memory_multi.c
Normal file
60
src/mac/kmac/kmac_memory_multi.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
|
||||
/**
|
||||
KMAC multiple blocks of memory to produce the authentication tag
|
||||
|
||||
@param variant 128 or 256 (optionally OR-ed with LTC_KMAC_XOF)
|
||||
@param key The secret key
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param cust Optional customization string (may be NULL when custlen == 0)
|
||||
@param custlen Length of the customization string (octets)
|
||||
@param out [out] Destination of the MAC
|
||||
@param outlen [in/out] Requested length on entry, produced length on return
|
||||
@param in The data to authenticate
|
||||
@param inlen The length of the data (octets)
|
||||
@param ... tuples of (data, len) pairs to authenticate, terminated with (NULL, x)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int kmac_memory_multi(int variant,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *cust, unsigned long custlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *in, unsigned long inlen, ...)
|
||||
{
|
||||
kmac_state st;
|
||||
int err;
|
||||
va_list args;
|
||||
const unsigned char *curptr;
|
||||
unsigned long curlen;
|
||||
|
||||
LTC_ARGCHK(key != NULL || keylen == 0);
|
||||
LTC_ARGCHK(cust != NULL || custlen == 0);
|
||||
LTC_ARGCHK(in != NULL || inlen == 0);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
va_start(args, inlen);
|
||||
curptr = in;
|
||||
curlen = inlen;
|
||||
if ((err = kmac_init(&st, variant, key, keylen, cust, custlen)) != CRYPT_OK) goto LBL_ERR;
|
||||
for (;;) {
|
||||
if ((err = kmac_process(&st, curptr, curlen)) != CRYPT_OK) goto LBL_ERR;
|
||||
curptr = va_arg(args, const unsigned char*);
|
||||
if (curptr == NULL) break;
|
||||
curlen = va_arg(args, unsigned long);
|
||||
}
|
||||
err = kmac_done(&st, out, outlen);
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(&st, sizeof(st));
|
||||
#endif
|
||||
va_end(args);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
123
src/mac/kmac/kmac_test.c
Normal file
123
src/mac/kmac/kmac_test.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_KMAC
|
||||
|
||||
/* Test vectors from NIST SP 800-185 sample document (KMAC_samples.pdf) */
|
||||
int kmac_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const unsigned char key[32] = {
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
|
||||
};
|
||||
static const unsigned char data4[4] = { 0x00, 0x01, 0x02, 0x03 };
|
||||
static unsigned char data200[200];
|
||||
static const char tag_app[] = "My Tagged Application";
|
||||
|
||||
static const struct {
|
||||
int variant;
|
||||
unsigned long custlen;
|
||||
unsigned long inlen;
|
||||
unsigned long outlen;
|
||||
const unsigned char *in;
|
||||
unsigned char out[64];
|
||||
} tests[] = {
|
||||
/* sample #1: KMAC128, S="" */
|
||||
{ LTC_KMAC128, 0, 4, 32, data4, {
|
||||
0xE5, 0x78, 0x0B, 0x0D, 0x3E, 0xA6, 0xF7, 0xD3, 0xA4, 0x29, 0xC5, 0x70, 0x6A, 0xA4, 0x3A, 0x00,
|
||||
0xFA, 0xDB, 0xD7, 0xD4, 0x96, 0x28, 0x83, 0x9E, 0x31, 0x87, 0x24, 0x3F, 0x45, 0x6E, 0xE1, 0x4E } },
|
||||
/* sample #2: KMAC128, S="My Tagged Application" */
|
||||
{ LTC_KMAC128, 21, 4, 32, data4, {
|
||||
0x3B, 0x1F, 0xBA, 0x96, 0x3C, 0xD8, 0xB0, 0xB5, 0x9E, 0x8C, 0x1A, 0x6D, 0x71, 0x88, 0x8B, 0x71,
|
||||
0x43, 0x65, 0x1A, 0xF8, 0xBA, 0x0A, 0x70, 0x70, 0xC0, 0x97, 0x9E, 0x28, 0x11, 0x32, 0x4A, 0xA5 } },
|
||||
/* sample #3: KMAC128, 200-byte input, S="My Tagged Application" */
|
||||
{ LTC_KMAC128, 21, 200, 32, data200, {
|
||||
0x1F, 0x5B, 0x4E, 0x6C, 0xCA, 0x02, 0x20, 0x9E, 0x0D, 0xCB, 0x5C, 0xA6, 0x35, 0xB8, 0x9A, 0x15,
|
||||
0xE2, 0x71, 0xEC, 0xC7, 0x60, 0x07, 0x1D, 0xFD, 0x80, 0x5F, 0xAA, 0x38, 0xF9, 0x72, 0x92, 0x30 } },
|
||||
/* sample #4: KMAC256, S="My Tagged Application" */
|
||||
{ LTC_KMAC256, 21, 4, 64, data4, {
|
||||
0x20, 0xC5, 0x70, 0xC3, 0x13, 0x46, 0xF7, 0x03, 0xC9, 0xAC, 0x36, 0xC6, 0x1C, 0x03, 0xCB, 0x64,
|
||||
0xC3, 0x97, 0x0D, 0x0C, 0xFC, 0x78, 0x7E, 0x9B, 0x79, 0x59, 0x9D, 0x27, 0x3A, 0x68, 0xD2, 0xF7,
|
||||
0xF6, 0x9D, 0x4C, 0xC3, 0xDE, 0x9D, 0x10, 0x4A, 0x35, 0x16, 0x89, 0xF2, 0x7C, 0xF6, 0xF5, 0x95,
|
||||
0x1F, 0x01, 0x03, 0xF3, 0x3F, 0x4F, 0x24, 0x87, 0x10, 0x24, 0xD9, 0xC2, 0x77, 0x73, 0xA8, 0xDD } },
|
||||
/* sample #5: KMAC256, 200-byte input, S="" */
|
||||
{ LTC_KMAC256, 0, 200, 64, data200, {
|
||||
0x75, 0x35, 0x8C, 0xF3, 0x9E, 0x41, 0x49, 0x4E, 0x94, 0x97, 0x07, 0x92, 0x7C, 0xEE, 0x0A, 0xF2,
|
||||
0x0A, 0x3F, 0xF5, 0x53, 0x90, 0x4C, 0x86, 0xB0, 0x8F, 0x21, 0xCC, 0x41, 0x4B, 0xCF, 0xD6, 0x91,
|
||||
0x58, 0x9D, 0x27, 0xCF, 0x5E, 0x15, 0x36, 0x9C, 0xBB, 0xFF, 0x8B, 0x9A, 0x4C, 0x2E, 0xB1, 0x78,
|
||||
0x00, 0x85, 0x5D, 0x02, 0x35, 0xFF, 0x63, 0x5D, 0xA8, 0x25, 0x33, 0xEC, 0x6B, 0x75, 0x9B, 0x69 } },
|
||||
/* sample #7: KMACXOF128, S="" */
|
||||
{ LTC_KMAC128_XOF, 0, 4, 32, data4, {
|
||||
0xCD, 0x83, 0x74, 0x0B, 0xBD, 0x92, 0xCC, 0xC8, 0xCF, 0x03, 0x2B, 0x14, 0x81, 0xA0, 0xF4, 0x46,
|
||||
0x0E, 0x7C, 0xA9, 0xDD, 0x12, 0xB0, 0x8A, 0x0C, 0x40, 0x31, 0x17, 0x8B, 0xAC, 0xD6, 0xEC, 0x35 } },
|
||||
/* sample #8: KMACXOF128, S="My Tagged Application" */
|
||||
{ LTC_KMAC128_XOF, 21, 4, 32, data4, {
|
||||
0x31, 0xA4, 0x45, 0x27, 0xB4, 0xED, 0x9F, 0x5C, 0x61, 0x01, 0xD1, 0x1D, 0xE6, 0xD2, 0x6F, 0x06,
|
||||
0x20, 0xAA, 0x5C, 0x34, 0x1D, 0xEF, 0x41, 0x29, 0x96, 0x57, 0xFE, 0x9D, 0xF1, 0xA3, 0xB1, 0x6C } },
|
||||
/* sample #9: KMACXOF128, 200-byte input, S="My Tagged Application" */
|
||||
{ LTC_KMAC128_XOF, 21, 200, 32, data200, {
|
||||
0x47, 0x02, 0x6C, 0x7C, 0xD7, 0x93, 0x08, 0x4A, 0xA0, 0x28, 0x3C, 0x25, 0x3E, 0xF6, 0x58, 0x49,
|
||||
0x0C, 0x0D, 0xB6, 0x14, 0x38, 0xB8, 0x32, 0x6F, 0xE9, 0xBD, 0xDF, 0x28, 0x1B, 0x83, 0xAE, 0x0F } },
|
||||
/* sample #10: KMACXOF256, S="My Tagged Application" */
|
||||
{ LTC_KMAC256_XOF, 21, 4, 64, data4, {
|
||||
0x17, 0x55, 0x13, 0x3F, 0x15, 0x34, 0x75, 0x2A, 0xAD, 0x07, 0x48, 0xF2, 0xC7, 0x06, 0xFB, 0x5C,
|
||||
0x78, 0x45, 0x12, 0xCA, 0xB8, 0x35, 0xCD, 0x15, 0x67, 0x6B, 0x16, 0xC0, 0xC6, 0x64, 0x7F, 0xA9,
|
||||
0x6F, 0xAA, 0x7A, 0xF6, 0x34, 0xA0, 0xBF, 0x8F, 0xF6, 0xDF, 0x39, 0x37, 0x4F, 0xA0, 0x0F, 0xAD,
|
||||
0x9A, 0x39, 0xE3, 0x22, 0xA7, 0xC9, 0x20, 0x65, 0xA6, 0x4E, 0xB1, 0xFB, 0x08, 0x01, 0xEB, 0x2B } },
|
||||
/* sample #11: KMACXOF256, 200-byte input, S="" */
|
||||
{ LTC_KMAC256_XOF, 0, 200, 64, data200, {
|
||||
0xFF, 0x7B, 0x17, 0x1F, 0x1E, 0x8A, 0x2B, 0x24, 0x68, 0x3E, 0xED, 0x37, 0x83, 0x0E, 0xE7, 0x97,
|
||||
0x53, 0x8B, 0xA8, 0xDC, 0x56, 0x3F, 0x6D, 0xA1, 0xE6, 0x67, 0x39, 0x1A, 0x75, 0xED, 0xC0, 0x2C,
|
||||
0xA6, 0x33, 0x07, 0x9F, 0x81, 0xCE, 0x12, 0xA2, 0x5F, 0x45, 0x61, 0x5E, 0xC8, 0x99, 0x72, 0x03,
|
||||
0x1D, 0x18, 0x33, 0x73, 0x31, 0xD2, 0x4C, 0xEB, 0x8F, 0x8C, 0xA8, 0xE6, 0xA1, 0x9F, 0xD9, 0x8B } }
|
||||
};
|
||||
unsigned int i;
|
||||
unsigned char buf[64];
|
||||
unsigned long buflen;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < sizeof(data200); ++i) data200[i] = (unsigned char)i;
|
||||
|
||||
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
|
||||
const unsigned char *cust = (tests[i].custlen == 0) ? NULL : (const unsigned char*)tag_app;
|
||||
buflen = tests[i].outlen;
|
||||
if ((err = kmac_memory(tests[i].variant, key, sizeof(key), cust, tests[i].custlen,
|
||||
tests[i].in, tests[i].inlen, buf, &buflen)) != CRYPT_OK) return err;
|
||||
if (ltc_compare_testvector(buf, buflen, tests[i].out, tests[i].outlen, "kmac", (int)i) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
/* sample #6: KMAC256, 200-byte input, S="My Tagged Application", processed one byte at a time */
|
||||
{
|
||||
static const unsigned char sample6[64] = {
|
||||
0xB5, 0x86, 0x18, 0xF7, 0x1F, 0x92, 0xE1, 0xD5, 0x6C, 0x1B, 0x8C, 0x55, 0xDD, 0xD7, 0xCD, 0x18,
|
||||
0x8B, 0x97, 0xB4, 0xCA, 0x4D, 0x99, 0x83, 0x1E, 0xB2, 0x69, 0x9A, 0x83, 0x7D, 0xA2, 0xE4, 0xD9,
|
||||
0x70, 0xFB, 0xAC, 0xFD, 0xE5, 0x00, 0x33, 0xAE, 0xA5, 0x85, 0xF1, 0xA2, 0x70, 0x85, 0x10, 0xC3,
|
||||
0x2D, 0x07, 0x88, 0x08, 0x01, 0xBD, 0x18, 0x28, 0x98, 0xFE, 0x47, 0x68, 0x76, 0xFC, 0x89, 0x65
|
||||
};
|
||||
kmac_state st;
|
||||
unsigned int j;
|
||||
if ((err = kmac_init(&st, LTC_KMAC256, key, sizeof(key), (const unsigned char*)tag_app, 21)) != CRYPT_OK) return err;
|
||||
for (j = 0; j < sizeof(data200); ++j) {
|
||||
if ((err = kmac_process(&st, &data200[j], 1)) != CRYPT_OK) return err;
|
||||
}
|
||||
buflen = 64;
|
||||
if ((err = kmac_done(&st, buf, &buflen)) != CRYPT_OK) return err;
|
||||
if (ltc_compare_testvector(buf, buflen, sample6, sizeof(sample6), "kmac stream", 0) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -288,6 +288,9 @@ const char *crypt_build_settings =
|
|||
#if defined(LTC_BLAKE2BMAC)
|
||||
" BLAKE2B MAC\n"
|
||||
#endif
|
||||
#if defined(LTC_KMAC)
|
||||
" KMAC\n"
|
||||
#endif
|
||||
|
||||
"\nENC + AUTH modes:\n"
|
||||
#if defined(LTC_EAX_MODE)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ int mac_test(void)
|
|||
#ifdef LTC_BLAKE2BMAC
|
||||
DO(blake2bmac_test());
|
||||
#endif
|
||||
#ifdef LTC_KMAC
|
||||
DO(kmac_test());
|
||||
#endif
|
||||
#ifdef LTC_SIV_MODE
|
||||
DO(siv_test());
|
||||
DO(siv_wycheproof_test());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue