diff --git a/ChangeLog.d/sha3.txt b/ChangeLog.d/sha3.txt new file mode 100644 index 000000000000..dafff74f169d --- /dev/null +++ b/ChangeLog.d/sha3.txt @@ -0,0 +1,3 @@ +Features + * Add SHA3 family hash functions. + diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 23a83f2c84d7..11600bb60e71 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -73,6 +73,7 @@ * SHA1 1 0x0035-0x0035 0x0073-0x0073 * SHA256 1 0x0037-0x0037 0x0074-0x0074 * SHA512 1 0x0039-0x0039 0x0075-0x0075 + * SHA-3 1 0x0076-0x0076 * CHACHA20 3 0x0051-0x0055 * POLY1305 3 0x0057-0x005B * CHACHAPOLY 2 0x0054-0x0056 diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 75e41476237b..985a50a7df3a 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -3164,6 +3164,17 @@ */ #define MBEDTLS_SHA512_C +/** + * \def MBEDTLS_SHA3_C + * + * Enable the SHA3 cryptographic hash algorithm. + * + * Module: library/sha3.c + * + * This module adds support for SHA3. + */ +#define MBEDTLS_SHA3_C + /** * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT * diff --git a/include/mbedtls/md.h b/include/mbedtls/md.h index 7bad24dc9b1c..a1429036875f 100644 --- a/include/mbedtls/md.h +++ b/include/mbedtls/md.h @@ -149,9 +149,13 @@ typedef enum { MBEDTLS_MD_SHA384, /**< The SHA-384 message digest. */ MBEDTLS_MD_SHA512, /**< The SHA-512 message digest. */ MBEDTLS_MD_RIPEMD160, /**< The RIPEMD-160 message digest. */ + MBEDTLS_MD_SHA3_224, /**< The SHA3-224 message digest. */ + MBEDTLS_MD_SHA3_256, /**< The SHA3-256 message digest. */ + MBEDTLS_MD_SHA3_384, /**< The SHA3-384 message digest. */ + MBEDTLS_MD_SHA3_512, /**< The SHA3-512 message digest. */ } mbedtls_md_type_t; -#if defined(MBEDTLS_MD_CAN_SHA512) +#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_SHA3_C) #define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ #elif defined(MBEDTLS_MD_CAN_SHA384) #define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */ @@ -164,7 +168,9 @@ typedef enum { or smaller (MD5 and earlier) */ #endif -#if defined(MBEDTLS_MD_CAN_SHA512) +#if defined(MBEDTLS_SHA3_C) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */ +#elif defined(MBEDTLS_MD_CAN_SHA512) #define MBEDTLS_MD_MAX_BLOCK_SIZE 128 #else #define MBEDTLS_MD_MAX_BLOCK_SIZE 64 diff --git a/include/mbedtls/sha3.h b/include/mbedtls/sha3.h new file mode 100644 index 000000000000..2ddb22a3bef1 --- /dev/null +++ b/include/mbedtls/sha3.h @@ -0,0 +1,199 @@ +/** + * \file sha3.h + * + * \brief This file contains SHA3 definitions and functions. + * + * The Secure Hash Algorithms cryptographic + * hash functions are defined in FIPS 202: SHA-3 Standard: + * Permutation-Based Hash and Extendable-Output Functions . + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MBEDTLS_SHA3_H +#define MBEDTLS_SHA3_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** SHA3 input data was malformed. */ +#define MBEDTLS_ERR_SHA3_BAD_INPUT_DATA -0x0076 + +/** + * SHA-3 family id. + * + * It identifies the family (SHA3-256, SHA3-512, etc.) + */ + +typedef enum { + MBEDTLS_SHA3_NONE = 0, /*!< Operation not defined. */ + MBEDTLS_SHA3_224, /*!< SHA3-224 */ + MBEDTLS_SHA3_256, /*!< SHA3-256 */ + MBEDTLS_SHA3_384, /*!< SHA3-384 */ + MBEDTLS_SHA3_512, /*!< SHA3-512 */ +} mbedtls_sha3_id; + +struct mbedtls_sha3_context; +typedef struct mbedtls_sha3_family_functions { + mbedtls_sha3_id id; + + uint16_t r; + uint16_t olen; + uint8_t xor_byte; +} +mbedtls_sha3_family_functions; + +/** + * \brief The SHA-3 context structure. + * + * The structure is used SHA-3 checksum calculations. + */ +typedef struct mbedtls_sha3_context { + uint64_t state[25]; + uint8_t index; + uint8_t id; + + uint16_t r; + uint16_t olen; + uint8_t xor_byte; + uint16_t max_block_size; +} +mbedtls_sha3_context; + +/** + * \brief This function initializes a SHA-3 context. + * + * \param ctx The SHA-3 context to initialize. This must not be \c NULL. + */ +void mbedtls_sha3_init(mbedtls_sha3_context *ctx); + +/** + * \brief This function clears a SHA-3 context. + * + * \param ctx The SHA-3 context to clear. This may be \c NULL, in which + * case this function returns immediately. If it is not \c NULL, + * it must point to an initialized SHA-3 context. + */ +void mbedtls_sha3_free(mbedtls_sha3_context *ctx); + +/** + * \brief This function clones the state of a SHA-3 context. + * + * \param dst The destination context. This must be initialized. + * \param src The context to clone. This must be initialized. + */ +void mbedtls_sha3_clone(mbedtls_sha3_context *dst, + const mbedtls_sha3_context *src); + +/** + * \brief This function starts a SHA-3 checksum + * calculation. + * + * \param ctx The context to use. This must be initialized. + * \param id The id of the SHA-3 family. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-3 checksum calculation. + * + * \param ctx The SHA-3 context. This must be initialized + * and have a hash operation started. + * \param input The buffer holding the data. This must be a readable + * buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha3_update(mbedtls_sha3_context *ctx, + const uint8_t *input, + size_t ilen); + +/** + * \brief This function finishes the SHA-3 operation, and writes + * the result to the output buffer. + * + * \param ctx The SHA-3 context. This must be initialized + * and have a hash operation started. + * \param output The SHA-3 checksum result. + * This must be a writable buffer of length \c olen bytes. + * \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256, + * SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64, + * respectively. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha3_finish(mbedtls_sha3_context *ctx, + uint8_t *output, size_t olen); + +/** + * \brief This function calculates the SHA-3 + * checksum of a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The SHA-3 result is calculated as + * output = SHA-3(id, input buffer, d). + * + * \param id The id of the SHA-3 family. + * \param input The buffer holding the data. This must be a readable + * buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The SHA-3 checksum result. + * This must be a writable buffer of length \c olen bytes. + * \param olen Defines the length of output buffer (in bytes). For SHA-3 224, SHA-3 256, + * SHA-3 384 and SHA-3 512 \c olen must equal to 28, 32, 48 and 64, + * respectively. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input, + size_t ilen, + uint8_t *output, + size_t olen); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine for the algorithms implemented + * by this module: SHA3-224, SHA3-256, SHA3-384, SHA3-512, + * SHAKE128, SHAKE256, cSHAKE128 and cSHAKE256. + * + * \return 0 if successful, or 1 if the test failed. + */ +int mbedtls_sha3_self_test(int verbose); +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_sha3.h */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index a992d8a71a0a..b60728c43993 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -84,6 +84,7 @@ set(src_crypto sha1.c sha256.c sha512.c + sha3.c threading.c timing.c version.c diff --git a/library/Makefile b/library/Makefile index 160aa6be5397..4e02bcd24810 100644 --- a/library/Makefile +++ b/library/Makefile @@ -149,6 +149,7 @@ OBJS_CRYPTO= \ sha1.o \ sha256.o \ sha512.o \ + sha3.o \ threading.o \ timing.o \ version.o \ diff --git a/library/md.c b/library/md.c index bebe3580bdda..993b006d2135 100644 --- a/library/md.c +++ b/library/md.c @@ -51,6 +51,9 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#if defined(MBEDTLS_SHA3_C) +#include "mbedtls/sha3.h" +#endif #if defined(MBEDTLS_MD_SOME_PSA) #include @@ -128,6 +131,33 @@ const mbedtls_md_info_t mbedtls_sha512_info = { }; #endif +#if defined(MBEDTLS_SHA3_C) +const mbedtls_md_info_t mbedtls_sha3_224_info = { + "SHA3-224", + MBEDTLS_MD_SHA3_224, + 28, + 144, +}; +const mbedtls_md_info_t mbedtls_sha3_256_info = { + "SHA3-256", + MBEDTLS_MD_SHA3_256, + 32, + 136, +}; +const mbedtls_md_info_t mbedtls_sha3_384_info = { + "SHA3-384", + MBEDTLS_MD_SHA3_384, + 48, + 104, +}; +const mbedtls_md_info_t mbedtls_sha3_512_info = { + "SHA3-512", + MBEDTLS_MD_SHA3_512, + 64, + 72, +}; +#endif + const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) { switch (md_type) { @@ -158,6 +188,16 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) #if defined(MBEDTLS_MD_CAN_SHA512) case MBEDTLS_MD_SHA512: return &mbedtls_sha512_info; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + return &mbedtls_sha3_224_info; + case MBEDTLS_MD_SHA3_256: + return &mbedtls_sha3_256_info; + case MBEDTLS_MD_SHA3_384: + return &mbedtls_sha3_384_info; + case MBEDTLS_MD_SHA3_512: + return &mbedtls_sha3_512_info; #endif default: return NULL; @@ -279,6 +319,14 @@ void mbedtls_md_free(mbedtls_md_context_t *ctx) case MBEDTLS_MD_SHA512: mbedtls_sha512_free(ctx->md_ctx); break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + mbedtls_sha3_free(ctx->md_ctx); + break; #endif default: /* Shouldn't happen */ @@ -357,6 +405,14 @@ int mbedtls_md_clone(mbedtls_md_context_t *dst, case MBEDTLS_MD_SHA512: mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + mbedtls_sha3_clone(dst->md_ctx, src->md_ctx); + break; #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -434,6 +490,14 @@ int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info case MBEDTLS_MD_SHA512: ALLOC(sha512); break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + ALLOC(sha3); + break; #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -496,6 +560,16 @@ int mbedtls_md_starts(mbedtls_md_context_t *ctx) #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA512: return mbedtls_sha512_starts(ctx->md_ctx, 0); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_224); + case MBEDTLS_MD_SHA3_256: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_256); + case MBEDTLS_MD_SHA3_384: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_384); + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_512); #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -543,6 +617,13 @@ int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, siz #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA512: return mbedtls_sha512_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_update(ctx->md_ctx, input, ilen); #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -592,6 +673,13 @@ int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output) #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA512: return mbedtls_sha512_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_finish(ctx->md_ctx, output, ctx->md_info->size); #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -643,6 +731,16 @@ int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, siz #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA512: return mbedtls_sha512(input, ilen, output, 0); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + return mbedtls_sha3(MBEDTLS_SHA3_224, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_256: + return mbedtls_sha3(MBEDTLS_SHA3_256, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_384: + return mbedtls_sha3(MBEDTLS_SHA3_384, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3(MBEDTLS_SHA3_512, input, ilen, output, md_info->size); #endif default: return MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -704,6 +802,12 @@ static const int supported_digests[] = { #if defined(MBEDTLS_MD_CAN_MD5) MBEDTLS_MD_MD5, #endif +#if defined(MBEDTLS_SHA3_C) + MBEDTLS_MD_SHA3_224, + MBEDTLS_MD_SHA3_256, + MBEDTLS_MD_SHA3_384, + MBEDTLS_MD_SHA3_512, +#endif MBEDTLS_MD_NONE }; @@ -754,6 +858,17 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) if (!strcmp("SHA512", md_name)) { return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } +#endif +#if defined(MBEDTLS_SHA3_C) + if (!strcmp("SHA3-224", md_name)) { + return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_224); + } else if (!strcmp("SHA3-256", md_name)) { + return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_256); + } else if (!strcmp("SHA3-384", md_name)) { + return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_384); + } else if (!strcmp("SHA3-512", md_name)) { + return mbedtls_md_info_from_type(MBEDTLS_MD_SHA3_512); + } #endif return NULL; } diff --git a/library/md_wrap.h b/library/md_wrap.h index cd539b54be32..5e1e327e7d9d 100644 --- a/library/md_wrap.h +++ b/library/md_wrap.h @@ -73,6 +73,12 @@ extern const mbedtls_md_info_t mbedtls_sha384_info; #if defined(MBEDTLS_SHA512_C) extern const mbedtls_md_info_t mbedtls_sha512_info; #endif +#if defined(MBEDTLS_SHA3_C) +extern const mbedtls_md_info_t mbedtls_sha3_224_info; +extern const mbedtls_md_info_t mbedtls_sha3_256_info; +extern const mbedtls_md_info_t mbedtls_sha3_384_info; +extern const mbedtls_md_info_t mbedtls_sha3_512_info; +#endif #ifdef __cplusplus } diff --git a/library/sha3.c b/library/sha3.c new file mode 100644 index 000000000000..959928e9da9e --- /dev/null +++ b/library/sha3.c @@ -0,0 +1,622 @@ +/* + * FIPS-202 compliant SHA3 implementation + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * The SHA-3 Secure Hash Standard was published by NIST in 2015. + * + * https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf + */ + +#include "common.h" + +#if defined(MBEDTLS_SHA3_C) + +#include "mbedtls/sha3.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#include "mbedtls/platform.h" +#endif /* MBEDTLS_SELF_TEST */ + +/* + * List of supported SHA-3 families + */ +static mbedtls_sha3_family_functions sha3_families[] = { + { MBEDTLS_SHA3_224, 1152, 224, 0x06 }, + { MBEDTLS_SHA3_256, 1088, 256, 0x06 }, + { MBEDTLS_SHA3_384, 832, 384, 0x06 }, + { MBEDTLS_SHA3_512, 576, 512, 0x06 }, + { MBEDTLS_SHA3_NONE, 0, 0, 0 } +}; + +static const uint64_t rc[24] = { + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, + 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, + 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, + 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, + 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008, +}; + +static const uint8_t rho[24] = { + 1, 62, 28, 27, 36, 44, 6, 55, 20, + 3, 10, 43, 25, 39, 41, 45, 15, + 21, 8, 18, 2, 61, 56, 14 +}; + +static const uint8_t pi[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1, +}; + +#define ROT64(x, y) (((x) << (y)) | ((x) >> (64U - (y)))) +#define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \ +} while (0) +#define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3))) +#define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0) + +/* The permutation function. */ +static void keccak_f1600(mbedtls_sha3_context *ctx) +{ + uint64_t lane[5]; + uint64_t *s = ctx->state; + int i; + + for (int round = 0; round < 24; round++) { + uint64_t t; + + /* Theta */ + lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; + lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; + lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; + lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; + lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; + + t = lane[4] ^ ROT64(lane[1], 1); + s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; + + t = lane[0] ^ ROT64(lane[2], 1); + s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; + + t = lane[1] ^ ROT64(lane[3], 1); + s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; + + t = lane[2] ^ ROT64(lane[4], 1); + s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; + + t = lane[3] ^ ROT64(lane[0], 1); + s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; + + /* Rho */ + for (i = 1; i < 25; i++) { + s[i] = ROT64(s[i], rho[i-1]); + } + + /* Pi */ + t = s[1]; + for (i = 0; i < 24; i++) { + SWAP(s[pi[i]], t); + } + + /* Chi */ + lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4]; + s[0] ^= (~lane[1]) & lane[2]; + s[1] ^= (~lane[2]) & lane[3]; + s[2] ^= (~lane[3]) & lane[4]; + s[3] ^= (~lane[4]) & lane[0]; + s[4] ^= (~lane[0]) & lane[1]; + + lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9]; + s[5] ^= (~lane[1]) & lane[2]; + s[6] ^= (~lane[2]) & lane[3]; + s[7] ^= (~lane[3]) & lane[4]; + s[8] ^= (~lane[4]) & lane[0]; + s[9] ^= (~lane[0]) & lane[1]; + + lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14]; + s[10] ^= (~lane[1]) & lane[2]; + s[11] ^= (~lane[2]) & lane[3]; + s[12] ^= (~lane[3]) & lane[4]; + s[13] ^= (~lane[4]) & lane[0]; + s[14] ^= (~lane[0]) & lane[1]; + + lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19]; + s[15] ^= (~lane[1]) & lane[2]; + s[16] ^= (~lane[2]) & lane[3]; + s[17] ^= (~lane[3]) & lane[4]; + s[18] ^= (~lane[4]) & lane[0]; + s[19] ^= (~lane[0]) & lane[1]; + + lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24]; + s[20] ^= (~lane[1]) & lane[2]; + s[21] ^= (~lane[2]) & lane[3]; + s[22] ^= (~lane[3]) & lane[4]; + s[23] ^= (~lane[4]) & lane[0]; + s[24] ^= (~lane[0]) & lane[1]; + + /* Iota */ + s[0] ^= rc[round]; + } +} + +void mbedtls_sha3_init(mbedtls_sha3_context *ctx) +{ + if (ctx == NULL) { + return; + } + + memset(ctx, 0, sizeof(mbedtls_sha3_context)); +} + +void mbedtls_sha3_free(mbedtls_sha3_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context)); +} + +void mbedtls_sha3_clone(mbedtls_sha3_context *dst, + const mbedtls_sha3_context *src) +{ + if (dst == NULL || src == NULL) { + return; + } + + *dst = *src; +} + +/* + * SHA-3 context setup + */ +int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id) +{ + mbedtls_sha3_family_functions *p = NULL; + if (ctx == NULL) { + return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; + } + + for (p = sha3_families; p->id != MBEDTLS_SHA3_NONE; p++) { + if (p->id == id) { + break; + } + } + + if (p == NULL || p->id == MBEDTLS_SHA3_NONE) { + return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; + } + + ctx->id = id; + ctx->r = p->r; + ctx->olen = p->olen / 8; + ctx->xor_byte = p->xor_byte; + ctx->max_block_size = ctx->r / 8; + + memset(ctx->state, 0, sizeof(ctx->state)); + ctx->index = 0; + + return 0; +} + +/* + * SHA-3 process buffer + */ +int mbedtls_sha3_update(mbedtls_sha3_context *ctx, + const uint8_t *input, + size_t ilen) +{ + if (ctx == NULL) { + return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; + } + + if (ilen == 0 || input == NULL) { + return 0; + } + + while (ilen-- > 0) { + ABSORB(ctx, ctx->index, *input++); + if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) { + keccak_f1600(ctx); + } + } + + return 0; +} + +int mbedtls_sha3_finish(mbedtls_sha3_context *ctx, + uint8_t *output, size_t olen) +{ + if (ctx == NULL || output == NULL) { + return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; + } + + /* Catch SHA-3 families, with fixed output length */ + if (ctx->olen > 0) { + if (ctx->olen > olen) { + return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA; + } + olen = ctx->olen; + } + + ABSORB(ctx, ctx->index, ctx->xor_byte); + ABSORB(ctx, ctx->max_block_size - 1, 0x80); + keccak_f1600(ctx); + ctx->index = 0; + + while (olen-- > 0) { + *output++ = SQUEEZE(ctx, ctx->index); + + if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) { + keccak_f1600(ctx); + } + } + + return 0; +} + +/* + * output = SHA3( input buffer ) + */ +int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input, + size_t ilen, uint8_t *output, size_t olen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_sha3_context ctx; + + mbedtls_sha3_init(&ctx); + + /* Sanity checks are performed in every mbedtls_sha3_xxx() */ + if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) { + goto exit; + } + + if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) { + goto exit; + } + + if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) { + goto exit; + } + +exit: + mbedtls_sha3_free(&ctx); + + return ret; +} + +/**************** Self-tests ****************/ + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char test_data[2][4] = +{ + "", + "abc", +}; + +static const size_t test_data_len[2] = +{ + 0, /* "" */ + 3 /* "abc" */ +}; + +static const unsigned char test_hash_sha3_224[2][28] = +{ + { /* "" */ + 0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7, + 0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB, + 0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F, + 0x5B, 0x5A, 0x6B, 0xC7 + }, + { /* "abc" */ + 0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A, + 0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F, + 0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD, + 0x73, 0xB4, 0x6F, 0xDF + } +}; + +static const unsigned char test_hash_sha3_256[2][32] = +{ + { /* "" */ + 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66, + 0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62, + 0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA, + 0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A + }, + { /* "abc" */ + 0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2, + 0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD, + 0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B, + 0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32 + } +}; + +static const unsigned char test_hash_sha3_384[2][48] = +{ + { /* "" */ + 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D, + 0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85, + 0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61, + 0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A, + 0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47, + 0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04 + }, + { /* "abc" */ + 0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9, + 0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D, + 0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25, + 0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2, + 0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5, + 0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25 + } +}; + +static const unsigned char test_hash_sha3_512[2][64] = +{ + { /* "" */ + 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5, + 0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E, + 0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59, + 0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6, + 0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C, + 0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58, + 0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3, + 0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26 + }, + { /* "abc" */ + 0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A, + 0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E, + 0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D, + 0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E, + 0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9, + 0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40, + 0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5, + 0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0 + } +}; + +static const unsigned char long_kat_hash_sha3_224[28] = +{ + 0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E, + 0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C, + 0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7, + 0xA7, 0xFD, 0x65, 0x3C +}; + +static const unsigned char long_kat_hash_sha3_256[32] = +{ + 0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34, + 0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6, + 0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99, + 0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1 +}; + +static const unsigned char long_kat_hash_sha3_384[48] = +{ + 0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53, + 0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD, + 0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E, + 0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84, + 0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42, + 0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40 +}; + +static const unsigned char long_kat_hash_sha3_512[64] = +{ + 0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB, + 0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E, + 0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF, + 0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59, + 0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE, + 0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66, + 0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E, + 0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87 +}; + +static int mbedtls_sha3_kat_test(int verbose, + const char *type_name, + mbedtls_sha3_id id, + int test_num) +{ + uint8_t hash[64]; + int result; + + result = mbedtls_sha3(id, + test_data[test_num], test_data_len[test_num], + hash, sizeof(hash)); + if (result != 0) { + if (verbose != 0) { + mbedtls_printf(" %s test %d error code: %d\n", + type_name, test_num, result); + } + + return result; + } + + switch (id) { + case MBEDTLS_SHA3_224: + result = memcmp(hash, test_hash_sha3_224[test_num], 28); + break; + case MBEDTLS_SHA3_256: + result = memcmp(hash, test_hash_sha3_256[test_num], 32); + break; + case MBEDTLS_SHA3_384: + result = memcmp(hash, test_hash_sha3_384[test_num], 48); + break; + case MBEDTLS_SHA3_512: + result = memcmp(hash, test_hash_sha3_512[test_num], 64); + break; + default: + break; + } + + if (0 != result) { + if (verbose != 0) { + mbedtls_printf(" %s test %d failed\n", type_name, test_num); + } + + return -1; + } + + if (verbose != 0) { + mbedtls_printf(" %s test %d passed\n", type_name, test_num); + } + + return 0; +} + +static int mbedtls_sha3_long_kat_test(int verbose, + const char *type_name, + mbedtls_sha3_id id) +{ + mbedtls_sha3_context ctx; + unsigned char buffer[1000]; + unsigned char hash[64]; + int i; + int result = 0; + + memset(buffer, 'a', 1000); + + if (verbose != 0) { + mbedtls_printf(" %s long KAT test ", type_name); + } + + mbedtls_sha3_init(&ctx); + + result = mbedtls_sha3_starts(&ctx, id); + if (result != 0) { + if (verbose != 0) { + mbedtls_printf("setup failed\n "); + } + } + + /* Process 1,000,000 (one million) 'a' characters */ + for (i = 0; i < 1000; i++) { + result = mbedtls_sha3_update(&ctx, buffer, 1000); + if (result != 0) { + if (verbose != 0) { + mbedtls_printf("update error code: %i\n", result); + } + + goto cleanup; + } + } + + result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash)); + if (result != 0) { + if (verbose != 0) { + mbedtls_printf("finish error code: %d\n", result); + } + + goto cleanup; + } + + switch (id) { + case MBEDTLS_SHA3_224: + result = memcmp(hash, long_kat_hash_sha3_224, 28); + break; + case MBEDTLS_SHA3_256: + result = memcmp(hash, long_kat_hash_sha3_256, 32); + break; + case MBEDTLS_SHA3_384: + result = memcmp(hash, long_kat_hash_sha3_384, 48); + break; + case MBEDTLS_SHA3_512: + result = memcmp(hash, long_kat_hash_sha3_512, 64); + break; + default: + break; + } + + if (result != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + +cleanup: + mbedtls_sha3_free(&ctx); + return result; +} + +int mbedtls_sha3_self_test(int verbose) +{ + int i; + + /* SHA3 Known Answer Tests (KAT) */ + for (i = 0; i < 2; i++) { + if (0 != mbedtls_sha3_kat_test(verbose, + "SHA3-224", MBEDTLS_SHA3_224, i)) { + return 1; + } + + if (0 != mbedtls_sha3_kat_test(verbose, + "SHA3-256", MBEDTLS_SHA3_256, i)) { + return 1; + } + + if (0 != mbedtls_sha3_kat_test(verbose, + "SHA3-384", MBEDTLS_SHA3_384, i)) { + return 1; + } + + if (0 != mbedtls_sha3_kat_test(verbose, + "SHA3-512", MBEDTLS_SHA3_512, i)) { + return 1; + } + } + + /* SHA3 long KAT tests */ + if (0 != mbedtls_sha3_long_kat_test(verbose, + "SHA3-224", MBEDTLS_SHA3_224)) { + return 1; + } + + if (0 != mbedtls_sha3_long_kat_test(verbose, + "SHA3-256", MBEDTLS_SHA3_256)) { + return 1; + } + + if (0 != mbedtls_sha3_long_kat_test(verbose, + "SHA3-384", MBEDTLS_SHA3_384)) { + return 1; + } + + if (0 != mbedtls_sha3_long_kat_test(verbose, + "SHA3-512", MBEDTLS_SHA3_512)) { + return 1; + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + return 0; +} +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA3_C */ diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 226faf35c3de..ecc4e94a6342 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -39,6 +39,7 @@ int main(void) #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#include "mbedtls/sha3.h" #include "mbedtls/des.h" #include "mbedtls/aes.h" @@ -113,11 +114,12 @@ static void mbedtls_set_alarm(int seconds); #define TITLE_LEN 25 #define OPTIONS \ - "md5, ripemd160, sha1, sha256, sha512,\n" \ - "des3, des, camellia, chacha20,\n" \ + "md5, ripemd160, sha1, sha256, sha512,\n" \ + "sha3_224, sha3_256, sha3_384, sha3_512,\n" \ + "des3, des, camellia, chacha20,\n" \ "aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly,\n" \ "aes_cmac, des3_cmac, poly1305\n" \ - "ctr_drbg, hmac_drbg\n" \ + "ctr_drbg, hmac_drbg\n" \ "rsa, dhm, ecdsa, ecdh.\n" #if defined(MBEDTLS_ERROR_C) @@ -506,6 +508,7 @@ unsigned char buf[BUFSIZE]; typedef struct { char md5, ripemd160, sha1, sha256, sha512, + sha3_224, sha3_256, sha3_384, sha3_512, des3, des, aes_cbc, aes_gcm, aes_ccm, aes_xts, chachapoly, aes_cmac, des3_cmac, @@ -553,6 +556,14 @@ int main(int argc, char *argv[]) todo.sha256 = 1; } else if (strcmp(argv[i], "sha512") == 0) { todo.sha512 = 1; + } else if (strcmp(argv[i], "sha3_224") == 0) { + todo.sha3_224 = 1; + } else if (strcmp(argv[i], "sha3_256") == 0) { + todo.sha3_256 = 1; + } else if (strcmp(argv[i], "sha3_384") == 0) { + todo.sha3_384 = 1; + } else if (strcmp(argv[i], "sha3_512") == 0) { + todo.sha3_512 = 1; } else if (strcmp(argv[i], "des3") == 0) { todo.des3 = 1; } else if (strcmp(argv[i], "des") == 0) { @@ -645,6 +656,20 @@ int main(int argc, char *argv[]) TIME_AND_TSC("SHA-512", mbedtls_sha512(buf, BUFSIZE, tmp, 0)); } #endif +#if defined(MBEDTLS_SHA3_C) + if (todo.sha3_224) { + TIME_AND_TSC("SHA3-224", mbedtls_sha3(MBEDTLS_SHA3_224, buf, BUFSIZE, tmp, 28)); + } + if (todo.sha3_256) { + TIME_AND_TSC("SHA3-256", mbedtls_sha3(MBEDTLS_SHA3_256, buf, BUFSIZE, tmp, 32)); + } + if (todo.sha3_384) { + TIME_AND_TSC("SHA3-384", mbedtls_sha3(MBEDTLS_SHA3_384, buf, BUFSIZE, tmp, 48)); + } + if (todo.sha3_512) { + TIME_AND_TSC("SHA3-512", mbedtls_sha3(MBEDTLS_SHA3_512, buf, BUFSIZE, tmp, 64)); + } +#endif #if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_CIPHER_MODE_CBC) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 13423a1a6af3..f896d4f9da09 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -33,6 +33,7 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#include "mbedtls/sha3.h" #include "mbedtls/des.h" #include "mbedtls/aes.h" #include "mbedtls/camellia.h" @@ -251,6 +252,9 @@ const selftest_t selftests[] = #if defined(MBEDTLS_SHA512_C) { "sha512", mbedtls_sha512_self_test }, #endif +#if defined(MBEDTLS_SHA3_C) + { "sha3", mbedtls_sha3_self_test }, +#endif #if defined(MBEDTLS_DES_C) { "des", mbedtls_des_self_test }, #endif diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index 878cfba33cf8..664a349e9823 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -49,7 +49,7 @@ CAMELLIA CCM CHACHA20 CHACHAPOLY CMAC CTR_DRBG DES ENTROPY ERROR GCM HKDF HMAC_DRBG LMS MD5 NET OID PADLOCK PBKDF2 PLATFORM POLY1305 RIPEMD160 - SHA1 SHA256 SHA512 THREADING ); + SHA1 SHA256 SHA512 SHA3 THREADING ); my @high_level_modules = qw( CIPHER DHM ECP MD PEM PK PKCS12 PKCS5 RSA SSL X509 PKCS7 ); diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py index b29ea0aa61ac..61908eb817a9 100755 --- a/tests/scripts/depends.py +++ b/tests/scripts/depends.py @@ -426,7 +426,8 @@ def __init__(self, options, conf): 'hashes': DualDomain(hash_symbols, build_and_test, exclude=r'MBEDTLS_(MD|RIPEMD|SHA1_)' \ '|MBEDTLS_SHA224_' \ - '|MBEDTLS_SHA384_'), + '|MBEDTLS_SHA384_' \ + '|MBEDTLS_SHA3_'), # Key exchange types. 'kex': ExclusiveDomain(key_exchange_symbols, build_and_test), 'pkalgs': ComplementaryDomain(['MBEDTLS_ECDSA_C', diff --git a/tests/suites/test_suite_md.data b/tests/suites/test_suite_md.data index ccc7b10ae4a1..0b0afee723b7 100644 --- a/tests/suites/test_suite_md.data +++ b/tests/suites/test_suite_md.data @@ -33,6 +33,22 @@ Information on SHA512 depends_on:MBEDTLS_MD_CAN_SHA512 md_info:MBEDTLS_MD_SHA512:"SHA512":64 +Information on SHA3-224 +depends_on:MBEDTLS_SHA3_C +md_info:MBEDTLS_MD_SHA3_224:"SHA3-224":28 + +Information on SHA3-256 +depends_on:MBEDTLS_SHA3_C +md_info:MBEDTLS_MD_SHA3_256:"SHA3-256":32 + +Information on SHA3-384 +depends_on:MBEDTLS_SHA3_C +md_info:MBEDTLS_MD_SHA3_384:"SHA3-384":48 + +Information on SHA3-512 +depends_on:MBEDTLS_SHA3_C +md_info:MBEDTLS_MD_SHA3_512:"SHA3-512":64 + generic mbedtls_md5 Test vector RFC1321 #1 depends_on:MBEDTLS_MD_CAN_MD5 md_text:MBEDTLS_MD_MD5:"":"d41d8cd98f00b204e9800998ecf8427e" @@ -93,6 +109,22 @@ generic mbedtls_ripemd160 Test vector from paper #8 depends_on:MBEDTLS_MD_CAN_RIPEMD160 md_text:MBEDTLS_MD_RIPEMD160:"12345678901234567890123456789012345678901234567890123456789012345678901234567890":"9b752e45573d4b39f4dbd3323cab82bf63326bfb" +generic mbedtls_sha3 SHA3-224 Test vector from CAVS 19.0 with Len = 8 +depends_on:MBEDTLS_SHA3_C +md_hex:MBEDTLS_MD_SHA3_224:"01":"488286d9d32716e5881ea1ee51f36d3660d70f0db03b3f612ce9eda4" + +generic mbedtls_sha3 SHA3-256 Test vector from CAVS 19.0 with Len = 8 +depends_on:MBEDTLS_SHA3_C +md_hex:MBEDTLS_MD_SHA3_256:"e9":"f0d04dd1e6cfc29a4460d521796852f25d9ef8d28b44ee91ff5b759d72c1e6d6" + +generic mbedtls_sha3 SHA3-384 Test vector from CAVS 19.0 with Len = 8 +depends_on:MBEDTLS_SHA3_C +md_hex:MBEDTLS_MD_SHA3_384:"80":"7541384852e10ff10d5fb6a7213a4a6c15ccc86d8bc1068ac04f69277142944f4ee50d91fdc56553db06b2f5039c8ab7" + +generic mbedtls_sha3 SHA3-512 Test vector from CAVS 19.0 with Len = 8 +depends_on:MBEDTLS_SHA3_C +md_hex:MBEDTLS_MD_SHA3_512:"e5":"150240baf95fb36f8ccb87a19a41767e7aed95125075a2b2dbba6e565e1ce8575f2b042b62e29a04e9440314a821c6224182964d8b557b16a492b3806f4c39c1" + generic HMAC-MD5 Hash File OpenSSL test #1 depends_on:MBEDTLS_MD_CAN_MD5 mbedtls_md_hmac:MBEDTLS_MD_MD5:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"42552882f00bd4633ea81135a184b284" @@ -225,6 +257,22 @@ generic multi step mbedtls_ripemd160 Test vector from paper #8 depends_on:MBEDTLS_MD_CAN_RIPEMD160 md_text_multi:MBEDTLS_MD_RIPEMD160:"12345678901234567890123456789012345678901234567890123456789012345678901234567890":"9b752e45573d4b39f4dbd3323cab82bf63326bfb" +generic multi step mbedtls_sha3 SHA3-224 Test vector from CAVS 19.0 with Len = 48 +depends_on:MBEDTLS_SHA3_C +md_hex_multi:MBEDTLS_MD_SHA3_224:"e7183e4d89c9":"650618f3b945c07de85b8478d69609647d5e2a432c6b15fbb3db91e4" + +generic multi step mbedtls_sha3 SHA3-256 Test vector from CAVS 19.0 with Len = 48 +depends_on:MBEDTLS_SHA3_C +md_hex_multi:MBEDTLS_MD_SHA3_256:"e6fd42037f80":"2294f8d3834f24aa9037c431f8c233a66a57b23fa3de10530bbb6911f6e1850f" + +generic multi step mbedtls_sha3 SHA3-384 Test vector from CAVS 19.0 with Len = 48 +depends_on:MBEDTLS_SHA3_C +md_hex_multi:MBEDTLS_MD_SHA3_384:"5a6659e9f0e7":"21b1f3f63b907f968821185a7fe30b16d47e1d6ee5b9c80be68947854de7a8ef4a03a6b2e4ec96abdd4fa29ab9796f28" + +generic multi step mbedtls_sha3 SHA3-512 Test vector from CAVS 19.0 with Len = 48 +depends_on:MBEDTLS_SHA3_C +md_hex_multi:MBEDTLS_MD_SHA3_512:"71a986d2f662":"def6aac2b08c98d56a0501a8cb93f5b47d6322daf99e03255457c303326395f765576930f8571d89c01e727cc79c2d4497f85c45691b554e20da810c2bc865ef" + generic multi step HMAC-MD5 Hash File OpenSSL test #1 depends_on:MBEDTLS_MD_CAN_MD5 md_hmac_multi:MBEDTLS_MD_MD5:16:"61616161616161616161616161616161":"b91ce5ac77d33c234e61002ed6":"42552882f00bd4633ea81135a184b284" @@ -473,6 +521,70 @@ generic HMAC-SHA-512 Test Vector NIST CAVS #6 depends_on:MBEDTLS_MD_CAN_SHA512 mbedtls_md_hmac:MBEDTLS_MD_SHA512:48:"8ab783d5acf32efa0d9c0a21abce955e96630d89":"17371e013dce839963d54418e97be4bd9fa3cb2a368a5220f5aa1b8aaddfa3bdefc91afe7c717244fd2fb640f5cb9d9bf3e25f7f0c8bc758883b89dcdce6d749d9672fed222277ece3e84b3ec01b96f70c125fcb3cbee6d19b8ef0873f915f173bdb05d81629ba187cc8ac1934b2f75952fb7616ae6bd812946df694bd2763af":"9ac7ca8d1aefc166b046e4cf7602ebe181a0e5055474bff5b342106731da0d7e48e4d87bc0a6f05871574289a1b099f8" +HMAC-SHA3-224: NIST example #1: keylenblocklen +depends_on:MBEDTLS_SHA3_C +mbedtls_md_hmac:MBEDTLS_MD_SHA3_224:28:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"078695eecc227c636ad31d063a15dd05a7e819a66ec6d8de1e193e59" + +HMAC-SHA3-224: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +mbedtls_md_hmac:MBEDTLS_MD_SHA3_256:32:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"9bcf2c238e235c3ce88404e813bd2f3a97185ac6f238c63d6229a00b07974258" + +HMAC-SHA3-256: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +mbedtls_md_hmac:MBEDTLS_MD_SHA3_384:48:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"e5ae4c739f455279368ebf36d4f5354c95aa184c899d3870e460ebc288ef1f9470053f73f7c6da2a71bcaec38ce7d6ac" + +HMAC-SHA3-384: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +mbedtls_md_hmac:MBEDTLS_MD_SHA3_512:64:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"5f464f5e5b7848e3885e49b2c385f0694985d0e38966242dc4a5fe3fea4b37d46b65ceced5dcf59438dd840bab22269f0ba7febdb9fcf74602a35666b2a32915" + +HMAC-SHA3-512: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +md_hmac_multi:MBEDTLS_MD_SHA3_224:28:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"078695eecc227c636ad31d063a15dd05a7e819a66ec6d8de1e193e59" + +HMAC-SHA3-224 multi-step: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +md_hmac_multi:MBEDTLS_MD_SHA3_256:32:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"9bcf2c238e235c3ce88404e813bd2f3a97185ac6f238c63d6229a00b07974258" + +HMAC-SHA3-256 multi-step: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +md_hmac_multi:MBEDTLS_MD_SHA3_384:48:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"e5ae4c739f455279368ebf36d4f5354c95aa184c899d3870e460ebc288ef1f9470053f73f7c6da2a71bcaec38ce7d6ac" + +HMAC-SHA3-384 multi-step: NIST example #4: keylenblocklen +depends_on:MBEDTLS_SHA3_C +md_hmac_multi:MBEDTLS_MD_SHA3_512:64:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687":"53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e":"5f464f5e5b7848e3885e49b2c385f0694985d0e38966242dc4a5fe3fea4b37d46b65ceced5dcf59438dd840bab22269f0ba7febdb9fcf74602a35666b2a32915" + +HMAC-SHA3-512 multi-step: NIST example #4: keylenlen); + + TEST_ASSERT(mbedtls_sha3(family, in->x, in->len, output, hash->len) == 0); + + ASSERT_COMPARE(output, hash->len, hash->x, hash->len); + +exit: + mbedtls_free(output); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SHA3_C */ +void mbedtls_sha3_multi(int family, data_t *in, data_t *hash) +{ + unsigned char *output = NULL; + mbedtls_sha3_context ctx; + const unsigned int block_size = 256; + + ASSERT_ALLOC(output, hash->len); + + mbedtls_sha3_init(&ctx); + mbedtls_sha3_starts(&ctx, family); + + for (size_t l = 0; l < in->len; l += block_size) { + TEST_ASSERT(mbedtls_sha3_update(&ctx, in->x + l, MIN(in->len - l, block_size)) == 0); + } + + TEST_ASSERT(mbedtls_sha3_finish(&ctx, output, hash->len) == 0); + + ASSERT_COMPARE(output, hash->len, hash->x, hash->len); + +exit: + mbedtls_free(output); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SHA3_C */ +void sha3_streaming(int type, data_t *input) +{ + mbedtls_sha3_context ctx; + unsigned char reference_hash[64]; + unsigned char hash[64]; + size_t chunk_size; + size_t hash_length = (type == MBEDTLS_SHA3_224 ? 28 : + type == MBEDTLS_SHA3_256 ? 32 : + type == MBEDTLS_SHA3_384 ? 48 : + type == MBEDTLS_SHA3_512 ? 64 : + 0); + + mbedtls_sha3_init(&ctx); + memset(reference_hash, 0, sizeof(reference_hash)); + memset(hash, 0, sizeof(hash)); + TEST_ASSERT(hash_length != 0); + + /* Generate a reference hash */ + mbedtls_sha3(type, input->x, input->len, reference_hash, hash_length); + + /* Repeat each test with increasingly-sized data chunks + * E.g. start by processing bytes individual bytes, then 2-byte chunks, + * then 3-byte chunks, and so on... + * At each test ensure that the same hash is generated. + */ + for (chunk_size = 1; chunk_size < input->len; chunk_size++) { + size_t i; + size_t remaining = input->len; + + mbedtls_sha3_init(&ctx); + TEST_ASSERT(mbedtls_sha3_starts(&ctx, type) == 0); + + for (i = 0; i < input->len; i += chunk_size) { + size_t len = remaining >= chunk_size ? chunk_size : remaining; + TEST_ASSERT(mbedtls_sha3_update(&ctx, input->x + i, len) == 0); + remaining -= len; + } + + mbedtls_sha3_finish(&ctx, hash, hash_length); + mbedtls_sha3_free(&ctx); + + ASSERT_COMPARE(hash, hash_length, reference_hash, hash_length); + } + +exit: + mbedtls_sha3_free(&ctx); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SHA3_C */ +void sha3_reuse(data_t *input1, data_t *hash1, + data_t *input2, data_t *hash2) +{ + unsigned char output[64]; + mbedtls_sha3_context ctx; + mbedtls_sha3_id type1, type2; + + mbedtls_sha3_init(&ctx); + switch (hash1->len) { + case 28: type1 = MBEDTLS_SHA3_224; break; + case 32: type1 = MBEDTLS_SHA3_256; break; + case 48: type1 = MBEDTLS_SHA3_384; break; + case 64: type1 = MBEDTLS_SHA3_512; break; + default: TEST_ASSERT(!"hash1->len validity"); break; + } + switch (hash2->len) { + case 28: type2 = MBEDTLS_SHA3_224; break; + case 32: type2 = MBEDTLS_SHA3_256; break; + case 48: type2 = MBEDTLS_SHA3_384; break; + case 64: type2 = MBEDTLS_SHA3_512; break; + default: TEST_ASSERT(!"hash2->len validity"); break; + } + + /* Round 1 */ + TEST_ASSERT(mbedtls_sha3_starts(&ctx, type1) == 0); + TEST_ASSERT(mbedtls_sha3_update(&ctx, input1->x, input1->len) == 0); + TEST_ASSERT(mbedtls_sha3_finish(&ctx, output, sizeof(output)) == 0); + ASSERT_COMPARE(output, hash1->len, hash1->x, hash1->len); + + /* Round 2 */ + TEST_ASSERT(mbedtls_sha3_starts(&ctx, type2) == 0); + TEST_ASSERT(mbedtls_sha3_update(&ctx, input2->x, input2->len) == 0); + TEST_ASSERT(mbedtls_sha3_finish(&ctx, output, sizeof(output)) == 0); + ASSERT_COMPARE(output, hash2->len, hash2->x, hash2->len); + +exit: + mbedtls_sha3_free(&ctx); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SHA3_C:MBEDTLS_SELF_TEST */ +void sha3_selftest() +{ + TEST_ASSERT(mbedtls_sha3_self_test(0) == 0); +} +/* END_CASE */