LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - sha3.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.4 % 247 122
Test Date: 2025-06-29 08:09:00 Functions: 63.6 % 11 7

            Line data    Source code
       1              : /*
       2              :  *  FIPS-202 compliant SHA3 implementation
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : /*
       8              :  *  The SHA-3 Secure Hash Standard was published by NIST in 2015.
       9              :  *
      10              :  *  https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
      11              :  */
      12              : 
      13              : #include "common.h"
      14              : 
      15              : #if defined(MBEDTLS_SHA3_C)
      16              : 
      17              : /*
      18              :  * These macros select manually unrolled implementations of parts of the main permutation function.
      19              :  *
      20              :  * Unrolling has a major impact on both performance and code size. gcc performance benefits a lot
      21              :  * from manually unrolling at higher optimisation levels.
      22              :  *
      23              :  * Depending on your size/perf priorities, compiler and target, it may be beneficial to adjust
      24              :  * these; the defaults here should give sensible trade-offs for gcc and clang on aarch64 and
      25              :  * x86-64.
      26              :  */
      27              : #if !defined(MBEDTLS_SHA3_THETA_UNROLL)
      28              :     #define MBEDTLS_SHA3_THETA_UNROLL 0 //no-check-names
      29              : #endif
      30              : #if !defined(MBEDTLS_SHA3_CHI_UNROLL)
      31              :     #if defined(__OPTIMIZE_SIZE__)
      32              :         #define MBEDTLS_SHA3_CHI_UNROLL 0 //no-check-names
      33              :     #else
      34              :         #define MBEDTLS_SHA3_CHI_UNROLL 1 //no-check-names
      35              :     #endif
      36              : #endif
      37              : #if !defined(MBEDTLS_SHA3_PI_UNROLL)
      38              :     #define MBEDTLS_SHA3_PI_UNROLL 1 //no-check-names
      39              : #endif
      40              : #if !defined(MBEDTLS_SHA3_RHO_UNROLL)
      41              :     #define MBEDTLS_SHA3_RHO_UNROLL 1 //no-check-names
      42              : #endif
      43              : 
      44              : #include "mbedtls/sha3.h"
      45              : #include "mbedtls/platform_util.h"
      46              : #include "mbedtls/error.h"
      47              : 
      48              : #include <string.h>
      49              : 
      50              : #if defined(MBEDTLS_SELF_TEST)
      51              : #include "mbedtls/platform.h"
      52              : #endif /* MBEDTLS_SELF_TEST */
      53              : 
      54              : #define XOR_BYTE 0x6
      55              : 
      56              : /* Precomputed masks for the iota transform.
      57              :  *
      58              :  * Each round uses a 64-bit mask value. In each mask values, only
      59              :  * bits whose position is of the form 2^k-1 can be set, thus only
      60              :  * 7 of 64 bits of the mask need to be known for each mask value.
      61              :  *
      62              :  * We use a compressed encoding of the mask where bits 63, 31 and 15
      63              :  * are moved to bits 4-6. This allows us to make each mask value
      64              :  * 1 byte rather than 8 bytes, saving 7*24 = 168 bytes of data (with
      65              :  * perhaps a little variation due to alignment). Decompressing this
      66              :  * requires a little code, but much less than the savings on the table.
      67              :  *
      68              :  * The impact on performance depends on the platform and compiler.
      69              :  * There's a bit more computation, but less memory bandwidth. A quick
      70              :  * benchmark on x86_64 shows a 7% speed improvement with GCC and a
      71              :  * 5% speed penalty with Clang, compared to the naive uint64_t[24] table.
      72              :  * YMMV.
      73              :  */
      74              : /* Helper macro to set the values of the higher bits in unused low positions */
      75              : #define H(b63, b31, b15) (b63 << 6 | b31 << 5 | b15 << 4)
      76              : static const uint8_t iota_r_packed[24] = {
      77              :     H(0, 0, 0) | 0x01, H(0, 0, 1) | 0x82, H(1, 0, 1) | 0x8a, H(1, 1, 1) | 0x00,
      78              :     H(0, 0, 1) | 0x8b, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x09,
      79              :     H(0, 0, 0) | 0x8a, H(0, 0, 0) | 0x88, H(0, 1, 1) | 0x09, H(0, 1, 0) | 0x0a,
      80              :     H(0, 1, 1) | 0x8b, H(1, 0, 0) | 0x8b, H(1, 0, 1) | 0x89, H(1, 0, 1) | 0x03,
      81              :     H(1, 0, 1) | 0x02, H(1, 0, 0) | 0x80, H(0, 0, 1) | 0x0a, H(1, 1, 0) | 0x0a,
      82              :     H(1, 1, 1) | 0x81, H(1, 0, 1) | 0x80, H(0, 1, 0) | 0x01, H(1, 1, 1) | 0x08,
      83              : };
      84              : #undef H
      85              : 
      86              : static const uint32_t rho[6] = {
      87              :     0x3f022425, 0x1c143a09, 0x2c3d3615, 0x27191713, 0x312b382e, 0x3e030832
      88              : };
      89              : 
      90              : static const uint32_t pi[6] = {
      91              :     0x110b070a, 0x10050312, 0x04181508, 0x0d13170f, 0x0e14020c, 0x01060916
      92              : };
      93              : 
      94              : #define ROTR64(x, y) (((x) << (64U - (y))) | ((x) >> (y))) // 64-bit rotate right
      95              : #define ABSORB(ctx, idx, v) do { ctx->state[(idx) >> 3] ^= ((uint64_t) (v)) << (((idx) & 0x7) << 3); \
      96              : } while (0)
      97              : #define SQUEEZE(ctx, idx) ((uint8_t) (ctx->state[(idx) >> 3] >> (((idx) & 0x7) << 3)))
      98              : #define SWAP(x, y) do { uint64_t tmp = (x); (x) = (y); (y) = tmp; } while (0)
      99              : 
     100              : /* The permutation function.  */
     101            3 : static void keccak_f1600(mbedtls_sha3_context *ctx)
     102              : {
     103              :     uint64_t lane[5];
     104            3 :     uint64_t *s = ctx->state;
     105              :     int i;
     106              : 
     107           75 :     for (int round = 0; round < 24; round++) {
     108              :         uint64_t t;
     109              : 
     110              :         /* Theta */
     111              : #if MBEDTLS_SHA3_THETA_UNROLL == 0 //no-check-names
     112          432 :         for (i = 0; i < 5; i++) {
     113          360 :             lane[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
     114              :         }
     115          432 :         for (i = 0; i < 5; i++) {
     116          360 :             t = lane[(i + 4) % 5] ^ ROTR64(lane[(i + 1) % 5], 63);
     117          360 :             s[i] ^= t; s[i + 5] ^= t; s[i + 10] ^= t; s[i + 15] ^= t; s[i + 20] ^= t;
     118              :         }
     119              : #else
     120              :         lane[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];
     121              :         lane[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];
     122              :         lane[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];
     123              :         lane[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];
     124              :         lane[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];
     125              : 
     126              :         t = lane[4] ^ ROTR64(lane[1], 63);
     127              :         s[0] ^= t; s[5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t;
     128              : 
     129              :         t = lane[0] ^ ROTR64(lane[2], 63);
     130              :         s[1] ^= t; s[6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t;
     131              : 
     132              :         t = lane[1] ^ ROTR64(lane[3], 63);
     133              :         s[2] ^= t; s[7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t;
     134              : 
     135              :         t = lane[2] ^ ROTR64(lane[4], 63);
     136              :         s[3] ^= t; s[8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t;
     137              : 
     138              :         t = lane[3] ^ ROTR64(lane[0], 63);
     139              :         s[4] ^= t; s[9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t;
     140              : #endif
     141              : 
     142              :         /* Rho */
     143          504 :         for (i = 1; i < 25; i += 4) {
     144          432 :             uint32_t r = rho[(i - 1) >> 2];
     145              : #if MBEDTLS_SHA3_RHO_UNROLL == 0
     146              :             for (int j = i; j < i + 4; j++) {
     147              :                 uint8_t r8 = (uint8_t) (r >> 24);
     148              :                 r <<= 8;
     149              :                 s[j] = ROTR64(s[j], r8);
     150              :             }
     151              : #else
     152          432 :             s[i + 0] = ROTR64(s[i + 0], MBEDTLS_BYTE_3(r));
     153          432 :             s[i + 1] = ROTR64(s[i + 1], MBEDTLS_BYTE_2(r));
     154          432 :             s[i + 2] = ROTR64(s[i + 2], MBEDTLS_BYTE_1(r));
     155          432 :             s[i + 3] = ROTR64(s[i + 3], MBEDTLS_BYTE_0(r));
     156              : #endif
     157              :         }
     158              : 
     159              :         /* Pi */
     160           72 :         t = s[1];
     161              : #if MBEDTLS_SHA3_PI_UNROLL == 0
     162              :         for (i = 0; i < 24; i += 4) {
     163              :             uint32_t p = pi[i >> 2];
     164              :             for (unsigned j = 0; j < 4; j++) {
     165              :                 SWAP(s[p & 0xff], t);
     166              :                 p >>= 8;
     167              :             }
     168              :         }
     169              : #else
     170           72 :         uint32_t p = pi[0];
     171           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     172           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     173           72 :         p = pi[1];
     174           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     175           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     176           72 :         p = pi[2];
     177           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     178           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     179           72 :         p = pi[3];
     180           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     181           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     182           72 :         p = pi[4];
     183           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     184           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     185           72 :         p = pi[5];
     186           72 :         SWAP(s[MBEDTLS_BYTE_0(p)], t); SWAP(s[MBEDTLS_BYTE_1(p)], t);
     187           72 :         SWAP(s[MBEDTLS_BYTE_2(p)], t); SWAP(s[MBEDTLS_BYTE_3(p)], t);
     188              : #endif
     189              : 
     190              :         /* Chi */
     191              : #if MBEDTLS_SHA3_CHI_UNROLL == 0 //no-check-names
     192              :         for (i = 0; i <= 20; i += 5) {
     193              :             lane[0] = s[i]; lane[1] = s[i + 1]; lane[2] = s[i + 2];
     194              :             lane[3] = s[i + 3]; lane[4] = s[i + 4];
     195              :             s[i + 0] ^= (~lane[1]) & lane[2];
     196              :             s[i + 1] ^= (~lane[2]) & lane[3];
     197              :             s[i + 2] ^= (~lane[3]) & lane[4];
     198              :             s[i + 3] ^= (~lane[4]) & lane[0];
     199              :             s[i + 4] ^= (~lane[0]) & lane[1];
     200              :         }
     201              : #else
     202           72 :         lane[0] = s[0]; lane[1] = s[1]; lane[2] = s[2]; lane[3] = s[3]; lane[4] = s[4];
     203           72 :         s[0] ^= (~lane[1]) & lane[2];
     204           72 :         s[1] ^= (~lane[2]) & lane[3];
     205           72 :         s[2] ^= (~lane[3]) & lane[4];
     206           72 :         s[3] ^= (~lane[4]) & lane[0];
     207           72 :         s[4] ^= (~lane[0]) & lane[1];
     208              : 
     209           72 :         lane[0] = s[5]; lane[1] = s[6]; lane[2] = s[7]; lane[3] = s[8]; lane[4] = s[9];
     210           72 :         s[5] ^= (~lane[1]) & lane[2];
     211           72 :         s[6] ^= (~lane[2]) & lane[3];
     212           72 :         s[7] ^= (~lane[3]) & lane[4];
     213           72 :         s[8] ^= (~lane[4]) & lane[0];
     214           72 :         s[9] ^= (~lane[0]) & lane[1];
     215              : 
     216           72 :         lane[0] = s[10]; lane[1] = s[11]; lane[2] = s[12]; lane[3] = s[13]; lane[4] = s[14];
     217           72 :         s[10] ^= (~lane[1]) & lane[2];
     218           72 :         s[11] ^= (~lane[2]) & lane[3];
     219           72 :         s[12] ^= (~lane[3]) & lane[4];
     220           72 :         s[13] ^= (~lane[4]) & lane[0];
     221           72 :         s[14] ^= (~lane[0]) & lane[1];
     222              : 
     223           72 :         lane[0] = s[15]; lane[1] = s[16]; lane[2] = s[17]; lane[3] = s[18]; lane[4] = s[19];
     224           72 :         s[15] ^= (~lane[1]) & lane[2];
     225           72 :         s[16] ^= (~lane[2]) & lane[3];
     226           72 :         s[17] ^= (~lane[3]) & lane[4];
     227           72 :         s[18] ^= (~lane[4]) & lane[0];
     228           72 :         s[19] ^= (~lane[0]) & lane[1];
     229              : 
     230           72 :         lane[0] = s[20]; lane[1] = s[21]; lane[2] = s[22]; lane[3] = s[23]; lane[4] = s[24];
     231           72 :         s[20] ^= (~lane[1]) & lane[2];
     232           72 :         s[21] ^= (~lane[2]) & lane[3];
     233           72 :         s[22] ^= (~lane[3]) & lane[4];
     234           72 :         s[23] ^= (~lane[4]) & lane[0];
     235           72 :         s[24] ^= (~lane[0]) & lane[1];
     236              : #endif
     237              : 
     238              :         /* Iota */
     239              :         /* Decompress the round masks (see definition of rc) */
     240           72 :         s[0] ^= ((iota_r_packed[round] & 0x40ull) << 57 |
     241           72 :                  (iota_r_packed[round] & 0x20ull) << 26 |
     242           72 :                  (iota_r_packed[round] & 0x10ull) << 11 |
     243           72 :                  (iota_r_packed[round] & 0x8f));
     244              :     }
     245            3 : }
     246              : 
     247            3 : void mbedtls_sha3_init(mbedtls_sha3_context *ctx)
     248              : {
     249            3 :     memset(ctx, 0, sizeof(mbedtls_sha3_context));
     250            3 : }
     251              : 
     252            6 : void mbedtls_sha3_free(mbedtls_sha3_context *ctx)
     253              : {
     254            6 :     if (ctx == NULL) {
     255            0 :         return;
     256              :     }
     257              : 
     258            6 :     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha3_context));
     259              : }
     260              : 
     261            0 : void mbedtls_sha3_clone(mbedtls_sha3_context *dst,
     262              :                         const mbedtls_sha3_context *src)
     263              : {
     264            0 :     *dst = *src;
     265            0 : }
     266              : 
     267              : /*
     268              :  * SHA-3 context setup
     269              :  */
     270            3 : int mbedtls_sha3_starts(mbedtls_sha3_context *ctx, mbedtls_sha3_id id)
     271              : {
     272            3 :     switch (id) {
     273            0 :         case MBEDTLS_SHA3_224:
     274            0 :             ctx->olen = 224 / 8;
     275            0 :             ctx->max_block_size = 1152 / 8;
     276            0 :             break;
     277            1 :         case MBEDTLS_SHA3_256:
     278            1 :             ctx->olen = 256 / 8;
     279            1 :             ctx->max_block_size = 1088 / 8;
     280            1 :             break;
     281            1 :         case MBEDTLS_SHA3_384:
     282            1 :             ctx->olen = 384 / 8;
     283            1 :             ctx->max_block_size = 832 / 8;
     284            1 :             break;
     285            1 :         case MBEDTLS_SHA3_512:
     286            1 :             ctx->olen = 512 / 8;
     287            1 :             ctx->max_block_size = 576 / 8;
     288            1 :             break;
     289            0 :         default:
     290            0 :             return MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
     291              :     }
     292              : 
     293            3 :     memset(ctx->state, 0, sizeof(ctx->state));
     294            3 :     ctx->index = 0;
     295              : 
     296            3 :     return 0;
     297              : }
     298              : 
     299              : /*
     300              :  * SHA-3 process buffer
     301              :  */
     302            3 : int mbedtls_sha3_update(mbedtls_sha3_context *ctx,
     303              :                         const uint8_t *input,
     304              :                         size_t ilen)
     305              : {
     306            3 :     if (ilen >= 8) {
     307              :         // 8-byte align index
     308            0 :         int align_bytes = 8 - (ctx->index % 8);
     309            0 :         if (align_bytes) {
     310            0 :             for (; align_bytes > 0; align_bytes--) {
     311            0 :                 ABSORB(ctx, ctx->index, *input++);
     312            0 :                 ilen--;
     313            0 :                 ctx->index++;
     314              :             }
     315            0 :             if ((ctx->index = ctx->index % ctx->max_block_size) == 0) {
     316            0 :                 keccak_f1600(ctx);
     317              :             }
     318              :         }
     319              : 
     320              :         // process input in 8-byte chunks
     321            0 :         while (ilen >= 8) {
     322            0 :             ABSORB(ctx, ctx->index, MBEDTLS_GET_UINT64_LE(input, 0));
     323            0 :             input += 8;
     324            0 :             ilen -= 8;
     325            0 :             if ((ctx->index = (ctx->index + 8) % ctx->max_block_size) == 0) {
     326            0 :                 keccak_f1600(ctx);
     327              :             }
     328              :         }
     329              :     }
     330              : 
     331              :     // handle remaining bytes
     332            9 :     while (ilen-- > 0) {
     333            6 :         ABSORB(ctx, ctx->index, *input++);
     334            6 :         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
     335            0 :             keccak_f1600(ctx);
     336              :         }
     337              :     }
     338              : 
     339            3 :     return 0;
     340              : }
     341              : 
     342            3 : int mbedtls_sha3_finish(mbedtls_sha3_context *ctx,
     343              :                         uint8_t *output, size_t olen)
     344              : {
     345            3 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     346              : 
     347              :     /* Catch SHA-3 families, with fixed output length */
     348            3 :     if (ctx->olen > 0) {
     349            3 :         if (ctx->olen > olen) {
     350            0 :             ret = MBEDTLS_ERR_SHA3_BAD_INPUT_DATA;
     351            0 :             goto exit;
     352              :         }
     353            3 :         olen = ctx->olen;
     354              :     }
     355              : 
     356            3 :     ABSORB(ctx, ctx->index, XOR_BYTE);
     357            3 :     ABSORB(ctx, ctx->max_block_size - 1, 0x80);
     358            3 :     keccak_f1600(ctx);
     359            3 :     ctx->index = 0;
     360              : 
     361          147 :     while (olen-- > 0) {
     362          144 :         *output++ = SQUEEZE(ctx, ctx->index);
     363              : 
     364          144 :         if ((ctx->index = (ctx->index + 1) % ctx->max_block_size) == 0) {
     365            0 :             keccak_f1600(ctx);
     366              :         }
     367              :     }
     368              : 
     369            3 :     ret = 0;
     370              : 
     371            3 : exit:
     372            3 :     mbedtls_sha3_free(ctx);
     373            3 :     return ret;
     374              : }
     375              : 
     376              : /*
     377              :  * output = SHA-3( input buffer )
     378              :  */
     379            3 : int mbedtls_sha3(mbedtls_sha3_id id, const uint8_t *input,
     380              :                  size_t ilen, uint8_t *output, size_t olen)
     381              : {
     382            3 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     383              :     mbedtls_sha3_context ctx;
     384              : 
     385            3 :     mbedtls_sha3_init(&ctx);
     386              : 
     387              :     /* Sanity checks are performed in every mbedtls_sha3_xxx() */
     388            3 :     if ((ret = mbedtls_sha3_starts(&ctx, id)) != 0) {
     389            0 :         goto exit;
     390              :     }
     391              : 
     392            3 :     if ((ret = mbedtls_sha3_update(&ctx, input, ilen)) != 0) {
     393            0 :         goto exit;
     394              :     }
     395              : 
     396            3 :     if ((ret = mbedtls_sha3_finish(&ctx, output, olen)) != 0) {
     397            0 :         goto exit;
     398              :     }
     399              : 
     400            3 : exit:
     401            3 :     mbedtls_sha3_free(&ctx);
     402              : 
     403            3 :     return ret;
     404              : }
     405              : 
     406              : /**************** Self-tests ****************/
     407              : 
     408              : #if defined(MBEDTLS_SELF_TEST)
     409              : 
     410              : static const unsigned char test_data[2][4] =
     411              : {
     412              :     "",
     413              :     "abc",
     414              : };
     415              : 
     416              : static const size_t test_data_len[2] =
     417              : {
     418              :     0, /* "" */
     419              :     3  /* "abc" */
     420              : };
     421              : 
     422              : static const unsigned char test_hash_sha3_224[2][28] =
     423              : {
     424              :     { /* "" */
     425              :         0x6B, 0x4E, 0x03, 0x42, 0x36, 0x67, 0xDB, 0xB7,
     426              :         0x3B, 0x6E, 0x15, 0x45, 0x4F, 0x0E, 0xB1, 0xAB,
     427              :         0xD4, 0x59, 0x7F, 0x9A, 0x1B, 0x07, 0x8E, 0x3F,
     428              :         0x5B, 0x5A, 0x6B, 0xC7
     429              :     },
     430              :     { /* "abc" */
     431              :         0xE6, 0x42, 0x82, 0x4C, 0x3F, 0x8C, 0xF2, 0x4A,
     432              :         0xD0, 0x92, 0x34, 0xEE, 0x7D, 0x3C, 0x76, 0x6F,
     433              :         0xC9, 0xA3, 0xA5, 0x16, 0x8D, 0x0C, 0x94, 0xAD,
     434              :         0x73, 0xB4, 0x6F, 0xDF
     435              :     }
     436              : };
     437              : 
     438              : static const unsigned char test_hash_sha3_256[2][32] =
     439              : {
     440              :     { /* "" */
     441              :         0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
     442              :         0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
     443              :         0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
     444              :         0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A
     445              :     },
     446              :     { /* "abc" */
     447              :         0x3A, 0x98, 0x5D, 0xA7, 0x4F, 0xE2, 0x25, 0xB2,
     448              :         0x04, 0x5C, 0x17, 0x2D, 0x6B, 0xD3, 0x90, 0xBD,
     449              :         0x85, 0x5F, 0x08, 0x6E, 0x3E, 0x9D, 0x52, 0x5B,
     450              :         0x46, 0xBF, 0xE2, 0x45, 0x11, 0x43, 0x15, 0x32
     451              :     }
     452              : };
     453              : 
     454              : static const unsigned char test_hash_sha3_384[2][48] =
     455              : {
     456              :     { /* "" */
     457              :         0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
     458              :         0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
     459              :         0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
     460              :         0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
     461              :         0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
     462              :         0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04
     463              :     },
     464              :     { /* "abc" */
     465              :         0xEC, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6F, 0xC9,
     466              :         0x26, 0x45, 0x9F, 0x58, 0xE2, 0xC6, 0xAD, 0x8D,
     467              :         0xF9, 0xB4, 0x73, 0xCB, 0x0F, 0xC0, 0x8C, 0x25,
     468              :         0x96, 0xDA, 0x7C, 0xF0, 0xE4, 0x9B, 0xE4, 0xB2,
     469              :         0x98, 0xD8, 0x8C, 0xEA, 0x92, 0x7A, 0xC7, 0xF5,
     470              :         0x39, 0xF1, 0xED, 0xF2, 0x28, 0x37, 0x6D, 0x25
     471              :     }
     472              : };
     473              : 
     474              : static const unsigned char test_hash_sha3_512[2][64] =
     475              : {
     476              :     { /* "" */
     477              :         0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
     478              :         0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
     479              :         0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
     480              :         0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
     481              :         0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
     482              :         0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
     483              :         0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
     484              :         0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26
     485              :     },
     486              :     { /* "abc" */
     487              :         0xB7, 0x51, 0x85, 0x0B, 0x1A, 0x57, 0x16, 0x8A,
     488              :         0x56, 0x93, 0xCD, 0x92, 0x4B, 0x6B, 0x09, 0x6E,
     489              :         0x08, 0xF6, 0x21, 0x82, 0x74, 0x44, 0xF7, 0x0D,
     490              :         0x88, 0x4F, 0x5D, 0x02, 0x40, 0xD2, 0x71, 0x2E,
     491              :         0x10, 0xE1, 0x16, 0xE9, 0x19, 0x2A, 0xF3, 0xC9,
     492              :         0x1A, 0x7E, 0xC5, 0x76, 0x47, 0xE3, 0x93, 0x40,
     493              :         0x57, 0x34, 0x0B, 0x4C, 0xF4, 0x08, 0xD5, 0xA5,
     494              :         0x65, 0x92, 0xF8, 0x27, 0x4E, 0xEC, 0x53, 0xF0
     495              :     }
     496              : };
     497              : 
     498              : static const unsigned char long_kat_hash_sha3_224[28] =
     499              : {
     500              :     0xD6, 0x93, 0x35, 0xB9, 0x33, 0x25, 0x19, 0x2E,
     501              :     0x51, 0x6A, 0x91, 0x2E, 0x6D, 0x19, 0xA1, 0x5C,
     502              :     0xB5, 0x1C, 0x6E, 0xD5, 0xC1, 0x52, 0x43, 0xE7,
     503              :     0xA7, 0xFD, 0x65, 0x3C
     504              : };
     505              : 
     506              : static const unsigned char long_kat_hash_sha3_256[32] =
     507              : {
     508              :     0x5C, 0x88, 0x75, 0xAE, 0x47, 0x4A, 0x36, 0x34,
     509              :     0xBA, 0x4F, 0xD5, 0x5E, 0xC8, 0x5B, 0xFF, 0xD6,
     510              :     0x61, 0xF3, 0x2A, 0xCA, 0x75, 0xC6, 0xD6, 0x99,
     511              :     0xD0, 0xCD, 0xCB, 0x6C, 0x11, 0x58, 0x91, 0xC1
     512              : };
     513              : 
     514              : static const unsigned char long_kat_hash_sha3_384[48] =
     515              : {
     516              :     0xEE, 0xE9, 0xE2, 0x4D, 0x78, 0xC1, 0x85, 0x53,
     517              :     0x37, 0x98, 0x34, 0x51, 0xDF, 0x97, 0xC8, 0xAD,
     518              :     0x9E, 0xED, 0xF2, 0x56, 0xC6, 0x33, 0x4F, 0x8E,
     519              :     0x94, 0x8D, 0x25, 0x2D, 0x5E, 0x0E, 0x76, 0x84,
     520              :     0x7A, 0xA0, 0x77, 0x4D, 0xDB, 0x90, 0xA8, 0x42,
     521              :     0x19, 0x0D, 0x2C, 0x55, 0x8B, 0x4B, 0x83, 0x40
     522              : };
     523              : 
     524              : static const unsigned char long_kat_hash_sha3_512[64] =
     525              : {
     526              :     0x3C, 0x3A, 0x87, 0x6D, 0xA1, 0x40, 0x34, 0xAB,
     527              :     0x60, 0x62, 0x7C, 0x07, 0x7B, 0xB9, 0x8F, 0x7E,
     528              :     0x12, 0x0A, 0x2A, 0x53, 0x70, 0x21, 0x2D, 0xFF,
     529              :     0xB3, 0x38, 0x5A, 0x18, 0xD4, 0xF3, 0x88, 0x59,
     530              :     0xED, 0x31, 0x1D, 0x0A, 0x9D, 0x51, 0x41, 0xCE,
     531              :     0x9C, 0xC5, 0xC6, 0x6E, 0xE6, 0x89, 0xB2, 0x66,
     532              :     0xA8, 0xAA, 0x18, 0xAC, 0xE8, 0x28, 0x2A, 0x0E,
     533              :     0x0D, 0xB5, 0x96, 0xC9, 0x0B, 0x0A, 0x7B, 0x87
     534              : };
     535              : 
     536            0 : static int mbedtls_sha3_kat_test(int verbose,
     537              :                                  const char *type_name,
     538              :                                  mbedtls_sha3_id id,
     539              :                                  int test_num)
     540              : {
     541              :     uint8_t hash[64];
     542              :     int result;
     543              : 
     544            0 :     result = mbedtls_sha3(id,
     545            0 :                           test_data[test_num], test_data_len[test_num],
     546              :                           hash, sizeof(hash));
     547            0 :     if (result != 0) {
     548            0 :         if (verbose != 0) {
     549            0 :             mbedtls_printf("  %s test %d error code: %d\n",
     550              :                            type_name, test_num, result);
     551              :         }
     552              : 
     553            0 :         return result;
     554              :     }
     555              : 
     556            0 :     switch (id) {
     557            0 :         case MBEDTLS_SHA3_224:
     558            0 :             result = memcmp(hash, test_hash_sha3_224[test_num], 28);
     559            0 :             break;
     560            0 :         case MBEDTLS_SHA3_256:
     561            0 :             result = memcmp(hash, test_hash_sha3_256[test_num], 32);
     562            0 :             break;
     563            0 :         case MBEDTLS_SHA3_384:
     564            0 :             result = memcmp(hash, test_hash_sha3_384[test_num], 48);
     565            0 :             break;
     566            0 :         case MBEDTLS_SHA3_512:
     567            0 :             result = memcmp(hash, test_hash_sha3_512[test_num], 64);
     568            0 :             break;
     569            0 :         default:
     570            0 :             break;
     571              :     }
     572              : 
     573            0 :     if (0 != result) {
     574            0 :         if (verbose != 0) {
     575            0 :             mbedtls_printf("  %s test %d failed\n", type_name, test_num);
     576              :         }
     577              : 
     578            0 :         return -1;
     579              :     }
     580              : 
     581            0 :     if (verbose != 0) {
     582            0 :         mbedtls_printf("  %s test %d passed\n", type_name, test_num);
     583              :     }
     584              : 
     585            0 :     return 0;
     586              : }
     587              : 
     588            0 : static int mbedtls_sha3_long_kat_test(int verbose,
     589              :                                       const char *type_name,
     590              :                                       mbedtls_sha3_id id)
     591              : {
     592              :     mbedtls_sha3_context ctx;
     593              :     unsigned char buffer[1000];
     594              :     unsigned char hash[64];
     595            0 :     int result = 0;
     596              : 
     597            0 :     memset(buffer, 'a', 1000);
     598              : 
     599            0 :     if (verbose != 0) {
     600            0 :         mbedtls_printf("  %s long KAT test ", type_name);
     601              :     }
     602              : 
     603            0 :     mbedtls_sha3_init(&ctx);
     604              : 
     605            0 :     result = mbedtls_sha3_starts(&ctx, id);
     606            0 :     if (result != 0) {
     607            0 :         if (verbose != 0) {
     608            0 :             mbedtls_printf("setup failed\n ");
     609              :         }
     610              :     }
     611              : 
     612              :     /* Process 1,000,000 (one million) 'a' characters */
     613            0 :     for (int i = 0; i < 1000; i++) {
     614            0 :         result = mbedtls_sha3_update(&ctx, buffer, 1000);
     615            0 :         if (result != 0) {
     616            0 :             if (verbose != 0) {
     617            0 :                 mbedtls_printf("update error code: %i\n", result);
     618              :             }
     619              : 
     620            0 :             goto cleanup;
     621              :         }
     622              :     }
     623              : 
     624            0 :     result = mbedtls_sha3_finish(&ctx, hash, sizeof(hash));
     625            0 :     if (result != 0) {
     626            0 :         if (verbose != 0) {
     627            0 :             mbedtls_printf("finish error code: %d\n", result);
     628              :         }
     629              : 
     630            0 :         goto cleanup;
     631              :     }
     632              : 
     633            0 :     switch (id) {
     634            0 :         case MBEDTLS_SHA3_224:
     635            0 :             result = memcmp(hash, long_kat_hash_sha3_224, 28);
     636            0 :             break;
     637            0 :         case MBEDTLS_SHA3_256:
     638            0 :             result = memcmp(hash, long_kat_hash_sha3_256, 32);
     639            0 :             break;
     640            0 :         case MBEDTLS_SHA3_384:
     641            0 :             result = memcmp(hash, long_kat_hash_sha3_384, 48);
     642            0 :             break;
     643            0 :         case MBEDTLS_SHA3_512:
     644            0 :             result = memcmp(hash, long_kat_hash_sha3_512, 64);
     645            0 :             break;
     646            0 :         default:
     647            0 :             break;
     648              :     }
     649              : 
     650            0 :     if (result != 0) {
     651            0 :         if (verbose != 0) {
     652            0 :             mbedtls_printf("failed\n");
     653              :         }
     654              :     }
     655              : 
     656            0 :     if (verbose != 0) {
     657            0 :         mbedtls_printf("passed\n");
     658              :     }
     659              : 
     660            0 : cleanup:
     661            0 :     mbedtls_sha3_free(&ctx);
     662            0 :     return result;
     663              : }
     664              : 
     665            0 : int mbedtls_sha3_self_test(int verbose)
     666              : {
     667              :     int i;
     668              : 
     669              :     /* SHA-3 Known Answer Tests (KAT) */
     670            0 :     for (i = 0; i < 2; i++) {
     671            0 :         if (0 != mbedtls_sha3_kat_test(verbose,
     672              :                                        "SHA3-224", MBEDTLS_SHA3_224, i)) {
     673            0 :             return 1;
     674              :         }
     675              : 
     676            0 :         if (0 != mbedtls_sha3_kat_test(verbose,
     677              :                                        "SHA3-256", MBEDTLS_SHA3_256, i)) {
     678            0 :             return 1;
     679              :         }
     680              : 
     681            0 :         if (0 != mbedtls_sha3_kat_test(verbose,
     682              :                                        "SHA3-384", MBEDTLS_SHA3_384, i)) {
     683            0 :             return 1;
     684              :         }
     685              : 
     686            0 :         if (0 != mbedtls_sha3_kat_test(verbose,
     687              :                                        "SHA3-512", MBEDTLS_SHA3_512, i)) {
     688            0 :             return 1;
     689              :         }
     690              :     }
     691              : 
     692              :     /* SHA-3 long KAT tests */
     693            0 :     if (0 != mbedtls_sha3_long_kat_test(verbose,
     694              :                                         "SHA3-224", MBEDTLS_SHA3_224)) {
     695            0 :         return 1;
     696              :     }
     697              : 
     698            0 :     if (0 != mbedtls_sha3_long_kat_test(verbose,
     699              :                                         "SHA3-256", MBEDTLS_SHA3_256)) {
     700            0 :         return 1;
     701              :     }
     702              : 
     703            0 :     if (0 != mbedtls_sha3_long_kat_test(verbose,
     704              :                                         "SHA3-384", MBEDTLS_SHA3_384)) {
     705            0 :         return 1;
     706              :     }
     707              : 
     708            0 :     if (0 != mbedtls_sha3_long_kat_test(verbose,
     709              :                                         "SHA3-512", MBEDTLS_SHA3_512)) {
     710            0 :         return 1;
     711              :     }
     712              : 
     713            0 :     if (verbose != 0) {
     714            0 :         mbedtls_printf("\n");
     715              :     }
     716              : 
     717            0 :     return 0;
     718              : }
     719              : #endif /* MBEDTLS_SELF_TEST */
     720              : 
     721              : #endif /* MBEDTLS_SHA3_C */
        

Generated by: LCOV version 2.0-1