diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8cd461414..eed63fdd1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,11 @@ Thank you for your pull request. -If this fixes an existing github issue, make sure to have a line saying 'Fixes #XXXX' (without quotes) in the commit message. +If this fixes an existing github issue, make sure to have a line saying 'Fixes: ' (without quotes) in the commit message. +Please use the long format to refer to an issue 'libtom/libtomcrypt#'. + +If this fixes something (even if there exists no github issue), make sure to have a line saying 'Fixes: ("Description")' +This can be created via e.g. `git --no-pager log -1 --pretty=fixes --> @@ -11,3 +15,4 @@ If this fixes an existing github issue, make sure to have a line saying 'Fixes # * [ ] documentation is added or updated * [ ] tests are added or updated +* [ ] if this fixes something: added a `Fixes:` tag to the commit message diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14be6ec0a..de52333ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,10 +47,12 @@ jobs: - { BUILDNAME: 'STOCK', BUILDOPTIONS: '', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'STOCK-MPI', BUILDOPTIONS: '-ULTM_DESC -UTFM_DESC -UUSE_LTM -UUSE_TFM', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'EASY', BUILDOPTIONS: '-DLTC_EASY', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL_CODE', BUILDOPTIONS: '-DLTC_SMALL_CODE', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL_STACK', BUILDOPTIONS: '-DLTC_SMALL_STACK', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'SMALL', BUILDOPTIONS: '-DLTC_SMALL_CODE -DLTC_SMALL_STACK', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_TABLES', BUILDOPTIONS: '-DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_FAST', BUILDOPTIONS: '-DLTC_NO_FAST', BUILDSCRIPT: '.ci/run.sh' } - - { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } + - { BUILDNAME: 'NO_FAST+SMALL+NO_TABLES', BUILDOPTIONS: '-DLTC_NO_FAST -DLTC_SMALL_CODE -DLTC_SMALL_STACK -DLTC_NO_TABLES', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_ASM', BUILDOPTIONS: '-DLTC_NO_ASM', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_DEPRECATED_APIS', BUILDOPTIONS: '-DLTC_NO_DEPRECATED_APIS', BUILDSCRIPT: '.ci/run.sh' } - { BUILDNAME: 'NO_TIMING_RESISTANCE', BUILDOPTIONS: '-DLTC_NO_ECC_TIMING_RESISTANT -DLTC_NO_RSA_BLINDING', BUILDSCRIPT: '.ci/run.sh' } @@ -63,11 +65,10 @@ jobs: steps: - uses: actions/checkout@v4 - name: install dependencies - uses: nick-fields/retry@v3 + uses: nick-fields/retry@v4.0.0 with: timeout_minutes: 20 max_attempts: 3 - retry_on: error command: | sudo apt-get update -qq sudo apt-get install -y libgmp-dev valgrind libtool-bin clang-tools lcov ruby clang @@ -117,11 +118,10 @@ jobs: steps: - uses: actions/checkout@v4 - name: install dependencies - uses: nick-fields/retry@v3 + uses: nick-fields/retry@v4.0.0 with: - timeout_minutes: 5 + timeout_minutes: 20 max_attempts: 3 - retry_on: error command: | sudo apt-get update -qq sudo apt-get remove -y libtommath1 @@ -133,3 +133,47 @@ jobs: run: | make pre_gen make CFLAGS="-DLTM_DESC -DUSE_LTM" EXTRALIBS="-ltommath" AMALGAM=1 -j$(nproc) check + + CMake: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-22.04, ubuntu-24.04, ubuntu-22.04-arm, ubuntu-24.04-arm ] + build_type: [ '', -DCMAKE_BUILD_TYPE=Debug, -DCMAKE_BUILD_TYPE=Release, -DCMAKE_BUILD_TYPE=RelWithDebInfo, -DCMAKE_BUILD_TYPE=MinSizeRel ] + cc: [ clang, gcc ] + cflags: [ '', '-DLTC_CFLAGS="-DLTC_NO_ASM"'] + config: + # Static library build + - { CMAKEOPTIONS: '-DBUILD_SHARED_LIBS=Off' } + # Shared library build + - { CMAKEOPTIONS: '-DBUILD_SHARED_LIBS=On' } + steps: + - uses: actions/checkout@v4 + - name: install dependencies + uses: nick-fields/retry@v4.0.0 + with: + timeout_minutes: 20 + max_attempts: 3 + command: | + sudo apt-get update -qq + sudo apt-get remove -y libtommath1 + curl -s https://packagecloud.io/install/repositories/libtom/packages/script.deb.sh | sudo bash + sudo apt-get install libtommath-git-dev + sudo apt-get install -y cmake gcc clang llvm + - name: build + run: | + mkdir build + cd build + CC=${{ matrix.cc }} cmake ${{ matrix.config.CMAKEOPTIONS }} ${{ matrix.build_type }} ${{ matrix.cflags }} .. + make -j$(nproc) + - name: test + run: | + cd build + CC=${{ matrix.cc }} cmake ${{ matrix.config.CMAKEOPTIONS }} ${{ matrix.build_type }} ${{ matrix.cflags }} -DBUILD_TESTING=On .. + make -j$(nproc) + ctest + - name: error logs + if: ${{ failure() }} + run: | + cat build/Testing/Temporary/LastTest.log || true + cat demo/build/Testing/Temporary/LastTest.log || true diff --git a/.gitignore b/.gitignore index 226ed4e6a..09324220b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,121 +1,121 @@ -# suppress compiler/linker output -*.[oa] -*.obj -*.dylib* -*.dll* -*.so* -[Dd]ebug/ -[Rr]elease/ -/MSVC_* -.bin/ - -# release files -/libtomcrypt-* -/crypt-* -pre_gen/ - -# suppress output of build process -gcc_[12].txt -testok.txt -test_*.txt -tv.txt -*_tv.txt -doxygen/ -doc/crypt.pdf -doc/refman.pdf - -# *nix/windows test executables -ltc-* -aesgcm -aesgcm.exe -constants -constants.exe -crypt -crypt.exe -der_print_flexi -der_print_flexi.exe -hashsum -hashsum.exe -multi -multi.exe -openssl-enc -openssl-enc.exe -openssh-privkey -openssh-privkey.exe -latex-tables -latex-tables.exe -sizes -sizes.exe -small -small.exe -test -test.exe -tv_gen -tv_gen.exe -timing -timing.exe - -# Visual Studio special files -# ignore user specific settings -*.user -*.suo -# ignore non-compressed browse file (holds information for ClassView, IntelliSense and WizardBar) -*.ncb -# ignore VS intermediate and program database files -*.idb -*.pdb - -# Eclipse special files -.project -.cproject -.settings/ - -# KDevelop special files -*.kdev4 - - -# macOS special files -.DS_Store - -# other special files -showlibs # symlink to .libs - -# oops ;) but we don't want them to appear in the repository... -*.stackdump -*.core - -# misc -*.rej -*.patch -*.diff -*.orig -*.out -*.ll -*.gcda -*.gcno -*.gcov -libtomcrypt.pc - -# output from doc generation -doxygen/ -*.dvi -*.log -*.aux -*.toc -*.idx -*.ilg -*.ind -*.out -*.lof -*.bak - -coverage*/ -coverage*.info - -# coverity intermediate directory etc. -cov-int/ -.coverity_* -libtomcrypt.lzma - -# cmake build directories -build*/ +# suppress compiler/linker output +*.[oa] +*.obj +*.dylib* +*.dll* +*.so* +[Dd]ebug/ +[Rr]elease/ +/MSVC_* +.bin/ + +# release files +/libtomcrypt-* +/crypt-* +pre_gen/ + +# suppress output of build process +gcc_[12].txt +testok.txt +test_*.txt +tv.txt +*_tv.txt +doxygen/ +doc/crypt.pdf +doc/refman.pdf + +# *nix/windows test executables +ltc-* +aesgcm +aesgcm.exe +constants +constants.exe +crypt +crypt.exe +der_print_flexi +der_print_flexi.exe +hashsum +hashsum.exe +multi +multi.exe +openssl-enc +openssl-enc.exe +openssh-privkey +openssh-privkey.exe +latex-tables +latex-tables.exe +sizes +sizes.exe +small +small.exe +test +test.exe +tv_gen +tv_gen.exe +timing +timing.exe + +# Visual Studio special files +# ignore user specific settings +*.user +*.suo +# ignore non-compressed browse file (holds information for ClassView, IntelliSense and WizardBar) +*.ncb +# ignore VS intermediate and program database files +*.idb +*.pdb + +# Eclipse special files +.project +.cproject +.settings/ + +# KDevelop special files +*.kdev4 + + +# macOS special files +.DS_Store + +# other special files +showlibs # symlink to .libs + +# oops ;) but we don't want them to appear in the repository... +*.stackdump +*.core + +# misc +*.rej +*.patch +*.diff +*.orig +*.out +*.ll +*.gcda +*.gcno +*.gcov +libtomcrypt.pc + +# output from doc generation +doxygen/ +*.dvi +*.log +*.aux +*.toc +*.idx +*.ilg +*.ind +*.out +*.lof +*.bak + +coverage*/ +coverage*.info + +# coverity intermediate directory etc. +cov-int/ +.coverity_* +libtomcrypt.lzma + +# cmake build directories +build*/ diff --git a/appveyor.yml b/appveyor.yml index 29cbf812b..655f2be2e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,10 +31,12 @@ build_script: cp test.exe test-stock.exe cp timing.exe timing-stock.exe nmake -f makefile.msvc clean - nmake -f makefile.msvc all CFLAGS="/Ox /DUSE_LTM /DLTM_DESC /DLTC_NO_AES_NI /I../libtommath" + nmake -f makefile.msvc all CFLAGS="/Ox /DUSE_LTM /DLTM_DESC /DLTC_NO_ACCEL /I../libtommath" test_script: - cmd: >- test-stock.exe test.exe - timing-stock.exe cipher_ecb - timing.exe cipher_ecb + timing-stock.exe cipher_ecb aes + timing.exe cipher_ecb aes + timing-stock.exe hash sha + timing.exe hash sha diff --git a/demos/openssl-enc.c b/demos/openssl-enc.c index 8fc1b14fb..b2f228030 100644 --- a/demos/openssl-enc.c +++ b/demos/openssl-enc.c @@ -152,12 +152,12 @@ static size_t s_pkcs7_pad(union paddable *buf, size_t nb, int block_length, if(is_padding) { length = sizeof(buf->pad); - if (padding_pad(buf->pad, nb, &length, block_length) != CRYPT_OK) + if (padding_pad(buf->pad, nb, &length, LTC_PAD_PKCS7 | block_length) != CRYPT_OK) return 0; return length; } else { length = nb; - if (padding_depad(buf->pad, &length, 0) != CRYPT_OK) + if (padding_depad(buf->pad, &length, LTC_PAD_PKCS7) != CRYPT_OK) return 0; return length; } diff --git a/demos/timing.c b/demos/timing.c index 572756dda..58ae680bc 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -14,6 +14,15 @@ static prng_state yarrow_prng; #define KTIMES 25 #define TIMES 100000 +static const char *filter_arg; + +static LTC_INLINE int should_skip(const char *name) +{ + if (name && filter_arg && strstr(name, filter_arg) == NULL) + return 1; + return 0; +} + static struct list { int id; ulong64 spd1, spd2, avg; @@ -56,7 +65,7 @@ static void tally_results(int type) } /* RDTSC from Scott Duplichan */ -static ulong64 rdtsc (void) +static LTC_INLINE ulong64 rdtsc (void) { #if defined __GNUC__ && !defined(LTC_NO_ASM) #if defined(__i386__) || defined(__x86_64__) @@ -111,12 +120,12 @@ static ulong64 rdtsc (void) static ulong64 timer, skew = 0; -static void t_start(void) +static LTC_INLINE void t_start(void) { timer = rdtsc(); } -static ulong64 t_read(void) +static LTC_INLINE ulong64 t_read(void) { return rdtsc() - timer; } @@ -185,6 +194,9 @@ static void time_cipher_ecb(void) fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { + if (should_skip(cipher_descriptor[x].name)) + continue; + ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb); /* sanity check on cipher */ @@ -258,6 +270,9 @@ static void time_cipher_cbc(void) fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { + if (should_skip(cipher_descriptor[x].name)) + continue; + cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc); /* sanity check on cipher */ @@ -331,6 +346,9 @@ static void time_cipher_ctr(void) fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { + if (should_skip(cipher_descriptor[x].name)) + continue; + ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr); /* sanity check on cipher */ @@ -405,6 +423,9 @@ static void time_cipher_lrw(void) no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { if (cipher_descriptor[x].block_length != 16) continue; + if (should_skip(cipher_descriptor[x].name)) + continue; + lrw_start(x, pt, key, cipher_descriptor[x].min_key_length, key, 0, &lrw); /* sanity check on cipher */ @@ -470,20 +491,26 @@ static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); } static void time_hash(void) { - unsigned long x, y1, len; + unsigned long x, y1, len = 1024; ulong64 t1, t2, c1, c2; hash_state md; int (*func)(hash_state *, const unsigned char *, unsigned long), err; - unsigned char pt[MAXBLOCKSIZE] = { 0 }; - + unsigned char *pt = XMALLOC(len); + if (pt == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } fprintf(stderr, "\n\nHASH Time Trials for:\n"); no_results = 0; for (x = 0; hash_descriptor[x].name != NULL; x++) { + if (should_skip(hash_descriptor[x].name)) + continue; /* sanity check on hash */ if ((err = hash_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err)); + XFREE(pt); exit(EXIT_FAILURE); } @@ -493,7 +520,6 @@ static void time_hash(void) #define DO2 DO1 DO1 func = hash_descriptor[x].process; - len = hash_descriptor[x].blocksize; c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < TIMES; y1++) { @@ -515,6 +541,7 @@ static void time_hash(void) #undef DO1 } tally_results(2); + XFREE(pt); } /*#warning you need an mp_rand!!!*/ @@ -592,8 +619,10 @@ static void time_prng(void) unsigned long x, y; int err; - fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n"); + fprintf(stderr, "Timing PRNGs - cycles/byte output, cycles add_entropy (32 bytes) :\n"); for (x = 0; prng_descriptor[x].name != NULL; x++) { + if (should_skip(prng_descriptor[x].name)) + continue; /* sanity check on prng */ if ((err = prng_descriptor[x].test()) != CRYPT_OK) { @@ -616,7 +645,7 @@ static void time_prng(void) t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "%20s: %5"PRI64"u ", prng_descriptor[x].name, t2>>12); + fprintf(stderr, "%20s: %5"PRI64"u, ", prng_descriptor[x].name, t2>>12); #undef DO2 #undef DO1 @@ -702,11 +731,21 @@ static void time_rsa(void) unsigned char buf[2][2048] = { 0 }; unsigned long x, y, z, zzz; int err, zz, stat; + ltc_rsa_op_parameters rsa_params = { + .u.crypt.lparam = (const unsigned char *)"testprog", + .u.crypt.lparamlen = 8, + .prng = &yarrow_prng, + .wprng = find_prng("yarrow"), + .params.hash_idx = find_hash("sha1"), + .params.mgf1_hash_idx = find_hash("sha1"), + .params.saltlen = 8, + }; if (ltc_mp.name == NULL) return; for (x = 2048; x <= 8192; x <<= 1) { t2 = 0; + rsa_params.padding = LTC_PKCS_1_OAEP; for (y = 0; y < 4; y++) { t_start(); t1 = t_read(); @@ -734,9 +773,7 @@ static void time_rsa(void) t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng, - find_prng("yarrow"), find_hash("sha1"), - &key)) != CRYPT_OK) { + if ((err = rsa_encrypt_key_v2(buf[0], 32, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -755,8 +792,7 @@ static void time_rsa(void) t_start(); t1 = t_read(); zzz = sizeof(buf[0]); - if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"), - &zz, &key)) != CRYPT_OK) { + if ((err = rsa_decrypt_key_v2(buf[1], z, buf[0], &zzz, &rsa_params, &zz, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -771,12 +807,12 @@ static void time_rsa(void) fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2); t2 = 0; + rsa_params.padding = LTC_PKCS_1_PSS; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); - if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, - find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) { + if ((err = rsa_sign_hash_v2(buf[0], 20, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -794,7 +830,7 @@ static void time_rsa(void) for (y = 0; y < 2048; y++) { t_start(); t1 = t_read(); - if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) { + if ((err = rsa_verify_hash_v2(buf[1], z, buf[0], 20, &rsa_params, &stat, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } @@ -1018,130 +1054,206 @@ static void time_ecc(void) static void time_ecc(void) { fprintf(stderr, "NO ECC\n"); } #endif -static void time_macs_(unsigned long MAC_SIZE) +typedef struct mac_ctx { + unsigned char *buf, key[32], tag[16]; + unsigned long size; + int cipher_idx, hash_idx; +} mac_ctx; + +#ifdef LTC_OMAC +static void time_omac(mac_ctx *ctx) { -#if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC) - unsigned char *buf, key[16], tag[16]; ulong64 t1, t2; unsigned long x, z; - int err, cipher_idx, hash_idx; - - fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); - - buf = XMALLOC(MAC_SIZE*1024); - if (buf == NULL) { - fprintf(stderr, "\n\nout of heap yo\n\n"); - exit(EXIT_FAILURE); - } + int err; - cipher_idx = find_cipher("aes"); - hash_idx = find_hash("sha1"); - - if (cipher_idx == -1 || hash_idx == -1) { - fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n"); - exit(EXIT_FAILURE); - } - - yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); - yarrow_read(key, 16, &yarrow_prng); - -#ifdef LTC_OMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = omac_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_XCBC +static void time_xcbc(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = xcbc_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_F9_MODE +static void time_f9(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = f9_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_PMAC +static void time_pmac(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err)); + if ((err = pmac_memory(ctx->cipher_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[ctx->cipher_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[ctx->cipher_idx].name, t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_PELICAN +static void time_pelican(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); - z = 16; - if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) { + if ((err = pelican_memory(ctx->key, 16, ctx->buf, ctx->size, ctx->tag)) != CRYPT_OK) { fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif #ifdef LTC_HMAC +static void time_hmac(mac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[hash_idx].name, error_to_string(err)); + if ((err = hmac_memory(ctx->hash_idx, ctx->key, 16, ctx->buf, ctx->size, ctx->tag, &z)) != CRYPT_OK) { + fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[ctx->hash_idx].name, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[ctx->hash_idx].name, t2/(ulong64)(ctx->size)); +} #endif - XFREE(buf); +static void time_macs_(unsigned long MAC_SIZE) +{ +#if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC) + mac_ctx ctx; + struct { + const char *name; + void (*time_fun)(mac_ctx*); + } time_funs[] = { +#define TIME_FUN(n) { #n, time_ ## n } +#ifdef LTC_OMAC + TIME_FUN(omac), +#endif +#ifdef LTC_XCBC + TIME_FUN(xcbc), +#endif +#ifdef LTC_F9_MODE + TIME_FUN(f9), +#endif +#ifdef LTC_PMAC + TIME_FUN(pmac), +#endif +#ifdef LTC_PELICAN + TIME_FUN(pelican), +#endif +#ifdef LTC_HMAC + TIME_FUN(hmac), +#endif +#undef TIME_FUN + }; + unsigned long n; + + fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); + + ctx.size = MAC_SIZE*1024; + ctx.buf = XMALLOC(ctx.size); + if (ctx.buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + ctx.cipher_idx = find_cipher("aes"); + ctx.hash_idx = find_hash("sha1"); + + if (ctx.cipher_idx == -1 || ctx.hash_idx == -1) { + fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n"); + exit(EXIT_FAILURE); + } + + yarrow_read(ctx.buf, ctx.size, &yarrow_prng); + yarrow_read(ctx.key, 16, &yarrow_prng); + + for (n = 0; n < LTC_ARRAY_SIZE(time_funs); ++n) { + if (!should_skip(time_funs[n].name)) + time_funs[n].time_fun(&ctx); + } + + XFREE(ctx.buf); #else LTC_UNUSED_PARAM(MAC_SIZE); fprintf(stderr, "NO MACs\n"); @@ -1155,137 +1267,124 @@ static void time_macs(void) time_macs_(32); } -static void time_encmacs_(unsigned long MAC_SIZE) -{ -#if defined(LTC_EAX_MODE) || defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || \ - defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) || defined(LTC_SIV_MODE) -#if defined(LTC_SIV_MODE) - unsigned char *aad[4]; - unsigned long buflen; -#endif +typedef struct eac_ctx { unsigned char *buf, IV[16], key[32], tag[16]; + unsigned long size; + int cipher_idx; +} eac_ctx; + +#ifdef LTC_EAX_MODE +static void time_eax(eac_ctx *ctx) +{ ulong64 t1, t2; unsigned long x, z; - int err, cipher_idx; - symmetric_ECB skey; - - fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); - - buf = XMALLOC(MAC_SIZE*1024); - if (buf == NULL) { - fprintf(stderr, "\n\nout of heap yo\n\n"); - exit(EXIT_FAILURE); - } + int err; - cipher_idx = find_cipher("aes"); - - yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); - yarrow_read(key, sizeof(key), &yarrow_prng); - yarrow_read(IV, sizeof(IV), &yarrow_prng); - -#ifdef LTC_EAX_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + if ((err = eax_encrypt_authenticate_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nEAX error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_OCB_MODE - t2 = -1; - for (x = 0; x < 10000; x++) { - t_start(); - t1 = t_read(); - z = 16; - if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { - fprintf(stderr, "\nOCB error... %s\n", error_to_string(err)); - exit(EXIT_FAILURE); - } - t1 = t_read() - t1; - if (t1 < t2) t2 = t1; - } - fprintf(stderr, "OCB \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); -#endif +#if defined(LTC_OCB3_MODE) +static void time_ocb3(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; -#ifdef LTC_OCB3_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 15, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { + if ((err = ocb3_encrypt_authenticate_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 15, (unsigned char*)"", 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_CCM_MODE +#if defined(LTC_CCM_MODE) +static void time_ccm(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + symmetric_ECB skey; + t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, NULL, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); - ecb_start(cipher_idx, key, 16, 0, &skey); + ecb_start(ctx->cipher_idx, ctx->key, 16, 0, &skey); t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { + if ((err = ccm_memory(ctx->cipher_idx, ctx->key, 16, &skey, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); ecb_done(&skey); +} #endif -#ifdef LTC_GCM_MODE +#if defined (LTC_GCM_MODE) +static void time_gcm(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + gcm_state gcm +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; t2 = -1; for (x = 0; x < 100; x++) { t_start(); t1 = t_read(); z = 16; - if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { + if ((err = gcm_memory(ctx->cipher_idx, ctx->key, 16, ctx->IV, 16, NULL, 0, ctx->buf, ctx->size, ctx->buf, ctx->tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); - - { - gcm_state gcm -#ifdef LTC_GCM_TABLES_SSE2 -__attribute__ ((aligned (16))) -#endif -; + fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); - if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } + if ((err = gcm_init(&gcm, ctx->cipher_idx, ctx->key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -1295,7 +1394,7 @@ __attribute__ ((aligned (16))) fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) { + if ((err = gcm_add_iv(&gcm, ctx->IV, 16)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } @@ -1303,36 +1402,45 @@ __attribute__ ((aligned (16))) fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) { + if ((err = gcm_process(&gcm, ctx->buf, ctx->size, ctx->buf, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } - if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) { + if ((err = gcm_done(&gcm, ctx->tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024)); - } + fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(ctx->size)); +} #endif -#ifdef LTC_SIV_MODE +#if defined(LTC_SIV_MODE) +static void time_siv(eac_ctx *ctx) +{ + ulong64 t1, t2; + unsigned long x, z; + int err; + unsigned char *aad[4]; + unsigned long buflen; + for(z = 0; z < 4; z++) { - aad[z] = IV + z * 4; + aad[z] = ctx->IV + z * 4; } for(z = 0; z < 4; z++) { t2 = -1; for (x = 0; x < 10000; x++) { - buflen = MAC_SIZE*1024; + buflen = ctx->size; t_start(); t1 = t_read(); - if ((err = siv_memory(cipher_idx, LTC_ENCRYPT, - key, 32, - buf, MAC_SIZE*1024 - 16, - buf, &buflen, + if ((err = siv_memory(ctx->cipher_idx, LTC_ENCRYPT, + ctx->key, 32, + ctx->buf, ctx->size - 16, + ctx->buf, &buflen, + 4 - z, aad[0], 16, aad[1], 12, aad[2], 8, @@ -1345,11 +1453,61 @@ __attribute__ ((aligned (16))) if (t1 < t2) t2 = t1; } aad[3-z] = NULL; - fprintf(stderr, "SIV (%lu x AAD)\t\t%9"PRI64"u\n", 4-z, t2/(ulong64)(MAC_SIZE*1024)); + fprintf(stderr, "SIV (%lu x AAD)\t\t%9"PRI64"u\n", 4-z, t2/(ulong64)(ctx->size)); } +} #endif - XFREE(buf); +static void time_eacs_(unsigned long MAC_SIZE) +{ +#if defined(LTC_EAX_MODE) || defined(LTC_OCB3_MODE) || \ + defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) || defined(LTC_SIV_MODE) + eac_ctx ctx; + struct { + const char *name; + void (*time_fun)(eac_ctx*); + } time_funs[] = { +#define TIME_FUN(n) { #n, time_ ## n } +#ifdef LTC_EAX_MODE + TIME_FUN(eax), +#endif +#ifdef LTC_OCB3_MODE + TIME_FUN(ocb3), +#endif +#ifdef LTC_CCM_MODE + TIME_FUN(ccm), +#endif +#ifdef LTC_GCM_MODE + TIME_FUN(gcm), +#endif +#ifdef LTC_SIV_MODE + TIME_FUN(siv), +#endif +#undef TIME_FUN + }; + unsigned long n; + + fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); + + ctx.size = MAC_SIZE*1024; + ctx.buf = XMALLOC(ctx.size); + if (ctx.buf == NULL) { + fprintf(stderr, "\n\nout of heap yo\n\n"); + exit(EXIT_FAILURE); + } + + ctx.cipher_idx = find_cipher("aes"); + + yarrow_read(ctx.buf, ctx.size, &yarrow_prng); + yarrow_read(ctx.key, sizeof(ctx.key), &yarrow_prng); + yarrow_read(ctx.IV, sizeof(ctx.IV), &yarrow_prng); + + for (n = 0; n < LTC_ARRAY_SIZE(time_funs); ++n) { + if (!should_skip(time_funs[n].name)) + time_funs[n].time_fun(&ctx); + } + + XFREE(ctx.buf); #else LTC_UNUSED_PARAM(MAC_SIZE); fprintf(stderr, "NO ENCMACs\n"); @@ -1357,23 +1515,26 @@ __attribute__ ((aligned (16))) } -static void time_encmacs(void) +static void time_eacs(void) { - time_encmacs_(1); - time_encmacs_(4); - time_encmacs_(32); + time_eacs_(1); + time_eacs_(4); + time_eacs_(32); } static void LTC_NORETURN die(int status) { FILE* o = status == EXIT_SUCCESS ? stdout : stderr; fprintf(o, - "Usage: timing [<-h|-l|alg>] [mpi]\n\n" + "Usage: timing [<-h|-l|alg>] [mpi] [filter]\n\n" "Run timing tests of all built-in algorithms, or only the one given in .\n\n" - "\talg\tThe algorithm to test. Use the '-l' option to check for valid values.\n" + "\talg\tThe algorithms to test. Use the '-l' option to check for valid values.\n" "\tmpi\tThe MPI provider to use.\n" + "\tfilter\tFilter within the algorithm class (currently only for 'cipher's, 'hash'es, and 'prng's).\n" "\t-l\tList all built-in algorithms that can be timed.\n" - "\t-h\tThe help you're looking at.\n" + "\t-h\tThe help you're looking at.\n\n" + "Examples:\n" + "\ttiming hash sha\t\tWill run the timing demo for all hashes containing 'sha' in their name\n" ); exit(status); } @@ -1395,7 +1556,7 @@ const struct LTC_TEST_FN(cipher_lrw), LTC_TEST_FN(hash), LTC_TEST_FN(macs), - LTC_TEST_FN(encmacs), + LTC_TEST_FN(eacs), LTC_TEST_FN(prng), LTC_TEST_FN(mult), LTC_TEST_FN(sqr), @@ -1440,6 +1601,9 @@ register_all_prngs(); if (crypt_mp_init(mpi_provider) != CRYPT_OK) { fprintf(stderr, "Init of MPI provider \"%s\" failed\n", mpi_provider ? mpi_provider : "(null)"); + filter_arg = mpi_provider; + } else if (argc > 3){ + filter_arg = argv[3]; } if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) { diff --git a/demos/tv_gen.c b/demos/tv_gen.c index d6ba2c6f6..5eba374a1 100644 --- a/demos/tv_gen.c +++ b/demos/tv_gen.c @@ -363,75 +363,6 @@ static void eax_gen(void) } #endif -#ifdef LTC_OCB_MODE -static void ocb_gen(void) -{ - int err, kl, x, y1, z; - FILE *out; - unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], - plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; - unsigned long len; - - OPEN_FILE("ocb_tv.txt", out); - fprintf(out, "OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n" - "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" - "step repeated sufficiently. The nonce is fixed throughout.\n\n"); - - for (x = 0; cipher_descriptor[x].name != NULL; x++) { - kl = cipher_descriptor[x].block_length; - - /* skip ciphers which do not have 64 or 128 bit block sizes */ - if (kl != 8 && kl != 16) continue; - - if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { - kl = cipher_descriptor[x].max_key_length; - } - fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl); - - /* the key */ - for (z = 0; z < kl; z++) { - key[z] = (z & 255); - } - - /* fixed nonce */ - for (z = 0; z < cipher_descriptor[x].block_length; z++) { - nonce[z] = z; - } - - for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ - for (z = 0; z < y1; z++) { - plaintext[z] = (unsigned char)(z & 255); - } - len = sizeof(tag); - if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { - printf("Error OCB'ing: %s\n", error_to_string(err)); - exit(EXIT_FAILURE); - } - if (len == 0) { - printf("Error OCB'ing: zero length\n"); - exit(EXIT_FAILURE); - } - fprintf(out, "%3d: ", y1); - for (z = 0; z < y1; z++) { - fprintf(out, "%02X", plaintext[z]); - } - fprintf(out, ", "); - for (z = 0; z <(int)len; z++) { - fprintf(out, "%02X", tag[z]); - } - fprintf(out, "\n"); - - /* forward the key */ - for (z = 0; z < kl; z++) { - key[z] = tag[z % len]; - } - } - fprintf(out, "\n"); - } - fclose(out); -} -#endif - #ifdef LTC_OCB3_MODE static void ocb3_gen(void) { @@ -817,9 +748,6 @@ int main(int argc, char **argv) #ifdef LTC_EAX_MODE printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n"); #endif -#ifdef LTC_OCB_MODE - printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n"); -#endif #ifdef LTC_OCB3_MODE printf("Generating OCB3 vectors..."); fflush(stdout); ocb3_gen(); printf("done\n"); #endif diff --git a/doc/crypt.tex b/doc/crypt.tex index a3358dc03..0bcb710da 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -1305,14 +1305,28 @@ \chapter{Stream Ciphers} Note: You shouldn't use the keystream interface as a PRNG, as it doesn't allow to re-seed the internal state. -\mysection{ChaCha} +\mysection{ChaCha and XChaCha20} \textit{ChaCha} is currently the most modern stream cipher included in LibTomCrypt, so use this one unless you have a reason for using some of the older algorithms. +\vspace{1mm} + +\textit{XChaCha20} is a variant of \textit{ChaCha20} designed to accept only a 256-bit key and a +longer 192-bit nonce (24 bytes), which dramatically reduces the risk of nonce collisions when +generating nonces randomly. Initialization is the only difference between \textit{XChaCha20} +and \textit{ChaCha20}. Even the \textit{chacha\_state} is the same. Thereafter, +chacha\_crypt(), chacha\_keystream(), and chacha\_done() are used unaltered. +chacha\_ivctr32() and chacha\_ivctr64() are NOT used with xchacha20\_setup(). +\vspace{1mm} For more information about ChaCha see \url{https://en.wikipedia.org/wiki/ChaCha_(cipher)}. +\vspace{1mm} -Supported key size: 16 or 32 bytes (128 or 256 bits). +For more information about XChaCha20 see +\url{https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha}. +\vspace{1mm} + +Supported key size: 16 or 32 bytes (128 or 256 bits) for ChaCha, 32 bytes only for XChaCha20. You can initialize ChaCha with 96bit \textit{nonce} + 32bit \textit{counter}: \begin{verbatim} @@ -1328,9 +1342,17 @@ \chapter{Stream Ciphers} err = chacha_ivctr64(&st, nonce, 8, initial_64bit_ctr); \end{verbatim} +To initialize \textit{XChaCha20} for the recommended 20 rounds with a 256-bit +key (32 bytes) and a 192-bit nonce (24 bytes), use: +\begin{verbatim} +chacha_state st; +err = xchacha20_setup(&st, key, key_len, nonce, nonce_len, rounds); +\end{verbatim} + The \textit{chacha\_setup} takes the number of rounds as a parameter -- choose 20 if you are not sure. As always never ever use the same key + nonce pair more than once. +Both \textit{ChaCha} and \textit{XChaCha20} use the following functions. For the actual encryption or decryption you have to call: \begin{verbatim} err = chacha_crypt(&st, in_buffer, in_len, out_buffer); @@ -1354,6 +1376,39 @@ \chapter{Stream Ciphers} err = chacha_memory(key, keylen, iv, ivlen, datain, datalen, rounds, dataout); \end{verbatim} +To encrypt plaintext (or decrypt ciphertext) using XChaCha20 for data already in +memory with a single function call, the following function may be used. +\begin{verbatim} +err = xchacha20_memory(key, keylen, rounds, nonce, nonce_len, datain, datalen, dataout); +\end{verbatim} + +For both \textit{ChaCha} and \textit{XChaCha20} rounds must be an even number +and if set to 0 the default number of rounds, 20, will be used. +\vspace{1mm} + +\subsection{HChaCha20} + +\textit{HChaCha20} is the key derivation function underlying \textit{XChaCha20}. It applies the +ChaCha20 block function (without the final addition step) to a 256-bit key and a 128-bit input, +producing a 256-bit derived key. It is also useful as a standalone KDF, for example in NaCl-style +\textit{crypto\_box} constructions. + +\index{xchacha20\_hchacha20()} +\begin{verbatim} +int xchacha20_hchacha20(unsigned char *out, unsigned long outlen, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + int rounds); +\end{verbatim} +This derives a 32-byte subkey from a 32-byte \textit{key} and a 16-byte \textit{in} using +\textit{rounds} ChaCha20 rounds (0 = default 20). The output is stored in \textit{out} +(\textit{outlen} must be 32, \textit{keylen} must be 32, \textit{inlen} must be 16). +\vspace{1mm} + +If you define \textit{LTC\_XCHACHA20} to include \textit{XChaCha20} and \textit{HChaCha20} in a +minimal \textit{libtomcrypt} library build, you must also define \textit{LTC\_CHACHA}. +\vspace{1mm} + \mysection{Salsa20 and XSalsa20} \textit{Salsa20} was Daniel Bernstein's submission to the EU eSTREAM @@ -1811,127 +1866,18 @@ \chapter{Authenticated Encryption} The only difference is eax\_decrypt\_verify\_memory() does not emit a tag. Instead you pass it a tag as input and it compares it against the tag it computed while decrypting the message. If the tags match then it stores a $1$ in \textit{res}, otherwise it stores a $0$. -\mysection{OCB Modes} +\mysection{OCB Mode} \subsection{Preface} -LibTomCrypt provides support for a mode called OCB in version 1 ''OCB''\footnote{See -P. Rogaway, M. Bellare, J. Black, T. Krovetz, \textit{OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption}.} -and version 3 ''OCB3''\footnote{See RFC7253, T. Krovetz, P. Rogaway, \textit{The OCB Authenticated-Encryption Algorithm}.}. +LibTomCrypt provides support for a mode called OCB in version 3 +''OCB3''\footnote{See RFC7253, T. Krovetz, P. Rogaway, \textit{The OCB Authenticated-Encryption Algorithm}.}. OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode but is less flexible. -Please be aware that all versions of OCB are patented and there are several licensing models provided by P. Rogaway, the patent holder +All versions of OCB were patented, but have been put into the public domain in 2013 and since then are free to use -- see \url{http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm}. -\subsection{OCB} -\subsubsection{Initialization and processing} - -Let's review how to initialize an OCB context. - -\index{ocb\_init()} -\begin{verbatim} -int ocb_init( ocb_state *ocb, - int cipher, - const unsigned char *key, - unsigned long keylen, - const unsigned char *nonce); -\end{verbatim} - -This will initialize the \textit{ocb} context using cipher descriptor \textit{cipher}. It will use a \textit{key} of length \textit{keylen} -and the random \textit{nonce}. Note that \textit{nonce} must be a random (public) string the same length as the block ciphers -block size (e.g. 16 bytes for AES). - -This mode has no \textit{Associated Data} like EAX mode does which means you cannot authenticate metadata along with the stream. -To encrypt or decrypt data use the following. - -\index{ocb\_encrypt()} \index{ocb\_decrypt()} -\begin{verbatim} -int ocb_encrypt( ocb_state *ocb, - const unsigned char *pt, - unsigned char *ct); - -int ocb_decrypt( ocb_state *ocb, - const unsigned char *ct, - unsigned char *pt); -\end{verbatim} - -This will encrypt (or decrypt for the latter) a fixed length of data from \textit{pt} to \textit{ct} (vice versa for the latter). -They assume that \textit{pt} and \textit{ct} are the same size as the block cipher's block size. Note that you cannot call -both functions given a single \textit{ocb} state. For bi-directional communication you will have to initialize two \textit{ocb} -states (with different nonces). Also \textit{pt} and \textit{ct} may point to the same location in memory. - -\subsubsection{State Termination} - -When you are finished encrypting the message you call the following function to compute the tag. - -\index{ocb\_done\_encrypt()} -\begin{verbatim} -int ocb_done_encrypt( ocb_state *ocb, - const unsigned char *pt, - unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, - unsigned long *taglen); -\end{verbatim} - -This will terminate an encrypt stream \textit{ocb}. If you have trailing bytes of plaintext that will not complete a block -you can pass them here. This will also encrypt the \textit{ptlen} bytes in \textit{pt} and store them in \textit{ct}. It will also -store up to \textit{taglen} bytes of the tag into \textit{tag}. - -Note that \textit{ptlen} must be less than or equal to the block size of block cipher chosen. Also note that if you have -an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. - -To terminate a decrypt stream and compared the tag you call the following. - -\index{ocb\_done\_decrypt()} -\begin{verbatim} -int ocb_done_decrypt( ocb_state *ocb, - const unsigned char *ct, - unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, - unsigned long taglen, - int *res); -\end{verbatim} -Similarly to the previous function you can pass trailing message bytes into this function. This will compute the -tag of the message (internally) and then compare it against the \textit{taglen} bytes of \textit{tag} provided. By default -\textit{res} is set to zero. If all \textit{taglen} bytes of \textit{tag} can be verified then \textit{res} is set to one (authenticated -message). - -\subsubsection{Packet Functions} -To make life simpler the following two functions are provided for memory bound OCB. - -%\index{ocb\_encrypt\_authenticate\_memory()} -\begin{verbatim} -int ocb_encrypt_authenticate_memory( - int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); -\end{verbatim} - -This will OCB encrypt the message \textit{pt} of length \textit{ptlen}, and store the ciphertext in \textit{ct}. The length \textit{ptlen} -can be any arbitrary length. - -\index{ocb\_decrypt\_verify\_memory()} -\begin{verbatim} -int ocb_decrypt_verify_memory( - int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, - int *res); -\end{verbatim} - -Similarly, this will OCB decrypt, and compare the internally computed tag against the tag provided. \textit{res} is set -appropriately to \textit{1} if the tag matches or to \textit{0} if it doesn't match. - -\subsection{OCB3} -\subsubsection{Initialization and processing} +\subsection{Initialization and processing} \index{ocb3\_init()} \begin{verbatim} @@ -1948,7 +1894,7 @@ \subsubsection{Initialization and processing} Note that you can only use ciphers with a block length of 16. -\subsubsection{Additional Authenticated Data} +\subsection{Additional Authenticated Data} OCB3 has, in contrary to OCB, the possibility to add "Additional Authenticated Data" (AAD) when performing cryptographic operations. @@ -1977,7 +1923,7 @@ \subsubsection{Additional Authenticated Data} both functions given a single \textit{ocb} state. For bi-directional communication you will have to initialize two \textit{ocb} states (with different nonces). Also \textit{pt} and \textit{ct} may point to the same location in memory. -\subsubsection{State Termination} +\subsection{State Termination} \index{ocb3\_encrypt\_last()} \index{ocb3\_decrypt\_last()} \begin{verbatim} @@ -2006,7 +1952,7 @@ \subsubsection{State Termination} The \textit{taglen} parameter defines on input the length of the tag to output and will be set to the actual length written, which is at most 16 octets. -\subsubsection{Packet Functions} +\subsection{Packet Functions} To make life simpler the following two functions are provided for memory bound OCB3. \index{ocb3\_encrypt\_authenticate\_memory()} @@ -2462,6 +2408,9 @@ \subsection{Example Usage} This authenticated encryption is based on the ChaCha20 stream cipher and Poly1305 authenticator. It is defined by \url{https://tools.ietf.org/html/rfc8439}. +When \textit{LTC\_XCHACHA20} is enabled, this mode also supports 24-byte IVs for +\textit{XChaCha20--Poly1305} as defined by +\url{https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha}. IMPORTANT NOTICE: The Chacha20--Poly1305 implementation of LibTomCrypt is compliant to \textbf{RFC8439}, which differs slightly to what OpenSSH defined as \textbf{chacha20-poly1305@openssh.com}. The OpenSSH compatibility mode can be enabled @@ -2489,8 +2438,10 @@ \subsection{Initialization Vector} const unsigned char *iv, unsigned long ivlen); \end{verbatim} -This adds the initialization vector from \textit{iv} of length \textit{ivlen} octects (valid lengths: 8 or 12) to -the ChaCha20--Poly1305 state \textit{st}. +This adds the initialization vector from \textit{iv} of length \textit{ivlen} octects (valid lengths: 8, 12, +or 24 when \textit{LTC\_XCHACHA20} is enabled) to the ChaCha20--Poly1305 state \textit{st}. +When \textit{ivlen} is 24, this operates as \textit{XChaCha20--Poly1305}, internally deriving +a subkey via HChaCha20 before proceeding. \index{chacha20poly1305\_setiv\_rfc7905()} \begin{verbatim} @@ -3027,10 +2978,15 @@ \subsection{Hash Registration} applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In particular this allows a cryptosystem to be designed using very few moving parts. +The \code{CHC} mode implements a Miyaguchi–Preneel Hash Construction +\footnote{\href{https://en.wikipedia.org/wiki/One-way_compression_function\#Miyaguchi–Preneel}{\nolinkurl{https://en.wikipedia.org/wiki/One-way_compression_function\#Miyaguchi-Preneel}}} +(MPHC), but provides an improved, \code{chc\_done()} implementation. + + In order to use the CHC system the developer will have to take a few extra steps. First the \textit{chc\_desc} hash -descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash +descriptor must be registered with \code{register\_hash()}. At this point the CHC hash cannot be used to hash data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished -via the chc\_register() function. +via the \code{chc\_register()} function. \index{chc\_register()} \begin{verbatim} @@ -3038,7 +2994,7 @@ \subsection{Hash Registration} \end{verbatim} A cipher has to be registered with CHC (and also in the cipher descriptor tables with -register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can +\code{register\_cipher()}). The \code{chc\_register()} function will bind a cipher to the CHC system. Only one cipher can be bound to the CHC hash at a time. There are additional requirements for the system to work. \begin{enumerate} @@ -4445,171 +4401,6 @@ \chapter{RSA Public Key Cryptography} padding algorithms for encryption and signatures. The standard includes the \textit{v1.5} and \textit{v2.1} algorithms. To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS respectively. -\mysection{PKCS \#1 Padding} -PKCS \#1 v1.5 padding is so simple that both signature and encryption padding are performed by the same function. Note: the -signature padding does \textbf{not} include the ASN.1 padding required. That is performed by the rsa\_sign\_hash\_ex() function -documented later on in this chapter. - -\subsection{PKCS \#1 v1.5 Encoding} -The following function performs PKCS \#1 v1.5 padding: -\index{pkcs\_1\_v1\_5\_encode()} -\begin{verbatim} -int pkcs_1_v1_5_encode( - const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - prng_state *prng, - int prng_idx, - unsigned char *out, - unsigned long *outlen); -\end{verbatim} - -This will encode the message pointed to by \textit{msg} of length \textit{msglen} octets. The \textit{block\_type} parameter must be set to -\textbf{LTC\_PKCS\_1\_EME} to perform encryption padding. It must be set to \textbf{LTC\_PKCS\_1\_EMSA} to perform signature padding. The \textit{modulus\_bitlen} -parameter indicates the length of the modulus in bits. The padded data is stored in \textit{out} with a length of \textit{outlen} octets. The output will not be -longer than the modulus which helps allocate the correct output buffer size. - -Only encryption padding requires a PRNG. When performing signature padding the \textit{prng\_idx} parameter may be left to zero as it is not checked for validity. - -\subsection{PKCS \#1 v1.5 Decoding} -The following function performs PKCS \#1 v1.5 de--padding: -\index{pkcs\_1\_v1\_5\_decode()} -\begin{verbatim} -int pkcs_1_v1_5_decode( - const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - unsigned char *out, - unsigned long *outlen, - int *is_valid); -\end{verbatim} -\index{LTC\_PKCS\_1\_EME} \index{LTC\_PKCS\_1\_EMSA} -This will remove the PKCS padding data pointed to by \textit{msg} of length \textit{msglen}. The decoded data is stored in \textit{out} of length -\textit{outlen}. If the padding is valid, a 1 is stored in \textit{is\_valid}, otherwise, a 0 is stored. The \textit{block\_type} parameter must be set to either -\textbf{LTC\_PKCS\_1\_EME} or \textbf{LTC\_PKCS\_1\_EMSA} depending on whether encryption or signature padding is being removed. - -\mysection{PKCS \#1 v2.1 Encryption} -PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of -the library is concerned we are only dealing with th OAEP padding of the message. - -\subsection{OAEP Encoding} - -The following function performs PKCS \#1 v2.1 encryption padding: - -\index{pkcs\_1\_oaep\_encode()} -\begin{alltt} -int pkcs_1_oaep_encode( - const unsigned char *msg, - unsigned long msglen, - const unsigned char *lparam, - unsigned long lparamlen, - unsigned long modulus_bitlen, - prng_state *prng, - int prng_idx, - int mgf_hash, - int lparam_hash, - unsigned char *out, - unsigned long *outlen); -\end{alltt} - -This accepts \textit{msg} as input of length \textit{msglen} which will be OAEP padded. The \textit{lparam} variable is an additional system specific -tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then -\textit{lparam} can be set to \textbf{NULL}. - -OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter -\textit{modulus\_bitlen}. \textit{mgf\_hash} is the index into the hash descriptor table of the hash desired for the mask generation function (MGF). -\textit{lparam\_hash} is the index into the hash descriptor table of the hash desired for the \textit{lparam}. This value can also be set to $-1$ -to indicate usage of the same algorithm than for the MGF. PKCS \#1 allows any hash to be -used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum - sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process. -The padded message is stored in \textit{out} along with the length in \textit{outlen}. - -If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for \textit{msg} is -$m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. - -Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to -rsa\_exptmod() to encrypt it. - -\subsection{OAEP Decoding} - -\index{pkcs\_1\_oaep\_decode()} -\begin{alltt} -int pkcs_1_oaep_decode( - const unsigned char *msg, - unsigned long msglen, - const unsigned char *lparam, - unsigned long lparamlen, - unsigned long modulus_bitlen, - int mgf_hash, - int lparam_hash, - unsigned char *out, - unsigned long *outlen, - int *res); -\end{alltt} - -This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the -output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not -match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits -and must match what was used during encoding. Similarly the \textit{mgf\_hash} and \textit{lparam\_hash} indexes into the hash descriptor table must -match what was used during encoding. - -If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a -$1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason -it returns an error code. - -\mysection{PKCS \#1 Digital Signatures} - -\subsection{PSS Encoding} -PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. - -\index{pkcs\_1\_pss\_encode()} -\begin{alltt} -int pkcs_1_pss_encode( - const unsigned char *msghash, - unsigned long msghashlen, - unsigned long saltlen, - prng_state *prng, - int prng_idx, - int hash_idx, - unsigned long modulus_bitlen, - unsigned char *out, - unsigned long *outlen); -\end{alltt} - -This function assumes the message to be PSS encoded has previously been hashed. The input hash \textit{msghash} is of length -\textit{msghashlen}. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. -\textit{hash\_idx} is the index into the hash descriptor table of the hash to use. \textit{prng\_idx} and \textit{prng} are the random -number generator information required for the salt. - -Similar to OAEP encoding \textit{modulus\_bitlen} is the size of the RSA modulus (in bits). It limits the size of the salt. If $m$ is the length -of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. - -This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). - -\subsection{PSS Decoding} - -To decode a PSS encoded signature block you have to use the following. - -\index{pkcs\_1\_pss\_decode()} -\begin{alltt} -int pkcs_1_pss_decode( - const unsigned char *msghash, - unsigned long msghashlen, - const unsigned char *sig, - unsigned long siglen, - unsigned long saltlen, - int hash_idx, - unsigned long modulus_bitlen, - int *res); -\end{alltt} -This will decode the PSS encoded message in \textit{sig} of length \textit{siglen} and compare it to values in \textit{msghash} of length -\textit{msghashlen}. If the block is a valid PSS block and the decoded hash equals the hash supplied \textit{res} is set to non--zero. Otherwise, -it is set to zero. The rest of the parameters are as in the PSS encode call. - -It's important to use the same \textit{saltlen} and hash for both encoding and decoding as otherwise the procedure will not work. - \mysection{RSA Key Operations} \subsection{Background} @@ -4711,15 +4502,78 @@ \subsection{RSA Key Size} \end{verbatim} This can be used to determine the modulus size of an RSA key. -\mysection{RSA Key Encryption} -Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message. -To facilitate encrypting short keys the following functions have been provided. +\mysection{RSA Key Operation Parameters} -\index{rsa\_encrypt\_key()} +The following RSA Key Operations share \code{struct}s which hold the parameters used in the operations. + +\index{RSASSA-PSS-params} +\begin{small} \begin{verbatim} -int rsa_encrypt_key( - const unsigned char *in, - unsigned long inlen, + RSASSA-PSS-params ::= SEQUENCE { + hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + saltLength [2] INTEGER DEFAULT 20, + trailerField [3] TrailerField DEFAULT trailerFieldBC + } +\end{verbatim} +\end{small} + +\href{https://datatracker.ietf.org/doc/html/rfc8017}{\textit{RFC 8017}} defines the ASN.1 module for \code{RSASSA-PSS-params} as shown above. + +\index{ltc\_rsa\_parameters} +\begin{small} +\begin{verbatim} +typedef struct ltc_rsa_parameters { + /** saltLength for PSS */ + unsigned long saltlen; + /** Hash algorithm index for OAEP/PSS, -1 if unset */ + int hash_idx; + /** MGF1 hash algorithm index, -1 if unset */ + int mgf1_hash_idx; +} ltc_rsa_parameters; +\end{verbatim} +\end{small} + +The \code{struct ltc\_rsa\_parameters} represents the RSA parameters as defined in \code{RSASSA-PSS-params}. +This \code{struct} is used in two places: first, embedded in \code{rsa\_key} when parsing an RSA key which contains those parameters +in order to restrict the usage of the RSA key to the given set of parameters (the \code{rsa\_key.pss\_oaep} flag indicates whether +the key is constrained). Its second use is explained below and defines the parameters used for an RSA operation. +The hash algorithms are identified by their descriptor index (as returned by \code{find\_hash()}). + +\index{ltc\_rsa\_op\_parameters} +\begin{small} +\begin{verbatim} +typedef struct ltc_rsa_op_parameters { + ltc_rsa_parameters params; + /* The padding type */ + int padding; + /* The PRNG to use. + * Only required for signing and encryption. */ + int wprng; + prng_state *prng; + /* Operation-specific parameters */ + union { + struct { + const unsigned char *lparam; + unsigned long lparamlen; + } crypt; + } u; +} ltc_rsa_op_parameters; +\end{verbatim} +\end{small} + +The \code{struct ltc\_rsa\_op\_parameters} holds all the potential arguments required for one of the four possible RSA operations. + + +\mysection{RSA Key Encryption} +Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message. +To facilitate encrypting short keys the following functions have been provided. + +\index{rsa\_encrypt\_key()} +\begin{verbatim} +int rsa_encrypt_key( + const unsigned char *in, + unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, @@ -4733,30 +4587,24 @@ \subsection{RSA Key Size} in \textit{out} of length \textit{outlen} octets. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass to \index{pkcs\_1\_oaep\_encode()} pkcs\_1\_oaep\_encode(). -\subsection{Extended Encryption} +This API function is implemented as a macro and under the hood uses the API as described in Chapter \ref{rsa-encrypt-v2}. + +\subsection{Extended Encryption v2} +\label{rsa-encrypt-v2} As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended encryption function: -\index{rsa\_encrypt\_key\_ex()} +\index{rsa\_encrypt\_key\_v2()} \begin{verbatim} -int rsa_encrypt_key_ex( - const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - const unsigned char *lparam, - unsigned long lparamlen, - prng_state *prng, - int prng_idx, - int mgf_hash, - int lparam_hash, - int padding, - rsa_key *key); +int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + const rsa_key *key); \end{verbatim} \index{LTC\_PKCS\_1\_OAEP} \index{LTC\_PKCS\_1\_V1\_5} -The parameters are all the same as for rsa\_encrypt\_key() except for the addition of the \textit{padding} parameter. It must be set to -\textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 encryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 encryption. +The parameters are all the same as for \code{rsa\_encrypt\_key()} except for the addition of the \textit{padding} parameter. It must be set to +\code{LTC\_PKCS\_1\_V1\_5} to perform v1.5 encryption, or set to \code{LTC\_PKCS\_1\_OAEP} to perform v2.1 encryption. When performing v1.5 encryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). @@ -4781,29 +4629,26 @@ \subsection{Extended Encryption} If the RSA decrypted data is not a valid OAEP packet then \textit{stat} is set to $0$. Otherwise, it is set to $1$. -\subsection{Extended Decryption} +This API function is implemented as a macro and under the hood uses the API as described in Chapter \ref{rsa-decrypt-v2}. + +\subsection{Extended Decryption v2} +\label{rsa-decrypt-v2} As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended decryption function: -\index{rsa\_decrypt\_key\_ex()} +\index{rsa\_decrypt\_key\_v2()} \begin{verbatim} -int rsa_decrypt_key_ex( - const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - const unsigned char *lparam, - unsigned long lparamlen, - int hash_idx, - int padding, - int *stat, - rsa_key *key); +int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key); \end{verbatim} -Similar to the extended encryption, the new parameter \textit{padding} indicates which version of the PKCS \#1 standard to use. -It must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 decryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 decryption. +Similar to the extended encryption, the parameter \textit{params.padding} indicates which version of the PKCS \#1 standard to use. +It must be set to \code{LTC\_PKCS\_1\_V1\_5} to perform v1.5 decryption, or set to \code{LTC\_PKCS\_1\_OAEP} to perform v2.1 decryption. -When performing v1.5 decryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). +When performing v1.5 decryption, the \textit{params.params.hash\_idx} and \textit{params.u.crypt.lparam} parameters are totally ignored and can be set to \code{-1} or \code{NULL} (respectively). \mysection{RSA Signature Generation} @@ -4831,37 +4676,33 @@ \subsection{Extended Decryption} default value is between 8 and 16 octets. Strictly, it must be small than $modulus\_len - hLen - 2$ where \textit{modulus\_len} is the size of the RSA modulus (in octets), and \textit{hLen} is the length of the message digest produced by the chosen hash. -\subsection{Extended Signatures} +This API function is implemented as a macro and under the hood uses the API as described in Chapter \ref{rsa-sign-v2}. + +\subsection{Extended Signatures v2} +\label{rsa-sign-v2} As of v1.15, the library supports both v1.5 and v2.1 signatures. The extended signature generation function has the following prototype: -\index{rsa\_sign\_hash\_ex()} +\index{rsa\_sign\_hash\_v2()} \begin{verbatim} -int rsa_sign_hash_ex( - const unsigned char *in, - unsigned long inlen, - unsigned char *out, - unsigned long *outlen, - int padding, - prng_state *prng, - int prng_idx, - int hash_idx, - unsigned long saltlen, - rsa_key *key); +int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen, + unsigned char *sig, unsigned long *siglen, + ltc_rsa_op_parameters *params, + const rsa_key *key); \end{verbatim} This will PKCS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PKCS encoded hash will be RSA -\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{padding} parameter -must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to produce a v1.5 signature, otherwise, it must be set to \textbf{LTC\_PKCS\_1\_PSS} to produce a +\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{params.padding} parameter +must be set to \code{LTC\_PKCS\_1\_V1\_5} to produce a v1.5 signature, otherwise, it must be set to \code{LTC\_PKCS\_1\_PSS} to produce a v2.1 signature. \index{LTC\_PKCS\_1\_V1\_5\_NA1} As of v1.18.0, the library also supports v1.5 signature generation without ASN.1 encoding the signature which can be indicated by passing -\textbf{LTC\_PKCS\_1\_V1\_5\_NA1} as \textit{padding} parameter. This option has been introduced to provide compatibilty to SSL3.0 implementations +\code{LTC\_PKCS\_1\_V1\_5\_NA1} as \textit{params.padding} parameter. This option has been introduced to provide compatibilty to SSL3.0 implementations which implemented this. -When generating a standard v1.5 signature the \textit{prng}, and \textit{prng\_idx} parameters are ignored. -When generating a v1.5 signature without ASN.1 decoding additionally the textit{hash\_idx} parameter is ignored. +When generating a standard v1.5 signature the \textit{params.prng}, and \textit{params.wprng} parameters are ignored. +When generating a v1.5 signature without ASN.1 decoding additionally the \textit{params.params.hash\_idx} parameter is ignored. \mysection{RSA Signature Verification} \index{rsa\_verify\_hash()} @@ -4882,6 +4723,8 @@ \subsection{Extended Signatures} If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash} value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. +This API function is implemented as a macro and under the hood uses the API as described in Chapter \ref{rsa-verify-v2}. + \subsection{RSA Signature Salt Length} The v2.1 signature algorithm requires a salt length to be able to properly @@ -4898,22 +4741,18 @@ \subsection{RSA Signature Salt Length} This function is provided to be able to use other lengths as well and to make sure at runtime that the RSA key can handle the desired salt length. -\subsection{Extended Verification} +\subsection{Extended Verification v2} +\label{rsa-verify-v2} As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype: -\index{rsa\_verify\_hash\_ex()} +\index{rsa\_verify\_hash\_v2()} \begin{verbatim} -int rsa_verify_hash_ex( - const unsigned char *sig, - unsigned long siglen, - const unsigned char *hash, - unsigned long hashlen, - int padding, - int hash_idx, - unsigned long saltlen, - int *stat, - rsa_key *key); +int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key); \end{verbatim} This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PKCS decoded @@ -6094,16 +5933,21 @@ \chapter{Elliptic Curve Cryptography - $Montgomery/Twisted Edwards$} \mysection{Introduction} The library provides functionality for \textit{Curve25519}-based \textit{X25519} Diffie-Hellman shared secrets -and \textit{EdDSA} a.k.a \textit{Ed25519} signature schemes. +and \textit{EdDSA} a.k.a \textit{Ed25519} signature schemes as well as the corresponding +\textit{Curve448}/\textit{ec448}-based \textit{X448} and \textit{Ed448} algorithms. -The implementation is based on the \textit{tweetnacl}\footnote{\url{https://tweetnacl.cr.yp.to/}} reference implementation +The Curve25519 implementation is based on the \textit{tweetnacl}\footnote{\url{https://tweetnacl.cr.yp.to/}} reference implementation as provided by Daniel J. Bernstein et.al. and only slightly modified to better fit in the library. +The Curve448/\textit{ec448} implementation follows the same overall code structure and arithmetic layout pattern. -Both algorithms share the key structure called \textit{curve25519\_key} which is used by all Curve25519 functions. +The Curve25519 family shares the key structure called \textit{curve25519\_key} which is used by all +Curve25519 functions. The Curve448 family uses the \textit{curve448\_key} structure. As Curve25519 and Ed25519 are based on the same elliptic curve, but use different mathematics, the keys are not compatible to each other. +Likewise X448 and Ed448 keys are not compatible to each other. + It is possible to convert a Curve-Key to an Ed-Key and vice-versa, but this is not provided (yet). @@ -6122,7 +5966,7 @@ \subsection{X25519 Key Operations} curve25519_key *key); \end{verbatim} -To generate a fresh X25529 key, one can use \textit{x25519\_make\_key} which will create a private\&public key-pair. +To generate a fresh X25519 key, one can use \textit{x25519\_make\_key} which will create a private\&public key-pair. \index{x25519\_import} \begin{verbatim} int x25519_import(const unsigned char *in, @@ -6217,7 +6061,7 @@ \subsection{EdDSA Key Operations} curve25519_key *key); \end{verbatim} -To generate a fresh Ed25529 key, one can use \textit{ed25519\_make\_key} which will create a private\&public key-pair. +To generate a fresh Ed25519 key, one can use \textit{ed25519\_make\_key} which will create a private\&public key-pair. \index{ed25519\_import} \begin{verbatim} @@ -6333,6 +6177,232 @@ \subsection{EdDSA Cryptographic Operations} pointed to by the array \textit{msg} of length \textit{msglen}. It will store a non--zero value in \textit{stat} if the signature is valid. Note: the function will not return an error if the signature is invalid. It will only return an error if the actual signature payload is an invalid format. +\mysection{Curve448-based Diffie-Hellman Key Exchange - X448} + +The library provides the Diffie-Hellman Key Exchange algorithm \textit{X448} for curve448 as specified in RFC 7748. + +\subsection{X448 Key Operations} + +The \textit{X448} algorithm API provides the following set of functions to create, import and export keys. + +\index{x448\_make\_key} +\begin{verbatim} +int x448_make_key( prng_state *prng, + int wprng, + curve448_key *key); +\end{verbatim} + +To generate a fresh X448 key, one can use \textit{x448\_make\_key} which will create a private\&public key-pair. +\index{x448\_import} +\begin{verbatim} +int x448_import(const unsigned char *in, + unsigned long inlen, + curve448_key *key); +\end{verbatim} + +The \textit{x448\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format. + +\index{x448\_import\_raw} +\begin{verbatim} +int x448_import_raw(const unsigned char *in, + unsigned long inlen, + int which, + curve448_key *key); +\end{verbatim} + +To import a public or private key in raw format, one can use the function \textit{x448\_import\_raw}. + +\index{x448\_import\_x509} +\begin{verbatim} +int x448_import_x509(const unsigned char *in, + unsigned long inlen, + curve448_key *key); +\end{verbatim} + +To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{x448\_import\_x509}. + +\index{x448\_import\_pkcs8} +\begin{verbatim} +int x448_import_pkcs8(const unsigned char *in, + unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key); +\end{verbatim} + +To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted, +one can use the function \textit{x448\_import\_pkcs8}. + +\index{x448\_export} +\begin{verbatim} +int x448_export( unsigned char *out, + unsigned long *outlen, + int which, + const curve448_key *key); +\end{verbatim} + +To export a key, the function \textit{x448\_export} is provided. + +It has support for the following output formats: + +\begin{figure}[H] +\begin{center} +\begin{tabular}{|c|c|} +\hline \textbf{which} & \textbf{output format} \\ +\hline PK\_PRIVATE & Raw \\ +\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\ +\hline PK\_PUBLIC & Raw \\ +\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\ +\hline +\end{tabular} +\end{center} +\caption{Possible x448\_export() output formats} +\end{figure} + +\subsection{X448 Cryptographic Operations} + +To construct a Diffie-Hellman shared secret with a private and a public X448 key, use the following function: + +\index{x448\_shared\_secret} +\begin{verbatim} +int x448_shared_secret(const curve448_key *private_key, + const curve448_key *public_key, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will construct the shared secret between the private- and the public-key and store the result in \textit{out} of length \textit{outlen}. + +\mysection{Curve448-based EdDSA Signature Scheme - Ed448} + +The library provides the EdDSA algorithm for the edwards448 curve in the PureEdDSA variant as specified in RFC 8032. + +\subsection{Ed448 Key Operations} + +The \textit{Ed448} algorithm API provides the following set of functions to create, import and export keys. + +\index{ed448\_make\_key} +\begin{verbatim} +int ed448_make_key( prng_state *prng, + int wprng, + curve448_key *key); +\end{verbatim} + +To generate a fresh Ed448 key, one can use \textit{ed448\_make\_key} which will create a private\&public key-pair. + +\index{ed448\_import} +\begin{verbatim} +int ed448_import(const unsigned char *in, + unsigned long inlen, + curve448_key *key); +\end{verbatim} + +The \textit{ed448\_import} function can be used to import a public key in DER-encoded \textit{SubjectPublicKeyInfo} format. + +\index{ed448\_import\_raw} +\begin{verbatim} +int ed448_import_raw(const unsigned char *in, + unsigned long inlen, + int which, + curve448_key *key); +\end{verbatim} + +To import a public or private key in raw format, one can use the function \textit{ed448\_import\_raw}. + +\index{ed448\_import\_x509} +\begin{verbatim} +int ed448_import_x509(const unsigned char *in, + unsigned long inlen, + curve448_key *key); +\end{verbatim} + +To import a public key from a DER-encoded \textit{X.509} certificate, one can use the function \textit{ed448\_import\_x509}. + +\index{ed448\_import\_pkcs8} +\begin{verbatim} +int ed448_import_pkcs8(const unsigned char *in, + unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key); +\end{verbatim} + +To import a private key in the \textit{OneAsymmetricKey} a.k.a \textit{PKCS \#8} format, either plain or PBES encrypted, +one can use the function \textit{ed448\_import\_pkcs8}. + +\index{ed448\_export} +\begin{verbatim} +int ed448_export( unsigned char *out, + unsigned long *outlen, + int which, + const curve448_key *key); +\end{verbatim} + +To export a key, the function \textit{ed448\_export} is provided. + +It has support for the following output formats: + +\begin{figure}[H] +\begin{center} +\begin{tabular}{|c|c|} +\hline \textbf{which} & \textbf{output format} \\ +\hline PK\_PRIVATE & Raw \\ +\hline PK\_PRIVATE \& PK\_STD & PKCS \#8 \\ +\hline PK\_PUBLIC & Raw \\ +\hline PK\_PUBLIC \& PK\_STD & SubjectPublicKeyInfo \\ +\hline +\end{tabular} +\end{center} +\caption{Possible ed448\_export() output formats} +\end{figure} + +\subsection{Ed448 Cryptographic Operations} + +To sign and/or verify a message use the following functions: + +\index{ed448\_sign} +\index{ed448ctx\_sign} +\index{ed448ph\_sign} +\begin{verbatim} +int ed448_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const curve448_key *private_key); +int ed448ctx_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key); +int ed448ph_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key); +\end{verbatim} + +These functions will EdDSA sign the message stored in the array pointed to by \textit{msg} of length \textit{msglen} octets. The signature +will be stored in the array pointed to by \textit{sig} of length \textit{siglen} octets. The \texttt{ctx} and \texttt{ph} variants also +allow passing a context \textit{ctx} of length \textit{ctxlen} octets. This context is allowed to be max. 255 octets long. + +\index{ed448\_verify} +\index{ed448ctx\_verify} +\index{ed448ph\_verify} +\begin{verbatim} +int ed448_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + int *stat, + const curve448_key *public_key); +int ed448ctx_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key); +int ed448ph_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key); +\end{verbatim} + +These functions will verify the EdDSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message +pointed to by the array \textit{msg} of length \textit{msglen}. It will store a non--zero value in \textit{stat} if the signature is valid. Note: +the function will not return an error if the signature is invalid. It will only return an error if the actual signature payload is an invalid format. + \chapter{Digital Signature Algorithm} \mysection{Introduction} @@ -6638,6 +6708,8 @@ \chapter{The PKA Union} LTC_PKA_X25519, LTC_PKA_ED25519, LTC_PKA_DH, + LTC_PKA_X448, + LTC_PKA_ED448, }; typedef struct { @@ -6646,6 +6718,10 @@ \chapter{The PKA Union} curve25519_key x25519; curve25519_key ed25519; #endif +#ifdef LTC_CURVE448 + curve448_key x448; + curve448_key ed448; +#endif #ifdef LTC_MDH dh_key dh; #endif @@ -7589,6 +7665,73 @@ \subsection{bcrypt} where \textit{outlen} contains the available buffer size on input and the written size after the invocation. +\subsection{Argon2} +\index{Argon2} +\label{argon2} + +Argon2 is a memory-hard password hashing function defined in \href{https://datatracker.ietf.org/doc/html/rfc9106}{\texttt{RFC 9106}}. +It is the winner of the 2015 \href{https://www.password-hashing.net/}{Password Hashing Competition} and is recommended for new applications that require password hashing or key derivation from passwords. + +Three variants are provided: + +\begin{description} +\item[Argon2d] uses data-dependent memory access, which makes it faster but susceptible to side-channel attacks. Suitable for applications with no threats from side-channels. +\item[Argon2i] uses data-independent memory access, which is preferred when side-channel resistance is needed. +\item[Argon2id] is a hybrid that uses data-independent addressing for the first half of the first pass and data-dependent addressing for the remainder. This is the recommended variant for password hashing. +\end{description} + +The implementation uses the BLAKE2b hash function internally. To enable Argon2, define \texttt{LTC\_ARGON2} in \textit{tomcrypt\_custom.h} (it also requires \texttt{LTC\_BLAKE2B}). + +\index{argon2\_hash()} +\begin{alltt} +int argon2_hash(const unsigned char *pwd, unsigned long pwdlen, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *secret, unsigned long secretlen, + const unsigned char *ad, unsigned long adlen, + unsigned int t_cost, unsigned int m_cost, + unsigned int parallelism, + argon2_type type, + unsigned char *out, unsigned long outlen); +\end{alltt} + +The \textit{pwd} parameter is the password of length \textit{pwdlen}. +The \textit{salt} parameter is a random salt of length \textit{saltlen}; a minimum of 16 bytes is recommended. +The \textit{secret} and \textit{ad} parameters are optional (may be \texttt{NULL} with a length of zero); they allow passing a secret key and associated data respectively. +The \textit{t\_cost} parameter is the number of passes over the memory (minimum 1). +The \textit{m\_cost} parameter is the memory usage in kibibytes (minimum $8 \times \textit{parallelism}$). +The \textit{parallelism} parameter is the number of lanes (minimum 1); note that this implementation is single-threaded, so increasing this value changes the algorithm output but does not improve performance. +The \textit{type} parameter selects the variant: \texttt{ARGON2\_D}, \texttt{ARGON2\_I}, or \texttt{ARGON2\_ID}. +The output tag of length \textit{outlen} (minimum 4 bytes) is written to \textit{out}. +The function returns \texttt{CRYPT\_OK} on success, \texttt{CRYPT\_MEM} if memory allocation fails, or \texttt{CRYPT\_INVALID\_ARG} if any parameter is out of range. + + +\subsection{scrypt} +\index{scrypt} +\label{scrypt} + +scrypt is a memory-hard password-based key derivation function defined in \href{https://datatracker.ietf.org/doc/html/rfc7914}{\texttt{RFC 7914}}. +It is designed so that a large amount of memory is required for evaluation, making hardware brute-force attacks more costly. +Internally it uses PBKDF2-HMAC-SHA-256 and a reduced-round Salsa20 core. + +To enable scrypt, define \texttt{LTC\_SCRYPT} in \textit{tomcrypt\_custom.h} (it also requires \texttt{LTC\_PKCS\_5} and \texttt{LTC\_SHA256}). + +\index{scrypt\_pbkdf()} +\begin{alltt} +int scrypt_pbkdf(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + unsigned long N, unsigned long r, unsigned long p, + unsigned char *out, unsigned long outlen); +\end{alltt} + +The \textit{password} parameter is the password of length \textit{password\_len}. +The \textit{salt} parameter is a random salt of length \textit{salt\_len}. +The \textit{N} parameter is the CPU/memory cost; it must be greater than 1 and a power of 2. +The \textit{r} parameter is the block size (minimum 1; a typical value is 8). +The \textit{p} parameter is the parallelisation factor (minimum 1); this implementation is single-threaded, so increasing \textit{p} raises the computational cost without improving performance. +The derived key of length \textit{outlen} is written to \textit{out}. +The function returns \texttt{CRYPT\_OK} on success or an error code on failure. + + \mysection{PKCS \#8} \index{PKCS \#8} \label{pkcs8} @@ -7860,14 +8003,14 @@ \subsection{PKCS PEM files} \begin{table}[H] \begin{minipage}{\textwidth} \begin{small} -\begin{tabular}{|l|l|l|l|l|} +\begin{tabular}{|l|l|l|l|p{4.1cm}|} \hline \textbf{Identifier} & \textbf{Key type} & \textbf{File content} & \textbf{Standard} & \textbf{Algorithm} \\ -\hline \texttt{BEGIN CERTIFICATE} & Public & Plain & \texttt{X.509} & DH, DSA, ECC, Ed25519, RSA, X25519 \\ +\hline \texttt{BEGIN CERTIFICATE} & Public & Plain & \texttt{X.509} & DH, DSA, ECC, Ed25519, Ed448, RSA, X25519, X448 \\ \hline \texttt{BEGIN DSA PRIVATE KEY} & Private & Maybe encrypted & \texttt{OpenSSL\footnote{There are two de-facto standard for DSA private key structures, LibTomCrypt implements OpenSSL's}} & DSA \\ \hline \texttt{BEGIN EC PRIVATE KEY} & Private & Maybe encrypted & \texttt{RFC 5915} & ECC \\ -\hline \texttt{BEGIN ENCRYPTED PRIVATE KEY} & Private & Encrypted & \texttt{PKCS \#8} & DH, DSA, ECC, Ed25519, RSA, X25519 \\ -\hline \texttt{BEGIN PRIVATE KEY} & Private & Plain & \texttt{PKCS \#8} & DH, DSA, ECC, Ed25519, RSA, X25519 \\ -\hline \texttt{BEGIN PUBLIC KEY} & Public & Plain & \texttt{X.509\footnote{Specifically, SubjectPublicKeyInfo}} & DH, DSA, ECC, Ed25519, RSA, X25519 \\ +\hline \texttt{BEGIN ENCRYPTED PRIVATE KEY} & Private & Encrypted & \texttt{PKCS \#8} & DH, DSA, ECC, Ed25519, Ed448, RSA, X25519, X448 \\ +\hline \texttt{BEGIN PRIVATE KEY} & Private & Plain & \texttt{PKCS \#8} & DH, DSA, ECC, Ed25519, Ed448, RSA, X25519, X448 \\ +\hline \texttt{BEGIN PUBLIC KEY} & Public & Plain & \texttt{X.509\footnote{Specifically, SubjectPublicKeyInfo}} & DH, DSA, ECC, Ed25519, Ed448, RSA, X25519, X448 \\ \hline \texttt{BEGIN RSA PRIVATE KEY} & Private & Maybe encrypted & \texttt{PKCS \#1} & RSA \\ \hline \texttt{BEGIN RSA PUBLIC KEY} & Public & Plain & \texttt{PKCS \#1} & RSA \\ \hline @@ -8334,8 +8477,11 @@ \subsection{Depadding} "RSA", "DSA", "ECC", - "Curve25519", + "X25519", + "Ed25519", "DH", + "X448", + "Ed448", }; static int password_get(void **p, unsigned long *l, void *u) @@ -9004,7 +9150,7 @@ \subsection{Installation Directories} The file \textit{tomcrypt\_cfg.h} is what lets you control various high level macros which control the behaviour of the library. Build options are also stored in \textit{tomcrypt\_custom.h} which allow the enabling and disabling of various algorithms. -\subsubsection{ARGTYPE} +\subsection{ARGTYPE} This lets you control how the LTC\_ARGCHK macro will behave. The macro is used to check pointers inside the functions against NULL. There are four settings for ARGTYPE. When set to 0, it will have the default behaviour of printing a message to stderr and raising a SIGABRT signal. This is provided so all platforms that use LibTomCrypt can have an error that functions @@ -9013,7 +9159,7 @@ \subsubsection{ARGTYPE} if you handle signals on your own. When set to 3, it will resolve to a empty macro and no error checking will be performed. Finally, when set to 4, it will return CRYPT\_INVALID\_ARG to the caller. -\subsubsection{Endianness} +\subsection{Endianness} There are five macros related to endianness issues. For little endian platforms define, \textbf{ENDIAN\_LITTLE}. For big endian platforms define \textbf{ENDIAN\_BIG}. Similarly when the default word size of an \textit{unsigned long} is 32-bits define \textbf{ENDIAN\_32BITWORD} or define \textbf{ENDIAN\_64BITWORD} when its 64-bits. If you do not define any of them the library will automatically use \textbf{ENDIAN\_NEUTRAL} @@ -9124,6 +9270,12 @@ \subsection{LTC\_SMALL\_CODE} When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants. These variants are slower but can save quite a bit of code space. +\subsection{LTC\_SMALL\_STACK} +When this is defined some of the code uses a variant which results in smaller stack sizes. +Depending on the architecture and other configuration options the results of execution speeed can vary. +Therefore we try to enable this automatically where it brings an advantage in speed. +In case you always want smaller stack usage, no matter if it makes the execution slower, you should enable this. + \subsection{LTC\_PTHREAD} When this is activated all of the descriptor table functions will use pthread locking to ensure thread safe updates to the tables. Note that it doesn't prevent a thread that is passively using a table from being messed up by another thread that updates the table. @@ -10387,7 +10539,9 @@ \subsection{RSA Functions} Since the function is given the entire RSA key (for private keys only) CRT is possible as prescribed in the PKCS \#1 v2.1 specification. -\mysection{Deprecated API functions} +\chapter{Deprecated API functions} + +\mysection{After v1.18.2} \subsection{Elliptic Curve Cryptography - $GF(p)$} @@ -10438,6 +10592,345 @@ \subsection{Elliptic Curve Cryptography - $GF(p)$} These two ECC verify functions have been deprecated in favor of \code{ecc\_verify\_hash\_v2()}. Please check Chapter \ref{ecc-verify} for details. +\subsection{PKCS \#1 Padding} +PKCS \#1 v1.5 padding is so simple that both signature and encryption padding are performed by the same function. Note: the +signature padding does \textbf{not} include the ASN.1 padding required. That is performed by the rsa\_sign\_hash\_ex() function +documented later on in this chapter. + +\subsection{PKCS \#1 v1.5 Encoding} +The following function performs PKCS \#1 v1.5 padding: +\index{pkcs\_1\_v1\_5\_encode()} +\begin{verbatim} +int pkcs_1_v1_5_encode( + const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); +\end{verbatim} + +This will encode the message pointed to by \textit{msg} of length \textit{msglen} octets. The \textit{block\_type} parameter must be set to +\textbf{LTC\_PKCS\_1\_EME} to perform encryption padding. It must be set to \textbf{LTC\_PKCS\_1\_EMSA} to perform signature padding. The \textit{modulus\_bitlen} +parameter indicates the length of the modulus in bits. The padded data is stored in \textit{out} with a length of \textit{outlen} octets. The output will not be +longer than the modulus which helps allocate the correct output buffer size. + +Only encryption padding requires a PRNG. When performing signature padding the \textit{prng\_idx} parameter may be left to zero as it is not checked for validity. + +\subsection{PKCS \#1 v1.5 Decoding} +The following function performs PKCS \#1 v1.5 de--padding: +\index{pkcs\_1\_v1\_5\_decode()} +\begin{verbatim} +int pkcs_1_v1_5_decode( + const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); +\end{verbatim} +\index{LTC\_PKCS\_1\_EME} \index{LTC\_PKCS\_1\_EMSA} +This will remove the PKCS padding data pointed to by \textit{msg} of length \textit{msglen}. The decoded data is stored in \textit{out} of length +\textit{outlen}. If the padding is valid, a 1 is stored in \textit{is\_valid}, otherwise, a 0 is stored. The \textit{block\_type} parameter must be set to either +\textbf{LTC\_PKCS\_1\_EME} or \textbf{LTC\_PKCS\_1\_EMSA} depending on whether encryption or signature padding is being removed. + +\mysection{PKCS \#1 v2.1 Encryption} +PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of +the library is concerned we are only dealing with the OAEP padding of the message. + +\subsection{OAEP Encoding} + +The following function performs PKCS \#1 v2.1 encryption padding: + +\index{pkcs\_1\_oaep\_encode()} +\begin{alltt} +int pkcs_1_oaep_encode( + const unsigned char *msg, + unsigned long msglen, + const unsigned char *lparam, + unsigned long lparamlen, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + int mgf_hash, + int lparam_hash, + unsigned char *out, + unsigned long *outlen); +\end{alltt} + +This accepts \textit{msg} as input of length \textit{msglen} which will be OAEP padded. The \textit{lparam} variable is an additional system specific +tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then +\textit{lparam} can be set to \textbf{NULL}. + +OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter +\textit{modulus\_bitlen}. \textit{mgf\_hash} is the index into the hash descriptor table of the hash desired for the mask generation function (MGF). +\textit{lparam\_hash} is the index into the hash descriptor table of the hash desired for the \textit{lparam}. This value can also be set to $-1$ +to indicate usage of the same algorithm than for the MGF. PKCS \#1 allows any hash to be +used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum + sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process. +The padded message is stored in \textit{out} along with the length in \textit{outlen}. + +If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for \textit{msg} is +$m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. + +Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to +rsa\_exptmod() to encrypt it. + +\subsection{OAEP Decoding} + +\index{pkcs\_1\_oaep\_decode()} +\begin{alltt} +int pkcs_1_oaep_decode( + const unsigned char *msg, + unsigned long msglen, + const unsigned char *lparam, + unsigned long lparamlen, + unsigned long modulus_bitlen, + int mgf_hash, + int lparam_hash, + unsigned char *out, + unsigned long *outlen, + int *res); +\end{alltt} + +This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the +output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not +match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits +and must match what was used during encoding. Similarly the \textit{mgf\_hash} and \textit{lparam\_hash} indexes into the hash descriptor table must +match what was used during encoding. + +If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a +$1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason +it returns an error code. + +\mysection{PKCS \#1 Digital Signatures} + +\subsection{PSS Encoding} +PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. + +\index{pkcs\_1\_pss\_encode()} +\begin{alltt} +int pkcs_1_pss_encode( + const unsigned char *msghash, + unsigned long msghashlen, + unsigned long saltlen, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen); +\end{alltt} + +This function assumes the message to be PSS encoded has previously been hashed. The input hash \textit{msghash} is of length +\textit{msghashlen}. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. +\textit{hash\_idx} is the index into the hash descriptor table of the hash to use. \textit{prng\_idx} and \textit{prng} are the random +number generator information required for the salt. + +Similar to OAEP encoding \textit{modulus\_bitlen} is the size of the RSA modulus (in bits). It limits the size of the salt. If $m$ is the length +of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. + +This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). + +\subsection{PSS Decoding} + +To decode a PSS encoded signature block you have to use the following. + +\index{pkcs\_1\_pss\_decode()} +\begin{alltt} +int pkcs_1_pss_decode( + const unsigned char *msghash, + unsigned long msghashlen, + const unsigned char *sig, + unsigned long siglen, + unsigned long saltlen, + int hash_idx, + unsigned long modulus_bitlen, + int *res); +\end{alltt} +This will decode the PSS encoded message in \textit{sig} of length \textit{siglen} and compare it to values in \textit{msghash} of length +\textit{msghashlen}. If the block is a valid PSS block and the decoded hash equals the hash supplied \textit{res} is set to non--zero. Otherwise, +it is set to zero. The rest of the parameters are as in the PSS encode call. + +It's important to use the same \textit{saltlen} and hash for both encoding and decoding as otherwise the procedure will not work. + +\mysection{RSA Key Encryption} + +\index{rsa\_encrypt\_key()} +\begin{verbatim} +int rsa_encrypt_key( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + prng_state *prng, + int prng_idx, + int hash_idx, + rsa_key *key); +\end{verbatim} +This function will OAEP pad \textit{in} of length \textit{inlen} bytes, RSA encrypt it, and store the ciphertext +in \textit{out} of length \textit{outlen} octets. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass +to \index{pkcs\_1\_oaep\_encode()} pkcs\_1\_oaep\_encode(). + +\subsection{Extended Encryption} +As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended +encryption function: + +\index{rsa\_encrypt\_key\_ex()} +\begin{verbatim} +int rsa_encrypt_key_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + prng_state *prng, + int prng_idx, + int mgf_hash, + int lparam_hash, + int padding, + rsa_key *key); +\end{verbatim} + +\mysection{RSA Key Decryption} +\index{rsa\_decrypt\_key()} +\begin{verbatim} +int rsa_decrypt_key( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + int mgf_hash, + int lparam_hash, + int *stat, + rsa_key *key); +\end{verbatim} +This function will RSA decrypt \textit{in} of length \textit{inlen} then OAEP de-pad the resulting data and store it in +\textit{out} of length \textit{outlen}. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass +to pkcs\_1\_oaep\_decode(). + +If the RSA decrypted data is not a valid OAEP packet then \textit{stat} is set to $0$. Otherwise, it is set to $1$. + +\subsection{Extended Decryption} +As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended +decryption function: + +\index{rsa\_decrypt\_key\_ex()} +\begin{verbatim} +int rsa_decrypt_key_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + const unsigned char *lparam, + unsigned long lparamlen, + int hash_idx, + int padding, + int *stat, + rsa_key *key); +\end{verbatim} + +\mysection{RSA Signature Generation} +Similar to RSA key encryption RSA is also used to \textit{digitally sign} message digests (hashes). To facilitate this +process the following functions have been provided. + +\index{rsa\_sign\_hash()} +\begin{verbatim} +int rsa_sign_hash(const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long saltlen, + rsa_key *key); +\end{verbatim} + +This will PSS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PSS encoded hash will be RSA +\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. + +The \textit{hash\_idx} parameter indicates which hash will be used to create the PSS encoding. It should be the same as the hash used to +hash the message being signed. The \textit{saltlen} parameter indicates the length of the desired salt, and should typically be small. A good +default value is between 8 and 16 octets. Strictly, it must be small than $modulus\_len - hLen - 2$ where \textit{modulus\_len} is the size of +the RSA modulus (in octets), and \textit{hLen} is the length of the message digest produced by the chosen hash. + +\subsection{Extended Signatures} + +As of v1.15, the library supports both v1.5 and v2.1 signatures. The extended signature generation function has the following prototype: + +\index{rsa\_sign\_hash\_ex()} +\begin{verbatim} +int rsa_sign_hash_ex( + const unsigned char *in, + unsigned long inlen, + unsigned char *out, + unsigned long *outlen, + int padding, + prng_state *prng, + int prng_idx, + int hash_idx, + unsigned long saltlen, + rsa_key *key); +\end{verbatim} + +This will PKCS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PKCS encoded hash will be RSA +\textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{padding} parameter +must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to produce a v1.5 signature, otherwise, it must be set to \textbf{LTC\_PKCS\_1\_PSS} to produce a +v2.1 signature. + +\index{LTC\_PKCS\_1\_V1\_5\_NA1} +As of v1.18.0, the library also supports v1.5 signature generation without ASN.1 encoding the signature which can be indicated by passing +\textbf{LTC\_PKCS\_1\_V1\_5\_NA1} as \textit{padding} parameter. This option has been introduced to provide compatibilty to SSL3.0 implementations +which implemented this. + +When generating a standard v1.5 signature the \textit{prng}, and \textit{prng\_idx} parameters are ignored. +When generating a v1.5 signature without ASN.1 decoding additionally the textit{hash\_idx} parameter is ignored. + +\mysection{RSA Signature Verification} +\index{rsa\_verify\_hash()} +\begin{verbatim} +int rsa_verify_hash(const unsigned char *sig, + unsigned long siglen, + const unsigned char *msghash, + unsigned long msghashlen, + int hash_idx, + unsigned long saltlen, + int *stat, + rsa_key *key); +\end{verbatim} + +This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PSS decoded +and the extracted hash is compared against the message digest pointed to by \textit{msghash} of length \textit{msghashlen} octets. + +If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash} +value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. + +\subsection{Extended Verification} + +As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype: + +\index{rsa\_verify\_hash\_ex()} +\begin{verbatim} +int rsa_verify_hash_ex( + const unsigned char *sig, + unsigned long siglen, + const unsigned char *hash, + unsigned long hashlen, + int padding, + int hash_idx, + unsigned long saltlen, + int *stat, + rsa_key *key); +\end{verbatim} \clearpage \addcontentsline{toc}{chapter}{Index} diff --git a/helper.pl b/helper.pl index 9198522e1..8a8824a15 100755 --- a/helper.pl +++ b/helper.pl @@ -108,7 +108,7 @@ sub check_descriptor { my @descriptors; find({ wanted => sub { push @src, $_ if $_ =~ /\.c$/ }, no_chdir=>1 }, "./src/${which}/"); for my $f (@src) { - my @n = map { my $x = $_; $x =~ s/^.*?ltc_${what}_descriptor\s+(\S+).*$/$1/; $x } grep { $_ =~ /ltc_${what}_descriptor/ } split /\n/, read_file($f); + my @n = map { my $x = $_; $x =~ s/^.*?ltc_${what}_descriptor\s+(\S+).*$/$1/; $x } grep { $_ =~ /^[^()]*ltc_${what}_descriptor/ } split /\n/, read_file($f); push @descriptors, @n if @n; } my $fails = 0; diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj index 200dc670a..11cfac1d5 100644 --- a/libtomcrypt_VS2008.vcproj +++ b/libtomcrypt_VS2008.vcproj @@ -735,54 +735,6 @@ > - - - - - - - - - - - - - - - - - - - - - - - - @@ -887,6 +839,14 @@ RelativePath="src\hashes\sha1.c" > + + + + @@ -934,10 +894,26 @@ RelativePath="src\hashes\sha2\sha224.c" > + + + + + + + + @@ -1407,6 +1383,14 @@ RelativePath="src\misc\zeromem.c" > + + + + @@ -1667,6 +1651,14 @@ > + + + + @@ -2427,6 +2419,26 @@ > + + + + + + + + + + @@ -2663,6 +2675,42 @@ > + + + + + + + + + + + + + + + + + + @@ -2795,6 +2843,38 @@ > + + + + + + + + + + + + + + + + + + + + + + 1 is the tag of the previous -step repeated sufficiently. The nonce is fixed throughout. - -OCB-aes (16 byte key) - 0: , 04ADA45E947BC5B6E00F4C8B8053902D - 1: 07, 987354C062CD6251CAA6D93280EFE9BE - 2: 1CB7, B9F1620EA8374E1C2D05110878D93069 - 3: B98C59, 3793FB737C2DFB29E73DD1AD8B8F71C7 - 4: 8978F240, 5E25316ED13D3300F2EC12D718A0BA8E - 5: CB4D261594, EDA252A1A5C7D0A4AB4620F771446DD3 - 6: 30D6B6688D59, 684037DE07832C6FC38CA42BDF2A7D53 - 7: D0583F9741BFA4, 3DF53DFF73431C0245982F4EEEAD432F - 8: EE3B9596CBEFF520, D283D1B9D990739EA05F4BAE2E96BE4E - 9: 6570FC25E6103AC125, 90D3F1FA6595B775749FAE7B00A8E5B1 - 10: F56750C98C370DFDC4A0, 19389A6875FAB432B72D64BCDD6BD26C - 11: 3344AE6D9528603CC1E4E1, 87AB6FBC7F919125A7DB0D17D19056B8 - 12: F3D9D816A727D3E67330C779, 07AC0F3841DFCFEC58A5AAC22270538C - 13: 976651E63ABC3B276799BC1FE4, EE603A8C66099AD6FF8667B3F34ABF29 - 14: A48E3ABC31336C6B717A96170A9B, A9D1B973D84D3125F5F9D7923BA0A8FF - 15: F60E9B2A911FAFB0080FAA3ECDEE42, 4902F8AEB7685F7B255ECC45B5B7D3D4 - 16: 0855DE488940144AF18C65A9966DDB66, A66B3E7A75D394273AC196FFD062F9DD - 17: 172DC1740F75AB2A27B2B80895961A69AB, D6986BB95F7E4137430CAC67F773623B - 18: A414234DCCC61B65A79B7C618A6B91ACA410, 6CE32E55E158BC3E51E94116A615F3A2 - 19: 16A1B16BC0F63D63179901F1CBC772D612C102, 54007EF9822E0E4A4F953838577C76FA - 20: 539788EBF85C15B3A638017B4054D71315BFF25F, 9B2511322E16CECD53E3241F3D51EB97 - 21: 7E74595A3DCFE1EA2C91B67738765463D50A22924A, AC9C9B526251C16F112E769F9FBE74E4 - 22: A2B61792102B2E44F1DC0E48B40472CE883730504FEB, 76452A49C2524404C8A4B098D6390F98 - 23: F58174BC06A022AB7D81991E9346F5E4B0AEC535D93473, 47F96374BC094BB2C1A5D1D291806912 - 24: A3A7713895D178A85D9092EA6138323DC2FF9090D7F01AC5, 3814208FA7009A2934F9A172D029667D - 25: 385525DAF9949DCDEB22F7518AF96438E40F7D94933706A9F2, 1249F3DF50084A6D1A76AA350FD85B0B - 26: 6838E207D98A5BF8D8E41454CF51663D8F8B76FD26092D45D1D9, 301723D0F49BF8CF37828340B894689C - 27: 736413C025A549CB2550E93139DFD5DC3CE241C296C9FE641FF520, BE07259963F251743A85DF51EB1B47FB - 28: 7F2CD26367A885BD9E2B515D4E871272AC1BEA1C650B530E5616B2D3, EEB37E8451597E5A53CB49072EDA9346 - 29: 68F23DCDEF223B60B46E3D724A93BEEF8B110D4394C990AC3D0E34E1B6, 9A60344982F852EFE02CBE9CBBAB60F1 - 30: 66C5DE3EB27139983D48BED81D0E5FCE6BA1AB402C357062FE989D31C69C, BAFA0A7997A529039F0CE8528E670415 - 31: D3B9009C1A930EE288C61B0B15C7E92CB73484C345594DC5A3F377147981DB, 1EDAACF7F1F3AC7EA613F94DA4DEF930 - 32: F7818DF15FE6FBC42A28FDE1D55A2C07EC8D82AA0E7A680DBD3CF26C13448F9B, 67FEB344108008A88067E92B210766D5 - -OCB-blowfish (8 byte key) - 0: , 07B7752047F9E0AE - 1: CE, 7D69017C42B06204 - 2: 1D6F, 4DFD4BD58439062F - 3: 30A011, DB49D988798F8842 - 4: B71C8951, AA3261584B0C20FD - 5: 06F89957DA, 88BFA80D36427F64 - 6: 45BC4CE5FABD, 4CAF71136ED166A7 - 7: A7405F124D0296, 5D8993CE64FFF0E7 - 8: ECABEFD9E6574E4D, B69349673CF86E41 - 9: F7D26A7E82A34ACC71, AFFDEE843ABEA68A - 10: E225C5F0FA1D649F81A3, 03AC1D5DF1323EF8 - 11: 58722FBFB86C2697061217, CE731D80E6355710 - 12: E577EB8FA70225C5A18D31DC, 2F08B140F0D3A255 - 13: 92154A94CD7D42EBADB6CFEE14, DC949170E84D3CA2 - 14: 5A3C08744FD85CA262D51AC6CD25, E83CE45547403BAD - 15: 8B2E4980ABA10A20573A402D89AD12, E3D978611DD831D0 - 16: 3EDC4A0FA95BD8F944BCE4F252B6470C, 87B54BBEA86A5B5C - -OCB-xtea (16 byte key) - 0: , F996E5CC593FD6E9 - 1: 88, 64636E3C48940F8D - 2: 223D, 230D7718A8BCB965 - 3: 32531B, 37FEA4728FAE474D - 4: BDCF3E96, A9F30B4187CD174C - 5: 7B0CCDE546, E7328648817987FE - 6: 824BD771B724, 0BDF80C14EDB758B - 7: 8F0E73B1280717, 2DEDBF2C87180CC4 - 8: 6F7EFA44AF774B1F, 1A9C5509D54A7185 - 9: 9749BCF684F68755AC, E46941DBE948BDD5 - 10: DCD32D91FE2D5590355D, E17DFA54A5B60E07 - 11: 3CBBF6464D438AB95B3ACF, C207876D030362EC - 12: 1C804A611F6CE4CFD2657366, B957F48EA00C428C - 13: 5A2F6927951D8F60C754893790, EB3A27A9E5B8928F - 14: C710D28CD02726002596D9196021, C6C9EBF090A20C07 - 15: 298FFCE0CD42BC329697AEB5F53A56, BB2F0C415317928C - 16: 59F6395260ECEAB2E3511991EEEF9656, 278A218A720F8E05 - -OCB-rc5 (8 byte key) - 0: , E7462C3C0C95A73E - 1: C5, 83CB00E780937259 - 2: 1533, 022FF70566E0BA87 - 3: 57543B, AC4EF15FC83BDF2D - 4: 01E4474B, BD817C06AC2141E0 - 5: 4CD7E850EE, 7BB6B3BDA5373422 - 6: 489C0CD1502A, 23DD4406F87EB164 - 7: 0CBAAE08E07EFF, 92569C958B722413 - 8: 073612F283F8A6E4, 1DD978D01CE8D1DF - 9: CDE676B1A3AC98B00E, C033F099E2620668 - 10: AD3BC88EEEDA40A83685, 36DA44E13C0C8A4D - 11: CA60E8B918F73E99986021, 45634CA0E43E4B13 - 12: 3B3CF82157ECEACAD8658EF5, E681F57616146CC7 - 13: EBC1A7068346EC1B7EB815A7DC, 2C806D2A909CCAF1 - 14: 97CDB3EF8276F1E7D6B6677DA2DB, 53F00B9A2E43DE08 - 15: 44169B3EDAD9506C51A6DA055EF9C2, 5BB6DD996130896B - 16: 35EC29065B1FC640015B0F779E7A358A, 867EBD0E86823F09 - -OCB-rc6 (16 byte key) - 0: , 27B9E3F544B8F567EEBF98ED5FD55C76 - 1: 92, 219FD2D74D7E3F21AA6C2A507C0A546B - 2: BECF, 96A656A16FB3C4579E6955D592AECAE1 - 3: 4DDE09, 7D1882879B5D6FD8C151502BD8AB220A - 4: 0D6B4FCC, E01FBD1ECA2A6A8DC6697A06AB12BDB0 - 5: E5E19C973B, E5A86AADF2F333D5DEDCE410688CC6A4 - 6: 90BA7D2A6965, 80523A2CAB2A7BB2E90B121DE80F46A9 - 7: 6FE258148EC8D0, B7254B11276A77C5F99FE5EC91D81F57 - 8: D887080095DF8817, F3FB938068A01EF89DE0F1226C544362 - 9: D9823313289D597614, A547764EF20BD4B4B303882B64FAF2C5 - 10: FF68942112CF01701E86, 94F3860D4438428EE296CEACB3EB67F5 - 11: FFD390D3E0B64F64D3192F, 99D2E424C67EBACCD4E2EB9A0CDB8CDD - 12: 3162235748BDDECC84FC8C94, BDD400A58AF59100A731DD5B4386444E - 13: D2A0EC8B1F20672289F7236C56, B245CF42644BDAC5F077143AF2A57BA7 - 14: 830929B2850E22F6C1BA2027248C, B6B522F7D6BA3CFFA92D093B383542FE - 15: 2A5FCCCCF43F845AA77750D3BC6B1E, 53A0A0882C7844636900509921661FCA - 16: 8480234796F9EAC313140CE014B0265C, 0656CA8D851B53FD5C1AAC303B264E43 - 17: F011A67C22F16A42CEA5E493CB766964AA, 830B8158B7A96224A53FB7F3A08CD128 - 18: F76274A730A608C2AB37497A049C3699882E, 4DC4DD4DF39D0E68D6169F9DC7F4A6D5 - 19: 7B38DD237DE552A72E4369A81C30AFEA5E5063, 01A62CBD30153702A5B29FB2A1683899 - 20: 58EB866F1FCB060ACC821D776AAC4AD9E87C326A, 25AFB8FC48605E1396EA8471F55C1294 - 21: A25F2C0FAD66B3580627498EC66C994B49C5445911, 0182A951D9A3DA53675612DE8EED1FB9 - 22: 8813977F092F07F251A1497C898967F3F98F5CB878CB, 80BC353E310880A83DD4DE4FE96AB6F0 - 23: 52DC8B76F5A6F78D51FB7DB51048E2663563335EC876A5, DC3689AA079C04C19D83646B272F9DEC - 24: 965437D3FDF91784B63C73C8CD001BD9372167963DF36B89, 9FF84E2845E3C1E3E6711D1646B18F21 - 25: ADD40F674BD56FFC8F9B4047FAAD2471F0A48F4544C894F806, 9D684F74F9734F1C497E33D96A27E00C - 26: 7B049B688839BC62785082397DEC7AA94B837D094AECA4B14571, EE711DF1C15B5C9E36B6E38B6F7152D2 - 27: DD4681F9C498A3CF69A9AC876E02BD9CDC4FB1F6798F772013B62D, C5A50676EFAA2A56CBDBE55CFED3050D - 28: 471B5E89A1337E75E88AFBAACA1C011790F1657425483229E55C34EE, 20F73F2AC452FFEA423BE2EBDF33CFA1 - 29: 71812C83DE34DB329C8DCD98890AFB1F7719E890DAE5CEB7AC9668CAD0, 6FAA03E10C6FB67D425C683C6D85FD76 - 30: 4BC2DB33786CFD29B5CA5B804454169906138E90E29E7BE9197971027AF7, 75053C433EF5572A70C58EEC96F56C53 - 31: 5E3A0AB41264AB65365458ED3B7E6A25827E50075A9E347F1622ED0723E229, C8F1ECD19AD5FC970CF0D31BF46B0F2B - 32: 2E48DEE4B379CD59F5367D17DC397C1BFD53B8C4CE46A8202518614076174EB6, EFCE758ECCB6BE875D16B7E03A498D31 - -OCB-safer+ (16 byte key) - 0: , 88618DEF98FE588E23107E9A5D89C26B - 1: 39, 2B01B202E751F957E331ECD1CEDE3456 - 2: 13CB, 17071E5AFD5D8CE953A73F49412BE8C4 - 3: DC4428, 4B0B1881C2540FF92E7DE63C479A7750 - 4: 120382B0, 0BB11D57B5BD9D846CF31033CD4CCB92 - 5: 97F332F95B, 335E0424D0A820F60DBB968B8B5AA057 - 6: 3C7AAE72037B, C8034C2C76C1CCD7C1B3F36DD8907E1D - 7: 8A99E4A1B89B6D, 06A8165DFADF1EA5ABD89E574422DF7F - 8: 676587065F0342B8, 93ADE63994DF2189079234DC204BF92B - 9: 8EC394CBC6877B245A, 1A89F0AB0B44BC708EBD9DE489E2EEB8 - 10: 5FB5366E5CAE4DB72411, 5CA5881A5805D53ACA4904A5EEC01550 - 11: 72A1994028F09ED6A4E45C, 0FFC0052996CE45DF4A28F7A6E9CFEA6 - 12: 1D5EF20F52A9B72386D1A601, A697DF1179628DE1120D5E8D9F39DA6E - 13: 79BD002AA59D74F125AD9E32DE, 2F02CB6F70BF57BBA0DF100DE503F633 - 14: 442C6F9016DF4C090056258756A9, 58C6FD3180B9B74459D70B5684BE3F4C - 15: 4FC5543D9A892B44ED04EE8B25E232, B8B858B3D3EB4B26E867E429F88A56B4 - 16: F06E7503167C2210AB332259BAFD6AB4, 73CE2589D1DF34CA3DC2B14CC9FA6276 - 17: BCCC260BD4823B64090FB33E6816F9C330, 81ABBDC83B2544907840FEB5AF4479EC - 18: 450C1105B76F960D1A5F33D7F9D37DAE20C3, C41DDC8980E88E3986D9C84857BBE1E7 - 19: C9F36EF3A990E0554EDB59E6788F8E9BF1DBC7, 90DD543E148D9A0B79A8B376C5509E09 - 20: 3666FEEA98A4FC434EDB7517E7FCEE2320C69BCB, 99F11B360DDB3A15C42110831CCBF21C - 21: 126F39C19D1E0B87F1180F6589A75712B66209E2CE, B4D268FB8EF5C048CA9A35337D57828A - 22: C1B6D14EE8B6D0A653BFCC295D5F94E6BCA09E181D8A, 4B4883B614D5CC412B53ED4203EA93B7 - 23: D1F2A10F1A9DAB738C61CD0EF66FE5F6D1DA95DC671128, 3F1EFDA55EFEF1A0B24708E132BC4D25 - 24: 9D457216C584F43DBA1DD55C54822A8B6A86D22DBFFA14D4, 53402970B128E98A5F0D62476A38F959 - 25: 012828614B5D67C9A1EE24A1EBCD322FE9C8BE0C3F20A53714, 2BFF288D90DBDC638084F80F3F7AADF3 - 26: B1904AECF599F6C74557475E409E75E646271DEDEC7A830260DB, BF119BDBDA27773E038B7067D2B0EECD - 27: ED831771C4346FC19435354AE29F7A9436D6E8D4D42CFF26207DBD, C3F029FC8AE690E84FBD0EF806B801F3 - 28: E051B958601223FECEADF932A277BCF18C25025AE4DA791155B85035, EB75E56BE7856F1B5ED3D125C092D38A - 29: AB3449537C5E22125BC32D483F74C3A3DBDBD5232839A85D300F65B4FD, 851B0FBABD080F783BDE4F47ADCD6D76 - 30: 4E68550837130652795A8C9D68530717D2B0AA5A17F3AEF92FFB502E46AC, 10E222706527A64E757EDE4B9EFC09DD - 31: C2D7033DA7A1857D79497EA6C64779EB969046CCEE6C74E6592FEE6E7C94C4, 2015674ECA80AC9B67AE854E18A7D56E - 32: 2F3F0374DDC24AE21F02D4DA74D46C71F0CD2269A68F32F7FAA0BAB64AA8E9BC, 737C8BA1677A8CE97D42FBB07530EE99 - -OCB-twofish (16 byte key) - 0: , 2CD8EF22E5457C7FE4016B0FB82FD204 - 1: 64, EB7BB60E4932C0E97A7A5906BD044ACF - 2: 3A59, E3D2024241666369BB542ED096F20C71 - 3: 67C038, 7E6F1EB3F2088F6416BB675DCAC0D484 - 4: BB36BF02, BDEEEF07EBB7A50A5201C8A2D72C0036 - 5: 6F06C0E293, C63557681D84ACCFFBFEE87D82EF1D3C - 6: 2015F94CC5AA, EF1DEAD4134D2A1A47A20F26FAA3554D - 7: A5F8CDD07964B0, 672B74D88C8AA7567C6AC4A896E0F6D1 - 8: 5EFC9D8C3B9E7F3F, DB9160C53AD429D4C22BC0E2E6C509C5 - 9: B62CB80F75594BC54F, 20020A798FF59F0472E750C796B5CC94 - 10: 970983B0F889760EEEF0, 360AE43CEBCC27755548D4984CEEA10C - 11: 75C3A8CCB30A94CD57D1F8, 79820F3B1625E216B5BC1D1A22B198F9 - 12: 033DA41CCBFE3C6897230FCE, CFE3EDD11627270CD63916508B058B7A - 13: 15358032F30043A66F49D3F76A, 98B8056A7991D5EF498E7C09DAC7B25D - 14: 71FBA7D6C2C8DC4A0E2773766F26, 22BA0ECEF19532554335D8F1A1C7DEFC - 15: BD761CD92C6F9FB651B38555CDFDC7, 8E3C7E1D8C4702B85C6FCD04184739E4 - 16: EB6D310E2B7F84C24872EC48BFAA6BD7, 12DE548D982A122716CEDF5B5D2176D9 - 17: 8DDF6CE25A67B409D3FB42A25C3AA7A842, 3E9FA2C6C65341A8E1101C15E1BBD936 - 18: 5563DFC29B750FBC647E427C5480B65846DB, 90881C6820901BD41F7B3C2DF529B8A9 - 19: 93343C1E9624321C2A0A155BA8B4E66FD92BE2, 71A641DDCD49825E10880D54BEF30E91 - 20: C256BCA0CF0ACCEEC1AA4B9372AF27D2C3C65AFC, 91D45C4DA49BBAD1809A11F4041C7D09 - 21: 3DE69FDB72C93518A3E317F7B26C425EE3DD42DA7E, 85E37B3E8EC3AF476DB7819D739D07D5 - 22: 676AC7885C7C8FBE9862242FCCC46C181440EE49AE59, BCDB42B53AC4FDDF9C3BF8849AB96EEC - 23: D71B98B88F46CC47D90BB931564CDF0157F0ABCB5E6954, 289CD5799D9E49F36D70F67726A59610 - 24: 669C16DB9DC175200C08476832155DAA52F1F8969DF3B79A, 835B210EBBE5C9D34C2E052E1843C1F8 - 25: 2F39346E14A34BBED0491929CD9F1FB3CEC412C25AB703372A, DC4B42E8BA676BA100B87BEE328C5229 - 26: 1FD0F8BD0AC95E91881635EB0CF0E4FB099CBB214CE556422E2D, 898CEB3CA8FCA565CE5B01EF932FD391 - 27: 7FBD32B3D88B7E002BA6055585B5D0E1CC648315A81CFECA363CC8, 804820B1E3813D244164F778B9C2A8C8 - 28: 877A5F336A1D33AB94751A33E285C21666F0D8F103AC1187FC205372, AF9F0AC165EAFCEE8C2A831608F166B4 - 29: ECCA297705B0395E71B9E4263343D486B29207DA188C2F1BA626EDBF46, A05DC873406B236E4DDBC038DC4D2627 - 30: FF3BD8D4E1108E98FBAE2E28BC12819CD7956BC491C0B3A291FBEE739599, 68DFE58473BA2818A23095D1D6EC065C - 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1 - 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47 - -OCB-safer-k64 (8 byte key) - 0: , 0EDD2A1AB692AA7A - 1: 3E, 306F814F3C2C109E - 2: 0593, 063D19B734C34715 - 3: CA72C6, DF6DAAFAD91BE697 - 4: 08924AEE, 15095FA49E789483 - 5: 359908A6CD, 16CB7F0741BA4091 - 6: 97F3BD820CF4, A59DB15B67B95EE8 - 7: 0A267201AC039E, B4FFC31DBCD8284A - 8: 9F6ACD9705C9ECC5, 6B41A938F0B1CAEB - 9: F355D5A937DD1582C2, 9D1F932E521CB955 - 10: ED39758CAF89E7932E48, 398EF517015F118F - 11: D8ACF19363A0E0ADC9321B, F98B2A30217766AA - 12: F8F54A8202B0F281ED610F33, 36EF7FA4A20E04B7 - 13: 0F8677DF64B5982DB6E2299140, 4DED2DA806834C81 - 14: 0C357A9DC321C93B3872881503B0, 7814D1C0C6A8900A - 15: 10B6B1A261C3015A18110AD200A7B6, 9A814D6D2BAD850C - 16: AA9EA9D1BA7818C0D2EBF23781A5467D, 236A24FC98826702 - -OCB-safer-sk64 (8 byte key) - 0: , 76F16BDCE55B3E23 - 1: 63, F34B0B471F6F8F75 - 2: 8651, D7EFE17943D35193 - 3: D45504, 263224E50E7E9E75 - 4: 57B414C3, A553D6CABCA0F285 - 5: 4976E3B303, AC5E9969F739EBD9 - 6: F10AB8EB94E0, 8301FFE68848D46D - 7: 6E954593AC427D, C1CF93BBC0F92644 - 8: F48F44441B898C0F, 698FFAED1A95E8E4 - 9: 1DC60156D62782E3D0, 6AFF0DCC65D4C933 - 10: 71920ADC8997CB8B3A72, 1C101C6A27CFBBBD - 11: 890ED7492ED914AC20391B, F66DCD6205D945C6 - 12: 1B9FAB84A8748BAC187C7393, B450757FCAFAAD52 - 13: B4C89E1BB280DBC265E43ACE15, AE6BB3D2E6A371FF - 14: 24B0C28944BDF22048E2E86644F5, 84E93E2191CEF17A - 15: 8F2D5694D55EE235168AAA735943AF, 514252AEF2F2A2D9 - 16: 568B7E31FFDA726718E40397CFC8DCC6, 3C80BA7FCA9E419E - -OCB-safer-k128 (16 byte key) - 0: , 4919F68F6BC44ABC - 1: 65, C6785F7BE4DE54D3 - 2: E1B0, C197C93B63F58355 - 3: BB7247, DFE092EF8184443B - 4: 38C2D022, 943FD999227C5596 - 5: D71E4FD0ED, 51040FE9A01EA901 - 6: C4B211EADC2A, 329429BE3366F22F - 7: 426DEB3FC3A4BC, CF1C976F6A19CE88 - 8: A6F813C09CE84800, 98D9FF427B3BD571 - 9: 4D1A9948FD157814B4, 5A389FAEEB85B8C6 - 10: EC3EA142C3F07F5A9EEB, 31E26E13F032A48F - 11: A75FB14365D1533CD3FBE7, 8EF01ACC568C0591 - 12: 891582B5853DD546FF3EA071, E013CFFE43219C21 - 13: 54CA848C49DCDEE076780F21F4, 298EFC7B4D6B6CFE - 14: EA7611C69A60F1A2EF71D6A7762D, 7D9AA51CFCEC8101 - 15: B2D1A211BC524B965A084BB4B21710, 7B2AC0EEB5216892 - 16: 5E81F1BFA270E804A488C9BFAB75811D, A67F627CE1E37851 - -OCB-safer-sk128 (16 byte key) - 0: , E523C6DBB3CA178D - 1: 5E, B1CB7EBE5780DF98 - 2: F4D8, 8036235F2BE7A817 - 3: 4FE268, 123320394EAC24F6 - 4: A5BA02B4, B8276B5E027D45DA - 5: 1571859CCC, 29406C5F2DF2CFC4 - 6: CA1E47447B95, 5D4FAF8FD5341791 - 7: 8710DB37022D96, E10040FEA9AEA9C2 - 8: 205990DC9A34DA3C, AE25CB49AA7A697B - 9: 757AFCB3191DC811C3, AA8CADA8638D6118 - 10: 6994F8C153522361BB92, 1BCEE09E928EB18B - 11: A86FA0CDD051BB60AF5AA8, 50A38F8E9889354D - 12: 8D3FD3EB7FF2269AACFD24BA, CB51CF84CEFC45F0 - 13: 03D2A313925D9490FC5547F95F, A1FF9D72E11C420B - 14: D77C0F0F600FE92F14F479FA457C, 1EBE1B4B9685EDFA - 15: 0CAF0A8BEB864E26058C7DF8EBA0EB, 1B153DDAE807561F - 16: 113D12716DFE0596A2F30C875EC6BA0E, C61F5AC0245154A6 - -OCB-rc2 (8 byte key) - 0: , 1A073F25FF5690BE - 1: F4, 3D3221E92E40F634 - 2: 2C76, C22C20B7231A0DB9 - 3: C647CB, 3E6348D996399629 - 4: 2021891A, 8EF76B24E9D55FDA - 5: 1966CBCBBF, 310D24024D573E8D - 6: 42C15AC9AAF0, 217E83C0CDE4F077 - 7: AB70F3F73DF0B6, 16AB2679D96A591B - 8: B7C7DD845D7E76DD, F33065EA531545CA - 9: 468CC16A37CF63EA73, 88879733F70AE3D3 - 10: 4F769E25A7346E22A932, 26E1A92FEDEE0597 - 11: 304A8B53B1CD24C6C27C17, 48B46E9F091B0B2E - 12: 4E3DF867FEFF0B8E06D5FA70, 53BB48BFB8AB4750 - 13: 2BAB3F0A8C38A3BD3C49DBBA5A, 52303CADCBB6D312 - 14: 3D04A29924589AAEF93A29003EE7, 120EF9364B83748F - 15: 486127A80E4EC599C461451CF1D79B, 2245D51599CAD629 - 16: AF8FB3FD2DB343F1AFF564FCBEA58785, 805BF441E660B0B0 - -OCB-des (8 byte key) - 0: , 8A65BD7DE54082AD - 1: A8, 3A83897CC8EC7CF6 - 2: 9256, DC66C39C7DD87D93 - 3: C145A0, 45967F3764F62F48 - 4: CD314BAB, EF38B0213259C3D4 - 5: 7074014741, 6748F4BAF06DD7BD - 6: 9A874CAE01F1, E382DB7235624104 - 7: DFA0D86DC4CA84, 627ABB432E50455E - 8: 685C2B2CBDD8D144, D166082E085063BA - 9: 53515DAAC7F7B8CE1D, 6680B6C26E1B0994 - 10: 2B3967812BF4155A8D36, AFED7F38AFEFC543 - 11: F4E5AC3CC5913B8A7F35FB, 6181DD3C46A6C24F - 12: F3EC89AD4235287D53715A81, 12CC354833FE5BD8 - 13: 66D554AC2CA85C079F051B8459, 097F31088CFBA239 - 14: 8746061C26D72771A7586949A3E4, 6CEF3565D0E45C6B - 15: FB3BCC650B29F418930A467EA4FB73, 64D12723E100F08B - 16: DE1C27E9B3C391AF5DF403291F2C084A, 6BADE4638AE46BE2 - -OCB-desx (24 byte key) - 0: , 972B4CC480AEA6A9 - 1: CB, C46CC58DE9615963 - 2: 2911, 9B5117BF9530018F - 3: 844501, 308F0F36D3313B67 - 4: 0C8CB549, 3F72789FB54CC9B1 - 5: 581FA34114, 1B86E66203EBF9EE - 6: D0BBE3E43961, 59F730D5ABF13265 - 7: 046529AB0EDD17, 240FF6134AA5327B - 8: FF4F32C3A96D61D9, 5DE9B81CC39ACC61 - 9: E94A99D609BE5B1A6D, 443F4948DE64E6A0 - 10: B3E783B59853EE1EBD36, F04B41EAAB9CDE18 - 11: 0BB36CE35BB8050169F6F2, 598A0705C800BC04 - 12: BE946B1CB03E7E5DA1CC12B8, 288B827CEA810662 - 13: 3FEC137C657FF1F2B34F4C5E56, F9248F59D1033253 - 14: 626DC4527055E80E68A6A1FE0F78, D8AA67D5ABD0B6A5 - 15: 476247537A509BC42BCD6DEC7F9506, 2C2D0385066B4815 - 16: 5D32BFE0B9ACB62B6AC29D43A0535A25, DE247F5F809C6CEC - -OCB-3des (24 byte key) - 0: , 9CB7074F93CD37DD - 1: 4D, 51541A838A154E0B - 2: 5C77, 60E86F2F1F4C6F96 - 3: B3D2F0, 7D74A9E6A061457D - 4: B3556075, EAF7A89A07453460 - 5: 1B61CE7230, F90D18620E1AB877 - 6: 3987FEC8D0D7, B5EF04DEE2E528F9 - 7: EBD0A7EBEEFF3B, A72CA24DD77A5DDA - 8: 429FB38DDABF76D4, D0578484C37227C8 - 9: F8DF28BF5C4CD28B1B, 5E7C4DC8E694E3B4 - 10: 2BF436BBE063F7E830C2, 8D919637C973C71B - 11: ED21656C8878319F1B7D29, 8813280C1277DF26 - 12: F45F90980D38EDF5D0FEC926, F9619341E273A31F - 13: 52F2D3CACC294B141B35D73BBF, 7BBC3F1A0D38F61F - 14: 2E6DA0FB55962F79B8E890E8DD8D, 8060799DCAB802E4 - 15: D6F9A6B2420174C499F9FE91178784, D3AAF969ED2F7215 - 16: 4F1CF285B8748C4F8F4D201C06B343CA, 203A2692C077F1B5 - -OCB-sm4 (16 byte key) - 0: , 644D127C5F75F64F48808EEE68350817 - 1: 6B, EE408CBD07CEC607EAA25CB0CF063DE4 - 2: 74E6, FE58AB1D0A951F156D0B78597DE88981 - 3: 049E45, 9674DCB58ED4981CFFCA8725B5BDCBD8 - 4: 416F6FAC, AB0981B209CEB024447861D113FE74AE - 5: CC01AFD1B6, 9125092E4696FE0939A256C03A37FD8C - 6: 1B32E33A7BA2, 80714FA9C1EAE774CF9C754F5FE7374A - 7: 6F91118A6F5E0F, 7065639ADBE5265F0B61836950C39871 - 8: C40E934B952D0108, A8D1ACC7CA93B14C2A187441C794D31E - 9: 06B7FF294A85CD8F8F, 3C433077C03E9B6A481B6A78565A865E - 10: 123093E41AAA91EEA2D1, 9EEF81BFAA0C7116C632DAE3D447BEC4 - 11: 83288869EBB8D22772AA98, A52688653CC795A14D7CC5C4FB59EFD6 - 12: FD8A2A59C3BA54DE090DFFAE, CA597A88711955563025FE6F6B6CB095 - 13: DA0FD6F4B1A0A8084D92F543D3, 9F22A8F0B9EFF906DFE7438E0738FF4E - 14: 8D8090EFF0A44E96A4CB582A61E5, 11477309B525FA0B1A1B4B0F25DED574 - 15: 95DF2F968380DAF60122B8FEA2614A, B25F1C94B4F963297EF31AD01819CAD6 - 16: E63BB516DEF0A60F3503FC9578082588, 9E75B31F3A10D922A698610EDD224AC6 - 17: 4141B7D60688A6B74659FA3F988749336C, 2A4A83E828CA79F3CBA7A417E4E9149F - 18: 68A58C0AAD6A8831231DD3537D5E6284FAD7, 4372DBFA17A102118A4750E719FCC9FF - 19: 6565EE0302F1AFE357E65B56980F04EB805228, 20E09947D4A4947CD24457589303BD69 - 20: 0400E928A18B85498DB78CFAFC026CB07F3DD3A3, 9646E0737D7F75F109430336754DE155 - 21: EC2A5AE19531D964B6C03C4ACE804909F3B0260DC6, 6DEE21A1B2A14FE5F8C13C3620F35EB4 - 22: F32AEDAF0281234753F5D2903F1FEF505165D4543923, B8F486809ABD26E4CACF6C283CBFBAFA - 23: 482B2728C75FF1206E280FDDD082F2C93EE9C2C15A14E9, 70DA0D202F68BF7DCF126DFE2CC75CA9 - 24: DB67772FC481A6D2F50ECCA59134984869C91436211A24A7, A7391E9F5698DF1BC984F127A874D8F6 - 25: DF60A24E93101ED2F68D3CAAD966F51271603C8E611AB16C3F, A4C44700A6845A75B72C04C1395E9820 - 26: E14DE8BC5A2A8417783267AB659DAC26A84A02B4EB5FA4BAAE7F, 1508521641C38536DAF3B2CE65BC060A - 27: 309D876E6CCB6C8FDF963D6143E2FC091DCF7FA75D002986502500, 323AE0DB790F786252F35547554990E2 - 28: 7D8D3119EA42098509D0B1FB8FDB945E1C6C7AF4E1C9773F82A6D3DF, 8F97D69077AA1AD2BD7A8FBE6950E632 - 29: 597A5B272750C5CCE0591CE40A4CE838F3C326A9BCAB160385D6D431C0, 2F9D9980E31419966C6F5DC8E6DA216D - 30: 676720E8BB37FAD3778C4289CA1442A4905F327798C7C3584FD9518F19CE, 60D96E4249518291C68EE01AEB5A5B05 - 31: 609D0A3770F9BE06D7100E75FA0096F21FA498C28224A9406228534A43DEAD, C3148A9D60CD32EA378720262A3529EA - 32: 18BA4D72E61851F5878E07459A24BDFCB48C6A2AF719584CBE6A0B321078B967, 077031AE31FC5ED7B27ADABDBE699CDE - -OCB-cast5 (8 byte key) - 0: , 77E8002236021687 - 1: 52, D57DF1037B6A799D - 2: 31C9, 7E781759B057D695 - 3: 5C8324, 56965D6CB2C97C0C - 4: 17D99099, 7C52B5D09475F5D3 - 5: 400082C475, 3CA5CDB9B4A0FAE9 - 6: 4DF0E4000C24, DCFEE2C3384F9731 - 7: 10004C3CE32255, 0A6832F985F61658 - 8: FFA6EA76B346893C, 6202693B153254D6 - 9: E96378C94D246AB51C, 5B259FEB715B9159 - 10: A9BED2D59A92D3D9418A, 1E7E066C098A023D - 11: 4EF144B7D4622BAD4DC840, 5DAB2C1D0DF56B08 - 12: 6DBCDF56E57CE47DD3D0CF44, 2A24F2A224368F55 - 13: 43241A0AD933635D7C8EAD47DC, 86B4B5AC22177F19 - 14: 920D6BDBE073F3C75052420C883D, 10943DBB23BD894D - 15: B2C75DF024269833B039CAB19EC865, 84B7DBB425E45855 - 16: 6A9424B6A873BB7155C01DC87E23EC52, 82C5047655952B01 - -OCB-noekeon (16 byte key) - 0: , C810FFEC70BB008FD7C314A732B226E6 - 1: D0, 3C48A2C7E0CE9B9099221EF2CEC56767 - 2: 5542, 518EDB8174B067CBF2568C6911378137 - 3: 65E8A4, 3E4EFF5F6FBC99EF3B71B11F566A20FB - 4: 3D0EF863, A366D5CE05F564B5E676EC78938CCC85 - 5: 89B17BA512, 0E83095D771F654CBD630AC114501A0F - 6: E9AF5FCFEFED, 3A283F7FF02274DD4B48C2CD7E36182D - 7: F7A001CEC51C30, 8392CC274521BB452134713153F36268 - 8: D796E3F23E31D4F2, 351C7B0304E127287A9A1DE38BB3167A - 9: C4E2BBF6B4827E1A84, 275907279D0764CF80D7E6626D81F994 - 10: 6C61226E61F70408A61A, 941AD1718D272BFCB8C5ACE08F90B2D1 - 11: 3C195850E7FD63EFC11F7C, 348A975B60908445230D4D56A0CAB008 - 12: EE5FF5362DA3744C9EAD274B, 875C2167BFAEB65F5601F2DB9035444C - 13: 7DB5392ED1933ED858EC0C52F5, BE6507D8AC743805A872658C680A4D06 - 14: FEDEAE2EC2059D22B960813B5E7D, A559933509C47854176CEEDEC12EB8B4 - 15: 64C81F2169F7CEFBF51E68D4186A36, FFE84A9B49F0E77A9799EDEC7D76B987 - 16: 66532B678D23130714E088FE874C4743, AF95ADA553A68319DBEBDA4172E18A22 - 17: 53E56845C091A1E2372F3FC772017C9804, 9A6AB7CEB632429F2B31FB91C141B6F0 - 18: DAF6832520591B886E2E962ACF5B9D0A38E9, 73FFEBA8997E0C55CB0B4ABE59C86BF6 - 19: 108F04FEFCB5EE68033E57346012CDEB348D14, E08E90976E0F7868994B017D7A007AB8 - 20: 101682160DEB9667FB073F96ED1D9C063ABCE668, FB79A4BEBCA9A7832C72116AD9B98D41 - 21: E10AB0D22A6C4C253D818AB6AF1A3FF5811C6CEF24, 174CD350B069A239F9EB80A7BCADE8B7 - 22: 9F62A79B25D4F5532D78228A50516F97ACB7A2C5DF13, DD25DD14174B5667B0AD70732323C8C4 - 23: 2A0AA96147E74A3B881D62BA692EE27927A9EAB351C6DB, 9CE03AACF9318770BF7E095F90B470DB - 24: 29E38605973D0218AA8BAF2FBAB7722DB242C4775E453372, 72D6038E8927EDDE469F98B84C74A8A3 - 25: 8DBF8C2B5477DBA6E07B269293713D60D60BE29E677CA35C33, 83100BBC1401C890B36890A3FD0CD4EE - 26: 13DE9776093827F254DBF500EEBE0C65DC602A5FDF6AEFFC34D9, D142F6CE9E43633CBE94A2BDCC9AC5A8 - 27: 4A25370043862CF7A12A00A5A278623F9BF8DE33212D35661591EC, 62064DD74F9F6D77682B43D9B44E26B8 - 28: 37C6C6C40DA0581BF041770E330A40185E90426A1A4AC9BCDBC5CA7D, E77EE99F62EB1A38CCD1E90CED6EB5C7 - 29: 6B9047158068957CBF77F35988E5C926C7B262A8EBA9D33638A15B1505, 913DC491D3B2AFF172053CC4D1271F46 - 30: 949E5F05396F60722877EDBAA5D7437DDB24B3E25651458C266992D0854E, 87D4396BBC24646659F10179823066B2 - 31: D48489C360F6EB2BF4155FFD7CCAFA4793B8870BFA4A95C9BEDD372F51C04E, 173EEB238E6186D5A93AC6072A22B772 - 32: ACB6F91E8BDB4CFFE1F2A5F6C712D16177EE06842E4CF27F61C8F68D44C842FF, A1E5F2560183B0AFE466243EF3921E4D - -OCB-skipjack (10 byte key) - 0: , 90EAAB5131AEB43B - 1: 2F, 6274B82063314006 - 2: DAF6, 6A6BCCE84FD4EF02 - 3: 5C2A88, C83D54C562A62852 - 4: B6E8FB5E, C44459EF41C8F296 - 5: 6C0888C119, 269DD7657BD0225F - 6: 1FD9AD7ECCC3, 3CA090F46B107839 - 7: 1EDBFF8AE458A3, 440380BF9745132B - 8: 04DBECC1F31F9F96, 2653620A4877B0E6 - 9: 908AE5648AF988A896, 00180FF33C1DD249 - 10: 53E63E0C297C1FC7859B, 36616209504C4230 - 11: 407BE16144187B4BEBD3A3, 4754B7DD4DB2927B - 12: 9961D87CFEDDF9CC22F2C806, 5947FC41E6B9CEC9 - 13: 9F5254962E4D210ED8AC301252, 97A392BEAF9B3B04 - 14: 379FDA76ECCFDAAC10F67FBF624C, 1D895ABD932BD5EC - 15: 1D5A7AD556FF3078284BB21A536DAA, 01FAE2F4936ED9D2 - 16: 4B8B71396924880CB33EA6EC6593F969, A0F4B1BE3B9B4CCE - -OCB-anubis (16 byte key) - 0: , D22ACF880B297DB0513DFAF0D2DF57D9 - 1: 59, 210A179469D6568AB9470C760415574E - 2: AFA5, 1223F9CD160ABE2F257164C6E5533C87 - 3: 969BEC, A57EC767543CA2ADBA4F5A7423ECA78A - 4: CF8B31F1, 13B5BF9CD87CE15CE696F3AF1B082650 - 5: 9B22DF3852, 4937FDDA0AFDDA04CCD53CCBB0A82745 - 6: E11719B2F0F8, 6847931DBF0223F5CEF66AE3F4DFCF9B - 7: 5A85E0F6DD2266, A1A0AF45A68A681CC396615FE1E1DFB5 - 8: 7F2DFCC65ED86976, 13614A3C6E0E08611D8DF8EE5B7D788F - 9: 1DAF10DFA3F1D53E50, 673632B6DD553BAE90E9E6CC8CDE0FA5 - 10: AF74FD9671F9C0A9879C, B8B4DD448FE967207227B84E42126D90 - 11: 49421CED1167A882E26297, 21C8951A1761E4BD13BC85CBD14D30BD - 12: BC0BC779B83F07D30CB340DA, FAABD25E14FFD8D468AD6616021F604C - 13: 843D7E00F94E61AE950B9AA191, 08933ED5FBDCAF72F788393CD5422D0F - 14: 296F15C383C511C36258F528E331, 8BFFADF5655C1864057D69A6706D1739 - 15: E31D2E80B2DBA4FBFAF52DB0513838, C4CD36821EC631CCBF1F258EE9931288 - 16: 87F319FE9A48E2D087EDF95563896EE5, 517960488E5A118D150A1573E76C290A - 17: 9632B7DC1740BBE0A7AEEFD0F535B5AE8A, 0C24D0950873621D319A928862D3A6AC - 18: 359431ED4B3AC537238CAC2F86126972D403, 4A0CED2F4BFA3355C17D6C5DF9FABFAA - 19: E15B50172EE8DA9C552D448A5A48BEEAA2F11D, 8166B2A2D3A0745D1055F9F503FD6C03 - 20: 75842DDC0D5E3BD80225E4BFBD1298421244D7EF, BB957BB2582B67B63978BCFD7A949EDD - 21: 3DD69162716D5F3E096E614991CAD7ED8E01F926B8, 40A954F31F5B0A2C5DD220ACED8D2B3E - 22: 8A49AC14F59593D5399A10F9346E2FD36F47F64ED419, 4324D408CE7F86370495AF14FBD1A859 - 23: 6AA8FA353BCAAB4262211D75F13D27BE173526B8BC3CFC, BA3A27D79EC8ECBC5A78CB9FD095B766 - 24: B918192BB72CFEF980298EEE570460356A4BA1755576FEAA, EB341ECE0A070E769F498600EE4EBF77 - 25: BEFAE0B77E42A2FD18958D9E43202E8A338562AFF8317461B0, 444C1D6BDC026A01012BB2CEEAD89C2C - 26: 07E86D49CFFE6FB08FDF44584033AF321447003D8AD3862C00C9, DA9355A79B224EF662DA65F19BE494A7 - 27: 911BB223AC6F6E54082FBFEDEC300D73FCAF715CCA35949212B372, 3496160A46A21DCDB5A4C179F159D860 - 28: ABB563FC803715F59AA35460E98470E2E94E4270455ACEBF4297641B, 899CFE1946A060DE620879B8A7464718 - 29: 47D98E83B5849CDE19B14ABCF9EA6CA9684AB49A3AB36BD14F328D808C, 6D76CD5EFF6D4AD3B67A56DF1EB42E05 - 30: C8BF0B71A95884FFB93D64C57E327A4754EC5A1EE26632CF8E0B6B26CBDE, 2B3BE785263B1A400E5893273AFD09AE - 31: 9804D668CF2D75CA58C9671F65630E33909269B9511AF9119BE88EBB35F00C, 3DDA028B1A2339CA817DC8D9371E0FF8 - 32: F6E038A82A09BCD20BAAC7926B2296B78F9CBA9DD12C497C47EA08DBCD8CEA3A, A203FC1E68E21A52E72224891AC10EE2 - -OCB-khazad (16 byte key) - 0: , BDEDFF7AA0070063 - 1: 00, 67E951582D66ED93 - 2: 5FED, 09DC8AEAD70673DE - 3: 26A7CC, CE1436CE1E37D4B0 - 4: 3D2BD063, 574C24395F31511A - 5: 597F1AFCB1, 6FBBE820C6F26CDB - 6: 202DAE442DF6, 58CA6E5706C9852D - 7: 7C20EDA18E9444, AABF0DA252A1BAAD - 8: DEC02BF76DFD5B77, A0A97446B80EACB6 - 9: 5D7A42F73843F9200E, A1DD603372D124CB - 10: 0D4710E454C19B68369E, CC78E9D7EAA6A39F - 11: 126694191BF09A29DCF40E, 76C9B84FA3E8913F - 12: A94EBB86BD325B4FA1942FA5, 613DE312DB1666F7 - 13: 4F9462386469EA0EFDC1BFAFE9, 5247244FD4BBAA6F - 14: 4EB794DFCF3823BDC38FA5EF3B23, 0C12017B5E058398 - 15: D870479780CC5B3B13A7A39029A56F, 003D3FCD31D497B5 - 16: A47BF1218AC86A60F6002CE004AF5E50, B4EC27091D5DCD58 - -OCB-seed (16 byte key) - 0: , D80D16D2D0FB2BD9EBA4912468B893D7 - 1: 12, 8776140CB818C1CBFD2CFCD8BDFC9FFA - 2: F8A1, 597381977898AC43194C302216113CEB - 3: B35B5E, BC327275E7A552C4E0AC0FCB8403A6C4 - 4: 19F57542, 4E49DE569547B619E4187239D9B755C2 - 5: EAD2D99E86, 53DCC5FAB4DE25541A22AF0309C9FE78 - 6: 4902A8FF9AF9, 950D9A28DFBDAECE5F14D47E6B7A8B8B - 7: 45FE502602EA4E, 69CD243A3CF17FE51ABBFA2CDE510BCC - 8: D54F2EDE48207CFB, 775EE6140AACF9D56787071F08F36F67 - 9: FEDBBFD9FAABC80186, B37B2C643D62A205BD009BB55D50B918 - 10: 3541A86C889AFEB783B7, FE41A36AC076F417B6A3870DB712CC1F - 11: 62EB71A2EAFDDE1A050AFC, A953ECF1F0B53438E869F0CFB84CB142 - 12: 77AFE377460D6A51208194DB, 5CC2A9D8499F1B25D78937DAFB1DED10 - 13: A34FCDD7CA45DFAA2178CDC7E8, A14A119115143EE2B4719282C9E2356C - 14: A61FA4E9550280C8AAC87EF7A204, A87DDD9631C87ED0792C067E8D7F1D9B - 15: EE82AF5C51896AED298B0C12E00ECF, 9051873090B013508F93677D3A080E96 - 16: 5D532646FAD510E984959C4E14F853D7, 275D8DF932818030F1269804DE06A73B - 17: 1D77F8916DF479DDCE3F49A1D9DEFA40FB, 99611A067F45F140AFDB6FB7E9C23DF2 - 18: 5857267B77E7B8D7732509AEAC0AA80BDB2C, 3159BF09910493977A33268C7F7DBC01 - 19: 1CF64E54D48811F02DAAE472846E65235DC8B7, 78F88A35E2D93A0746058D1B37762A27 - 20: 8CC20A5FEFE9AAE81742DE70453F62A961188DB7, EDA9E9208EC38152E53AFD62ABC77F0B - 21: 1D6CCEEEC72CC7369C33F5CD83ED0DCD6F5613D562, 9FEFD274F3F906B11DD87CC2C0F9D0A2 - 22: 20A9C1EAD88F005DB8F69C8BE005D8A010B261FF2EAD, A341F754932DCBC6DAFE4231918A9CF1 - 23: DCEC1BB28E8D77D69B5148FB02E02C281B68BA6E9768B0, 6AAB2EEB1D25D2DF7CEEFA6054E295DA - 24: 7C4F7165943DB1EFA5731F5C75931F4391F0C40D5731BC54, 3FBFF88733ACE5289D9FB9CD24C44C3F - 25: F5E2C8A9B3A02E0BB86F9E969B0EDA5F554B0C8902BB6F4643, DFB22569019686B2EE92ABA9EE6610B0 - 26: 42B7D0E9613AFAD6E8093E4F638BC96E22413F15A84202188C31, 002F0F602F596236A8F239E81CE47FC0 - 27: 88B89B7756BD3BE09467998FABD12BCE87E5FE994ADE9B30844AE6, 05E0E8AFA55C3B571A849CE4C9F1F477 - 28: 10452565D15D1D829FC54F61960C6A749AFB91086E388269CF6B588A, DD88B0C63E040DF8878B3C919AA95218 - 29: E68619409B86082C744496FC3F645CE1134E84192D2CBCE1CFEEB12612, 83258C337EF21302724CE051A03195D6 - 30: 840277319319EF1DDF6A57682B6695550157F5B76756BF81BFFB3394AFC0, 183FA85F8E91F8972DA23108FA066F20 - 31: C74A4B01328B809397C07F4FC16131FBEE6396293181C327ADB50EF39CC936, D6C5CF79D47995D7CDB5745F601D859F - 32: FF3FEE866339B01DD2C1EC0C0E569A458A77DD014AF0CC9C0A8DC52A52133940, BF1AF01F2CB34CBAF1EAB96FBCCB5404 - -OCB-kasumi (16 byte key) - 0: , 7B4CE3A5B7284F8B - 1: F8, 80584D787B7AE753 - 2: D37A, 7BD7B52BE65B995C - 3: 2D07BF, 6E6E16FDFE808D21 - 4: 9F1A8E7F, 810CDE98B80F2CF2 - 5: C6A7842512, CB6E9709AD7E8545 - 6: 056553F25EE5, 24A74A113D68E373 - 7: C3E0215DEABD43, 80B9F0ABDC207E04 - 8: 38DA7B24B04DDF91, AEEB273DCAE4F743 - 9: 34169FBF64966E0EB8, 1D10D18FC0DF5372 - 10: 5B3A510F1AE97BFCE1EA, 5B1342A77724DBF7 - 11: 39D1B5067E584E59BB6603, 38EDA20D46B2563D - 12: AC2DD02E2406D7D8175EB308, AE7DCB1AE6188975 - 13: B0623EDBC20FEBEDF9B4AB70E6, E218732D221A04A4 - 14: 82F57A435A92E28B56F4EF5E7EA8, CC5842752D089C26 - 15: F2D54E3B9022AB32F668AD5A20D050, D811DF3DE76089FF - 16: 1CAC13A538AFC64D9747226AC23F072C, 2DF49C64213B35B9 - -OCB-multi2 (40 byte key) - 0: , 70A2AD75028C8B3E - 1: 3E, 76BE76B249142049 - 2: 5C21, E31CDBD0ED6B864D - 3: 62BC9F, F1124FC4C9C82617 - 4: BB5AC85A, 97035E20D4FFEC81 - 5: 500D9D05E3, 86D5EC5AD1D55434 - 6: 5179B8442E46, 432EAB80B938A00E - 7: 361000D13C364B, 5ADB3F9FD65EC776 - 8: 5C5BD790B927CBE4, F6ED8E9D330FD37E - 9: 2020DD735C5D7B4739, F98DEFD6A8368E1F - 10: 008A8548790A3582C2AC, 041C4E2FA196390C - 11: E6409403D3E2E4385EE54E, 25AE9113A0E7A3EF - 12: E23E598908C755FCF9D51E39, 21BF8C9F319FB44F - 13: C1F13F46FF04717C7E54FFBDC7, E7D8CDF40A1D78A5 - 14: 27721EB66D4F6362308B96DD9895, A374C96FCA94C809 - 15: 1A393F94CB9ACD3BB93D8766C63569, 45A090303B71D35D - 16: BCC0498FB13CEE8A615FF6409EDF1707, 9589A4CBC481A455 - -OCB-camellia (16 byte key) - 0: , 6972CC27A9711EAE6654851AB8E0C53F - 1: A2, 208D783961FD532E14376B4EE904FE52 - 2: 1177, C7CC74015F7EDD9A72F7435494D8A050 - 3: 0F8502, F1A708AA0F485A554E2E76592CD9D7F4 - 4: 9986180B, D47186A8B539F890824DEBA223861ACD - 5: C0FF4519C3, 4430A9453016E4974CFB5380A1F3E95F - 6: 2AC54E3E6A0B, 6E320BE8DAF4BA0462A57BECC574740F - 7: 846053E1A37A6A, 5B91B680B92517781DC362C2F3E144E4 - 8: CCB09ECFF76EEE2C, F91E7E245F4C8A404F3ECC7DE49261C3 - 9: E049E2AA271388106E, 8C6981A160D831F4DC57FACE5ACCF006 - 10: 761782341D52BA8AD12F, 672DC4B06DBBCED80381CE4845757F0B - 11: 92AD781DEC4549940265C6, DB04CAABC54E71FE1A9C41DF1ED5C52E - 12: D507B77EEE9BE07EAD700143, B3EFCC0B27DC85166E04E7BC39E45C58 - 13: 5AA1AD6B9CAE3001D4C1CC4048, 424D8A22F7B9ADA30AAC0C1D3D4E77F9 - 14: C69E96F7A4B9A6F0F2C7EFA72C26, 678144F802AE9DD83D11877779B48972 - 15: E2596B3FE48EF6EC50D857C8B4E3F4, DDB3BD2B8AB2FA71C7F56C8E57AFF2C2 - 16: D81664A002E03A75E08CF16EE7670E97, B56A0B0955E15E62C557C6E66782AF4C - 17: A8F2696A972A87C784FDC775439470D822, 36E3AD03CB18002A17D49E466CE64814 - 18: C2B537D807BD1ACA734AA072D9C2B836F588, 449B05D145666D1E5A92E204FC3507D7 - 19: D5418F1288BFA7D39D23B3C6ECF797397D3D44, B0CFBA612544B8AB159E9D4AD1FFB3D4 - 20: 2F9522460182291C6F264308E0363B9FE312E517, 1EE4CB38075B67463FB9DE26DF9D581C - 21: DF2881568BECA504A66E4B15BEA58AE6E99D0270E6, 3283D46803FC33098BB262FC1D2B2157 - 22: 4B0083A4CF7E166C8466A5B991AD0CDF71F9DF010EE7, 7C91D9A5DF6C76CB02D83D8C7F3D8D07 - 23: AC0457474B4193647D62906BD08D8C8EB32BE151555B68, 0A448FF3C468D7CDC945724172CEB66F - 24: E6E7786EBECDC296F072CD66C89141C700DE2A8B5DBF6549, 68ACCB5FEC04717FB21FF3B46A34BC74 - 25: 860865770047A9798D90C9365E9C9F8210CB804D785D65E2C0, A58F22FFC4CBFE3BBA451BE4B3B95723 - 26: F157588B4F98D798E6850D8F04ABF9905C1BBB2D055ADE1EA424, D6960C1EA6DAF225366374333D38EBDB - 27: DE3431977821BC861CD88E4236BCAAAFFE3C894607498FB8D68746, A3D23729464BD38338F4AC5B4D9F5C81 - 28: 3F2F0AB546E118B76B937D539806DC02D02A5D42D64926A9E1101D66, 3C0D2D23F5DAF7D36DDC0F87B4163F42 - 29: 3F9FFAE1D7BC62BB80A2FA2728FC33FF02E26CB9F52EA8D03FFE95A49A, 96B45B3F946E629ED974EFA7B66F5DDF - 30: A398B66C8425CE9E8A6BF5AB900CEA1EAE811E06AC7BC0D69A53FB2015BB, F83411C72B7DB201B254565D1DD8D1BF - 31: 9C760ED6C10A80C52F092ED20AB1D03A52427B6235F3C7FE7541033AACDD74, 8AB98FCA89D1245B177E0AC06E083024 - 32: C38F260587B3BA9919601BD0A56909FB36ABCEB8968D08DD6B74F1EF5ED7065C, E357D0D56124276790DACA38D95792BB - -OCB-idea (16 byte key) - 0: , BDB7AEE81A437AD8 - 1: 20, 98EC8CAA4544B41E - 2: CF69, 33A6414FBC482456 - 3: 25723A, DA6DE676482C6607 - 4: E4220FC6, F67538CEA28002AE - 5: E440418489, A21E9F1D15F44038 - 6: 886944E0CF10, 2EF54D278B08DE7D - 7: 5088BF9EFA7E6E, 8443C572C85AF187 - 8: 0D6765F689BF0BE5, 7E658DF3FA677FD0 - 9: D5D02EDEB67AC6E573, 1B1568BC59905994 - 10: 0C6BDA63A6EF19AE4A3F, 6FA765B6906E5B8B - 11: C58013FE24604DCD40611D, 58A5351EA8CADBC4 - 12: DB78CF844EA91A3F7CCF1478, F9B6EC2F22888C12 - 13: 4329E9812856B9A80297CC95C7, 46A1DE8C53B6A1A4 - 14: 6D1CD2DF838697CACCDB28376973, A587EE5CE2351348 - 15: 21C3BCB256DBFC0B472F30A6D469CA, 3ADD0D84695C5B14 - 16: BE073E735F86AFA6D3A4F56C914D5EB8, 07921F5BA6E9F250 - -OCB-serpent (16 byte key) - 0: , D9490CE405238D17C036B3E5DF4DFC7F - 1: DB, 44C1E20A0467B693019DFBA21EAF9035 - 2: A343, 2E20DAB7135E395AA3FF227959A70610 - 3: CB7E24, EE8FAA34CA9C43CFB24061B79DE82C70 - 4: F9BCE9E7, B6A48414BED23D37F99FED990A3A0B14 - 5: 2D3FB0FEA0, 06700497ABDC995F781771CCEAC341B7 - 6: 0C1BAB99858B, E4EB74D56565A50D16CF91D9872B702E - 7: 72CEBD89561A1D, 8FCC39F07C721EC8C92AEEA3C4BE845F - 8: A6CC972273DAF3E8, 099BDEA86D5CB994285A7AB9BC59EAC7 - 9: 0ED1E78C9A39377377, C969C9583F3CCE5799630C5450BE9134 - 10: F68611B69D657B6D6DC4, 893C25068299C5F6305411E3A9199616 - 11: 7402BE21EEE415AA5438F8, 01916E4C573FF695CFEC41C7F29EA1CC - 12: 125918FFB1902AC3F4F81265, F3EA4E417E4DA6B8BDCCC8BD4E87FE27 - 13: 01C2E839EB6C4CFFFF4856C97C, B57A6FB6918F8E11113E449D75CF638F - 14: 708B33704EB6E379FEC223371C74, 44EC0A795B2E604D29B8E917A73EAC29 - 15: A45EEE44431E19F61B5E4D257B7BDD, E42E3A6D212B42595E39E5A6E14B0C43 - 16: F23AD7425EB8D3CE0FAFDCBEF52A1962, 5C6BD772DD1DE0070391A9BF63D0913D - 17: 9B40D36F988B6F105380C7C949EDB1F379, 78FC67EEC03CE078A72977801B75DA52 - 18: 9A894DFCA373610C48ED16149CE0D84E2939, D2E05400320F61FDAF1729F5505B513F - 19: 47CE7BBF27734E7C480CD4F9DD69F4B3E11223, 07C22A4DCCB71372A12ABB0ED2C5EAD3 - 20: 61F7F55DD6DC89472728E54C53CCC7034922EC7C, 490D005087FF9ACB5211FE2E40D3B5B7 - 21: DE27EBD9891828F422321C96BA900026F4033A1B98, E8C33743F34494061455F0F5A104F218 - 22: D73F22E0BBE04F9B7537DB5A8B35D9B978AC45B1DCA0, 3271FA71E989D845EEB7E76755A68CB0 - 23: F61DC254C28E7CEA0B526D9E4BF0E6C554A09251BC0BAA, FA74560634DDAD5F56B8842B2E49EFE8 - 24: 6155A4D65C03F0AB2665FC65408FDD29276C4D3B6E957CCE, E41DCA2C8D3601AD9C344BE53334F8A7 - 25: 9C4487CC097FF24A45502A9A3C0F7A2134235EDB2108ED470A, C28CB7100F45C6D87B0CE1682871761D - 26: 0CB17A181F579A62B28A1171B1C3AF8A275C8D99D6AF95A3514A, 33BB5B063092B223A40C310B98B8FDE9 - 27: A5D0455E5E4C3DE2009A774F055F5DDAFFDC89A25872E99DCB1E75, 19488A3644BBF9BB621E80ED45EB826D - 28: F4A054D11AD6B2A3A7F7A4EF40A09243373F4C151320464A0A9A9E06, 272D1709AA49838DEDA8F78D9878CD4F - 29: 83EFF58C64BFCD1CB5DD0F6D040B8ACFE6C8992E14605FCCCFF142D0AC, 5BE7739321D83A5E4CC9AB5FA6D56966 - 30: E12A3514CBF30326E5078B8117678823E6AFA8F3A78FEAF06C5B1508CEA0, 301B3BE76675FD30209EEA086BB40CD8 - 31: 77E2B65956B52BD90E90081F389BBFC8D4550FBCC74B6469C5CE98FC093A0F, C43272FD03A35AE4D9AF467CD7811F1D - 32: 77E116BE37F8153D717F3F19DEFD045C2E8CAC499295B9EE6A95A3509D4CBC47, A0406E2C09C510AB5A9E5A5B20B0C306 - -OCB-tea (16 byte key) - 0: , 1A6D3BE15B6C879D - 1: B5, 91A035C7871CCF11 - 2: AEB1, C715E399C46D9DD1 - 3: 2B3273, 2F8BD77A9E036FA5 - 4: 5C009E43, 1CDEEEA46EEAE63F - 5: 8E07B56FEB, 2A486014BEDC6B01 - 6: F2D5B9842DE7, 1734AB18A976BACB - 7: C49F333DFA40A8, 007BEE13E4B1151F - 8: 4A99C75688B0DBA8, 2BB62A22623A02B3 - 9: 1E1175070E0C9EBBE5, B9750E34056F00AF - 10: D066C7016D6458538A33, C8301F29178F512D - 11: 6B036FFB0C6636135ADC66, 48967AD3659260BA - 12: 3018AB281C87CA4185A53207, 4F043FB366001F3C - 13: 93DA80463817D8A43B5D59133C, E95DE5587B95E6AC - 14: C1389108A40292097F489603BF2D, 8E56A1F7B04194EB - 15: 36E512F52335419EB6DAD9CB9C40BC, F0498560CD814C62 - 16: 2381E281D648AFF1ABB7D65B9AE41B35, EEC952B027B9A81D - diff --git a/sources.cmake b/sources.cmake index 85cc37fde..0d3ef35e0 100644 --- a/sources.cmake +++ b/sources.cmake @@ -62,17 +62,6 @@ src/encauth/gcm/gcm_mult_h.c src/encauth/gcm/gcm_process.c src/encauth/gcm/gcm_reset.c src/encauth/gcm/gcm_test.c -src/encauth/ocb/ocb_decrypt.c -src/encauth/ocb/ocb_decrypt_verify_memory.c -src/encauth/ocb/ocb_done_decrypt.c -src/encauth/ocb/ocb_done_encrypt.c -src/encauth/ocb/ocb_encrypt.c -src/encauth/ocb/ocb_encrypt_authenticate_memory.c -src/encauth/ocb/ocb_init.c -src/encauth/ocb/ocb_ntz.c -src/encauth/ocb/ocb_shift_xor.c -src/encauth/ocb/ocb_test.c -src/encauth/ocb/s_ocb_done.c src/encauth/ocb3/ocb3_add_aad.c src/encauth/ocb3/ocb3_decrypt.c src/encauth/ocb3/ocb3_decrypt_last.c @@ -101,8 +90,14 @@ src/hashes/rmd160.c src/hashes/rmd256.c src/hashes/rmd320.c src/hashes/sha1.c +src/hashes/sha1_desc.c +src/hashes/sha1_x86.c src/hashes/sha2/sha224.c +src/hashes/sha2/sha224_desc.c +src/hashes/sha2/sha224_x86.c src/hashes/sha2/sha256.c +src/hashes/sha2/sha256_desc.c +src/hashes/sha2/sha256_x86.c src/hashes/sha2/sha384.c src/hashes/sha2/sha512.c src/hashes/sha2/sha512_224.c @@ -190,6 +185,7 @@ src/math/rand_bn.c src/math/rand_prime.c src/math/tfm_desc.c src/misc/adler32.c +src/misc/argon2/argon2.c src/misc/base16/base16_decode.c src/misc/base16/base16_encode.c src/misc/base32/base32_decode.c @@ -252,6 +248,7 @@ src/misc/pkcs12/pkcs12_utf8_to_utf16.c src/misc/pkcs5/pkcs_5_1.c src/misc/pkcs5/pkcs_5_2.c src/misc/pkcs5/pkcs_5_test.c +src/misc/scrypt/scrypt.c src/misc/ssh/ssh_decode_sequence_multi.c src/misc/ssh/ssh_encode_sequence_multi.c src/misc/zeromem.c @@ -406,6 +403,10 @@ src/pk/ec25519/ec25519_crypto_ctx.c src/pk/ec25519/ec25519_export.c src/pk/ec25519/ec25519_import_pkcs8.c src/pk/ec25519/tweetnacl.c +src/pk/ec448/ec448_common.c +src/pk/ec448/ec448_crypto_ctx.c +src/pk/ec448/ec448_export.c +src/pk/ec448/ec448_import_pkcs8.c src/pk/ecc/ecc.c src/pk/ecc/ecc_ansi_x963_export.c src/pk/ecc/ecc_ansi_x963_import.c @@ -463,6 +464,14 @@ src/pk/ed25519/ed25519_import_x509.c src/pk/ed25519/ed25519_make_key.c src/pk/ed25519/ed25519_sign.c src/pk/ed25519/ed25519_verify.c +src/pk/ed448/ed448_export.c +src/pk/ed448/ed448_import.c +src/pk/ed448/ed448_import_pkcs8.c +src/pk/ed448/ed448_import_raw.c +src/pk/ed448/ed448_import_x509.c +src/pk/ed448/ed448_make_key.c +src/pk/ed448/ed448_sign.c +src/pk/ed448/ed448_verify.c src/pk/pka_key.c src/pk/pkcs1/pkcs_1_i2osp.c src/pk/pkcs1/pkcs_1_mgf1.c @@ -494,6 +503,13 @@ src/pk/x25519/x25519_import_raw.c src/pk/x25519/x25519_import_x509.c src/pk/x25519/x25519_make_key.c src/pk/x25519/x25519_shared_secret.c +src/pk/x448/x448_export.c +src/pk/x448/x448_import.c +src/pk/x448/x448_import_pkcs8.c +src/pk/x448/x448_import_raw.c +src/pk/x448/x448_import_x509.c +src/pk/x448/x448_make_key.c +src/pk/x448/x448_shared_secret.c src/prngs/chacha20.c src/prngs/fortuna.c src/prngs/rc4.c @@ -510,6 +526,9 @@ src/stream/chacha/chacha_keystream.c src/stream/chacha/chacha_memory.c src/stream/chacha/chacha_setup.c src/stream/chacha/chacha_test.c +src/stream/chacha/xchacha20_memory.c +src/stream/chacha/xchacha20_setup.c +src/stream/chacha/xchacha20_test.c src/stream/rabbit/rabbit.c src/stream/rabbit/rabbit_memory.c src/stream/rc4/rc4_stream.c diff --git a/src/ciphers/aes/aes_desc.c b/src/ciphers/aes/aes_desc.c index 2ff913e83..c03e1bb36 100644 --- a/src/ciphers/aes/aes_desc.c +++ b/src/ciphers/aes/aes_desc.c @@ -9,6 +9,60 @@ #include "tomcrypt_private.h" +#if defined(LTC_ARCH_X86) && (defined(LTC_AES_NI) || !defined(ENCRYPT_ONLY)) + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_aesni_is_supported(void) +{ + static int initialized = 0, is_supported = 0; + + if (initialized == 0) { + /* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI) + * EAX = 1, ECX = 0 + */ + int regs[4]; + s_x86_cpuid(regs, 1); + is_supported = ((regs[2] >> 19) & 1) && ((regs[2] >> 25) & 1); + initialized = 1; + } + + return is_supported; +} +#endif /* LTC_ARCH_X86 */ + +#ifndef ENCRYPT_ONLY +int aesni_is_supported(void) +{ +#if defined(LTC_ARCH_X86) + return s_aesni_is_supported(); +#else + return 0; +#endif +} +#endif /* ENCRYPT_ONLY */ + #if defined(LTC_RIJNDAEL) #ifndef ENCRYPT_ONLY @@ -46,54 +100,6 @@ const struct ltc_cipher_descriptor aes_enc_desc = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -#endif - -/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */ -#if defined(LTC_AES_NI) -static LTC_INLINE int s_aesni_is_supported(void) -{ - static int initialized = 0, is_supported = 0; - - if (initialized == 0) { - int a, b, c, d; - - /* Look for CPUID.1.0.ECX[19] (SSE4.1) and CPUID.1.0.ECX[25] (AES-NI) - * EAX = 1, ECX = 0 - */ - a = 1; - c = 0; - -#if defined(_MSC_VER) && !defined(__clang__) - int arr[4]; - __cpuidex(arr, a, c); - a = arr[0]; - b = arr[1]; - c = arr[2]; - d = arr[3]; -#else - __asm__ volatile ("cpuid" - :"=a"(a), "=b"(b), "=c"(c), "=d"(d) - :"a"(a), "c"(c) - ); -#endif - - is_supported = ((c >> 19) & 1) && ((c >> 25) & 1); - initialized = 1; - } - - return is_supported; -} -#endif - -#ifndef ENCRYPT_ONLY -int aesni_is_supported(void) -{ -#ifdef LTC_AES_NI - return s_aesni_is_supported(); -#else - return 0; -#endif -} #endif /** diff --git a/src/ciphers/aes/aesni.c b/src/ciphers/aes/aesni.c index d74722919..c4b981dda 100644 --- a/src/ciphers/aes/aesni.c +++ b/src/ciphers/aes/aesni.c @@ -20,9 +20,17 @@ const struct ltc_cipher_descriptor aesni_desc = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#endif #include #include #include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif #define setup_mix(t, c) _mm_extract_epi32(_mm_aeskeygenassist_si128(t, 0), c) #define temp_load(k) _mm_loadu_si128((__m128i*)(k)) diff --git a/src/encauth/chachapoly/chacha20poly1305_setiv.c b/src/encauth/chachapoly/chacha20poly1305_setiv.c index d5ec3e692..e5937b41c 100644 --- a/src/encauth/chachapoly/chacha20poly1305_setiv.c +++ b/src/encauth/chachapoly/chacha20poly1305_setiv.c @@ -9,7 +9,7 @@ Set IV + counter data to the ChaCha20Poly1305 state and reset the context @param st The ChaCha20Poly1305 state @param iv The IV data to add - @param ivlen The length of the IV (must be 12 or 8) + @param ivlen The length of the IV (must be 12 or 8, or 24 when LTC_XCHACHA20 is enabled) @return CRYPT_OK on success */ int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen) @@ -20,7 +20,62 @@ int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, LTC_ARGCHK(st != NULL); LTC_ARGCHK(iv != NULL); +#ifdef LTC_XCHACHA20 + LTC_ARGCHK(ivlen == 12 || ivlen == 8 || ivlen == 24); +#else LTC_ARGCHK(ivlen == 12 || ivlen == 8); +#endif + +#ifdef LTC_XCHACHA20 + if (ivlen == 24) { + unsigned char orig_key[32]; + + /* extract the original key from state (stored by chacha_setup via chacha20poly1305_init) */ + STORE32L(st->chacha.input[4], orig_key + 0); + STORE32L(st->chacha.input[5], orig_key + 4); + STORE32L(st->chacha.input[6], orig_key + 8); + STORE32L(st->chacha.input[7], orig_key + 12); + STORE32L(st->chacha.input[8], orig_key + 16); + STORE32L(st->chacha.input[9], orig_key + 20); + STORE32L(st->chacha.input[10], orig_key + 24); + STORE32L(st->chacha.input[11], orig_key + 28); + + /* derive subkey via HChaCha20 and set up state with counter=0 */ + if ((err = xchacha20_setup(&st->chacha, orig_key, 32, iv, 24, 20)) != CRYPT_OK) { + zeromem(orig_key, sizeof(orig_key)); + return err; + } + + /* copy state to temporary for Poly1305 key derivation (counter=0) */ + for (i = 0; i < 16; i++) tmp_st.input[i] = st->chacha.input[i]; + tmp_st.input[12] = 0; + tmp_st.rounds = st->chacha.rounds; + tmp_st.ksleft = 0; + tmp_st.ivlen = 12; /* use IETF counter mode for keystream generation */ + + /* generate Poly1305 key from block 0 */ + if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) { + zeromem(orig_key, sizeof(orig_key)); + return err; + } + + /* set main state counter to 1 for encryption */ + st->chacha.input[12] = 1; + st->chacha.ksleft = 0; + + /* initialize Poly1305 */ + if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) { + zeromem(orig_key, sizeof(orig_key)); + return err; + } + st->ctlen = 0; + st->aadlen = 0; + st->aadflg = 1; + + zeromem(orig_key, sizeof(orig_key)); + return CRYPT_OK; + } +#endif /* set IV for chacha20 */ if (ivlen == 12) { diff --git a/src/encauth/chachapoly/chacha20poly1305_test.c b/src/encauth/chachapoly/chacha20poly1305_test.c index f6f9c130b..902985c30 100644 --- a/src/encauth/chachapoly/chacha20poly1305_test.c +++ b/src/encauth/chachapoly/chacha20poly1305_test.c @@ -152,6 +152,71 @@ int chacha20poly1305_test(void) } } +#ifdef LTC_XCHACHA20 + /* XChaCha20-Poly1305 AEAD test (draft-irtf-cfrg-xchacha, Appendix A.3.1) */ + { + unsigned char xk[] = { 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f }; + unsigned char xi24[] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b, + 0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 }; + unsigned char xaad[] = { 0x50,0x51,0x52,0x53,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7 }; + unsigned char xpt[] = { 0x4c,0x61,0x64,0x69,0x65,0x73,0x20,0x61,0x6e,0x64,0x20,0x47,0x65,0x6e,0x74,0x6c, + 0x65,0x6d,0x65,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x63,0x6c,0x61,0x73, + 0x73,0x20,0x6f,0x66,0x20,0x27,0x39,0x39,0x3a,0x20,0x49,0x66,0x20,0x49,0x20,0x63, + 0x6f,0x75,0x6c,0x64,0x20,0x6f,0x66,0x66,0x65,0x72,0x20,0x79,0x6f,0x75,0x20,0x6f, + 0x6e,0x6c,0x79,0x20,0x6f,0x6e,0x65,0x20,0x74,0x69,0x70,0x20,0x66,0x6f,0x72,0x20, + 0x74,0x68,0x65,0x20,0x66,0x75,0x74,0x75,0x72,0x65,0x2c,0x20,0x73,0x75,0x6e,0x73, + 0x63,0x72,0x65,0x65,0x6e,0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x62,0x65,0x20,0x69, + 0x74,0x2e }; + unsigned char xenc[] = { 0xbd,0x6d,0x17,0x9d,0x3e,0x83,0xd4,0x3b,0x95,0x76,0x57,0x94,0x93,0xc0,0xe9,0x39, + 0x57,0x2a,0x17,0x00,0x25,0x2b,0xfa,0xcc,0xbe,0xd2,0x90,0x2c,0x21,0x39,0x6c,0xbb, + 0x73,0x1c,0x7f,0x1b,0x0b,0x4a,0xa6,0x44,0x0b,0xf3,0xa8,0x2f,0x4e,0xda,0x7e,0x39, + 0xae,0x64,0xc6,0x70,0x8c,0x54,0xc2,0x16,0xcb,0x96,0xb7,0x2e,0x12,0x13,0xb4,0x52, + 0x2f,0x8c,0x9b,0xa4,0x0d,0xb5,0xd9,0x45,0xb1,0x1b,0x69,0xb9,0x82,0xc1,0xbb,0x9e, + 0x3f,0x3f,0xac,0x2b,0xc3,0x69,0x48,0x8f,0x76,0xb2,0x38,0x35,0x65,0xd3,0xff,0xf9, + 0x21,0xf9,0x66,0x4c,0x97,0x63,0x7d,0xa9,0x76,0x88,0x12,0xf6,0x15,0xc6,0x8b,0x13, + 0xb5,0x2e }; + unsigned char xtag[] = { 0xc0,0x87,0x59,0x24,0xc1,0xc7,0x98,0x79,0x47,0xde,0xaf,0xd8,0x78,0x0a,0xcf,0x49 }; + unsigned long xptlen = sizeof(xpt); + + /* encrypt with incremental API */ + if ((err = chacha20poly1305_init(&st1, xk, sizeof(xk))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_setiv(&st1, xi24, sizeof(xi24))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_add_aad(&st1, xaad, sizeof(xaad))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_encrypt(&st1, xpt, xptlen, ct)) != CRYPT_OK) return err; + len = sizeof(emac); + if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(ct, xptlen, xenc, sizeof(xenc), "XCHACHA20POLY1305-ENC-CT", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + if (ltc_compare_testvector(emac, len, xtag, sizeof(xtag), "XCHACHA20POLY1305-ENC-TAG", 2) != 0) return CRYPT_FAIL_TESTVECTOR; + + /* decrypt with incremental API */ + if ((err = chacha20poly1305_init(&st2, xk, sizeof(xk))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_setiv(&st2, xi24, sizeof(xi24))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_add_aad(&st2, xaad, sizeof(xaad))) != CRYPT_OK) return err; + if ((err = chacha20poly1305_decrypt(&st2, ct, xptlen, pt)) != CRYPT_OK) return err; + len = sizeof(dmac); + if ((err = chacha20poly1305_done(&st2, dmac, &len)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(pt, xptlen, xpt, xptlen, "XCHACHA20POLY1305-DEC-PT", 3) != 0) return CRYPT_FAIL_TESTVECTOR; + if (ltc_compare_testvector(dmac, len, xtag, sizeof(xtag), "XCHACHA20POLY1305-DEC-TAG", 4) != 0) return CRYPT_FAIL_TESTVECTOR; + + /* chacha20poly1305_memory - encrypt with 24-byte IV */ + len = sizeof(emac); + if ((err = chacha20poly1305_memory(xk, sizeof(xk), xi24, sizeof(xi24), xaad, sizeof(xaad), xpt, + xptlen, ct, emac, &len, CHACHA20POLY1305_ENCRYPT)) != CRYPT_OK) return err; + if (ltc_compare_testvector(ct, xptlen, xenc, sizeof(xenc), "XCHACHA20POLY1305-MEM-CT", 1) != 0) return CRYPT_FAIL_TESTVECTOR; + if (ltc_compare_testvector(emac, len, xtag, sizeof(xtag), "XCHACHA20POLY1305-MEM-TAG", 2) != 0) return CRYPT_FAIL_TESTVECTOR; + + /* chacha20poly1305_memory - decrypt with 24-byte IV */ + len = sizeof(dmac); + XMEMCPY(dmac, xtag, sizeof(xtag)); + if ((err = chacha20poly1305_memory(xk, sizeof(xk), xi24, sizeof(xi24), xaad, sizeof(xaad), + ct, xptlen, pt, dmac, &len, CHACHA20POLY1305_DECRYPT)) != CRYPT_OK) return err; + if (ltc_compare_testvector(pt, xptlen, xpt, xptlen, "XCHACHA20POLY1305-MEM-PT", 3) != 0) return CRYPT_FAIL_TESTVECTOR; + } +#endif + return CRYPT_OK; #endif } diff --git a/src/encauth/gcm/gcm_gf_mult.c b/src/encauth/gcm/gcm_gf_mult.c index f2669ec84..778ce2da4 100644 --- a/src/encauth/gcm/gcm_gf_mult.c +++ b/src/encauth/gcm/gcm_gf_mult.c @@ -7,6 +7,259 @@ */ #include "tomcrypt_private.h" +#if defined(LTC_GCM_MODE) || defined(LTC_LRW_MODE) +#if defined(LTC_GCM_PCLMUL) + +#define LTC_GCM_PCLMUL_TARGET LTC_ATTRIBUTE((__target__("pclmul,ssse3"))) + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#endif +#if defined(_MSC_VER) +#include +#else +#include +#endif +#include +#include +#include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_pclmul_is_supported(void) +{ + static int initialized = 0, is_supported = 0; + + if (initialized == 0) { + int regs[4]; + s_x86_cpuid(regs, 1); + /* Test CPUID.1.0.ECX[1] (PCLMUL) and CPUID.1.0.ECX[9] (SSSE3) */ + is_supported = ((regs[2] >> 1) & 1) && ((regs[2] >> 9) & 1); + initialized = 1; + } + + return is_supported; +} + +/* + * 128x128-bit binary polynomial multiplication for Intel x86 and x86_64 + * Based on "Intel Carry-Less Multiplication Instruction and its Usage for + * Computing the GCM Mode", Shay Gueron, Michael E. Kounavis + * https://cdrdv2-public.intel.com/836172/clmul-wp-rev-2-02-2014-04-20.pdf + */ +LTC_GCM_PCLMUL_TARGET +static void s_gfmul_pclmul(__m128i a, __m128i b, __m128i *res){ + /* Page 25. Figure 5. Code Sample - Performing Ghash Using Algorithms 1 and 5 (C) */ + __m128i /*tmp0, tmp1,*/ tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + tmp3 = _mm_clmulepi64_si128(a, b, 0x00); + tmp4 = _mm_clmulepi64_si128(a, b, 0x10); + tmp5 = _mm_clmulepi64_si128(a, b, 0x01); + tmp6 = _mm_clmulepi64_si128(a, b, 0x11); + tmp4 = _mm_xor_si128(tmp4, tmp5); + tmp5 = _mm_slli_si128(tmp4, 8); + tmp4 = _mm_srli_si128(tmp4, 8); + tmp3 = _mm_xor_si128(tmp3, tmp5); + tmp6 = _mm_xor_si128(tmp6, tmp4); + tmp7 = _mm_srli_epi32(tmp3, 31); + tmp8 = _mm_srli_epi32(tmp6, 31); + tmp3 = _mm_slli_epi32(tmp3, 1); + tmp6 = _mm_slli_epi32(tmp6, 1); + tmp9 = _mm_srli_si128(tmp7, 12); + tmp8 = _mm_slli_si128(tmp8, 4); + tmp7 = _mm_slli_si128(tmp7, 4); + tmp3 = _mm_or_si128(tmp3, tmp7); + tmp6 = _mm_or_si128(tmp6, tmp8); + tmp6 = _mm_or_si128(tmp6, tmp9); + tmp7 = _mm_slli_epi32(tmp3, 31); + tmp8 = _mm_slli_epi32(tmp3, 30); + tmp9 = _mm_slli_epi32(tmp3, 25); + tmp7 = _mm_xor_si128(tmp7, tmp8); + tmp7 = _mm_xor_si128(tmp7, tmp9); + tmp8 = _mm_srli_si128(tmp7, 4); + tmp7 = _mm_slli_si128(tmp7, 12); + tmp3 = _mm_xor_si128(tmp3, tmp7); + tmp2 = _mm_srli_epi32(tmp3, 1); + tmp4 = _mm_srli_epi32(tmp3, 2); + tmp5 = _mm_srli_epi32(tmp3, 7); + tmp2 = _mm_xor_si128(tmp2, tmp4); + tmp2 = _mm_xor_si128(tmp2, tmp5); + tmp2 = _mm_xor_si128(tmp2, tmp8); + tmp3 = _mm_xor_si128(tmp3, tmp2); + tmp6 = _mm_xor_si128(tmp6, tmp3); + *res = tmp6; +} + +LTC_GCM_PCLMUL_TARGET +static void s_gcm_gf_mult_pclmul(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + __m128i ci; + __m128i BSWAP_MASK = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + __m128i ai = _mm_loadu_si128((const __m128i *) a); + __m128i bi = _mm_loadu_si128((const __m128i *) b); + + ai = _mm_shuffle_epi8(ai, BSWAP_MASK); + bi = _mm_shuffle_epi8(bi, BSWAP_MASK); + + s_gfmul_pclmul(ai, bi, &ci); + + ci = _mm_shuffle_epi8(ci, BSWAP_MASK); + + XMEMCPY(c, &ci, sizeof(ci)); +} +#endif /* defined(LTC_GCM_PCLMUL) */ + +#if defined(LTC_GCM_PMULL) +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wbad-function-cast" +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wmissing-braces" +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif +#include +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +#if defined(__APPLE__) +#include +#elif defined(_WIN32) +#include +#elif defined(__linux__) +#include +#include +#elif defined(__FreeBSD__) +#include +#endif + +static LTC_INLINE int s_pmull_is_supported(void) +{ + static int initialized = 0, is_supported = 0; + + if (initialized == 0) { +#if defined(__APPLE__) + int val = 0; + size_t len = sizeof(val); + if (sysctlbyname("hw.optional.arm.FEAT_PMULL", &val, &len, NULL, 0) == 0) { + is_supported = (val != 0); + } +#elif defined (_WIN32) + is_supported = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); +#elif defined(__linux__) + unsigned long hwcaps = getauxval(AT_HWCAP); + is_supported = (hwcaps & HWCAP_PMULL); +#elif defined(__FreeBSD__) + unsigned long hwcaps = 0; + if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) == 0) { + is_supported = (hwcaps & HWCAP_PMULL) != 0; + } +#endif + initialized = 1; + } + + return is_supported; +} + +/* + * 128x128-bit binary polynomial multiplication for AArch64 using PMULL/PMULL2 + * Based on "Implementing GCM on ARMv8", Conrado P. L. Gouvea and Julio Lopez + * https://conradoplg.modp.net/files/2010/12/gcm14.pdf + */ +#if defined(_MSC_VER) +#define GET_LOW_P64(x) vreinterpret_p64_u64(vcreate_u64((uint64_t)vgetq_lane_p64((x), 0))) +#else +#define GET_LOW_P64(x) vgetq_lane_p64((x), 0) +#endif + +LTC_GCM_PMULL_TARGET +static void s_gfmul_pmull(uint8x16_t a, uint8x16_t b, uint8x16_t *res) { + uint8x16_t r0, r1, t0, t1, z, p; + poly64x2_t pa, pb, pt0, pr1, pp; + + z = vdupq_n_u8(0); + + pa = vreinterpretq_p64_u8(a); + pb = vreinterpretq_p64_u8(b); + + /* Page 7. Algorithm 3 128 x 128-bit binary polynomial multiplier for ARMv8 AArch64 (PMULL) */ + r0 = vreinterpretq_u8_p128(vmull_p64(GET_LOW_P64(pa), GET_LOW_P64(pb))); + r1 = vreinterpretq_u8_p128(vmull_high_p64(pa, pb)); + t0 = vextq_u8(b, b, 8); + pt0 = vreinterpretq_p64_u8(t0); + + t1 = vreinterpretq_u8_p128(vmull_p64(GET_LOW_P64(pa), GET_LOW_P64(pt0))); + t0 = vreinterpretq_u8_p128(vmull_high_p64(pa, pt0)); + t0 = veorq_u8(t0, t1); + t1 = vextq_u8(z, t0, 8); + r0 = veorq_u8(r0, t1); + t1 = vextq_u8(t0, z, 8); + r1 = veorq_u8(r1, t1); + + /* Page 8. Algorithm 5 256-bit to 128-bit GCM polynomial reduction for ARMv8 AAarch64 using PMULL */ + p = vreinterpretq_u8_u64(vdupq_n_u64(0x0000000000000087ULL)); + pp = vreinterpretq_p64_u8(p); + pr1 = vreinterpretq_p64_u8(r1); + t0 = vreinterpretq_u8_p128(vmull_high_p64(pr1, pp)); + t1 = vextq_u8(t0, z, 8); + r1 = veorq_u8(r1, t1); + t1 = vextq_u8(z, t0, 8); + r0 = veorq_u8(r0, t1); + pr1 = vreinterpretq_p64_u8(r1); + + t0 = vreinterpretq_u8_p128(vmull_p64(GET_LOW_P64(pr1), GET_LOW_P64(pp))); + a = veorq_u8(r0, t0); + + *res = a; +} + +LTC_GCM_PMULL_TARGET +static void s_gcm_gf_mult_pmull(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ + uint8x16_t va, vb, vc; + + va = vld1q_u8(a); + vb = vld1q_u8(b); + va = vrbitq_u8(va); + vb = vrbitq_u8(vb); + + s_gfmul_pmull(va, vb, &vc); + + vc = vrbitq_u8(vc); + + XMEMCPY(c, &vc, sizeof(vc)); +} + +#endif /* defined(LTC_GCM_PMULL) */ +#endif /* defined(LTC_GCM_MODE) || defined(LTC_LRW_MODE) */ + #if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || (defined(LTC_GCM_MODE) && defined(LTC_FAST)) /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the @@ -50,6 +303,7 @@ const unsigned char gcm_shift_table[256*2] = { #if defined(LTC_GCM_MODE) || defined(LTC_LRW_MODE) + #ifndef LTC_FAST /* right shift */ static void s_gcm_rightshift(unsigned char *a) @@ -72,7 +326,7 @@ static const unsigned char poly[] = { 0x00, 0xE1 }; @param b Second value @param c Destination for a * b */ -void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +static void s_gcm_gf_mult_sw(const unsigned char *a, const unsigned char *b, unsigned char *c) { unsigned char Z[16], V[16]; unsigned char x, y, z; @@ -106,7 +360,7 @@ void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char * @param b Second value @param c Destination for a * b */ -void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +static void s_gcm_gf_mult_sw(const unsigned char *a, const unsigned char *b, unsigned char *c) { int i, j, k, u; LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z; @@ -209,5 +463,29 @@ void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char * #endif +/** + GCM GF multiplier (internal use only) + @param a First value + @param b Second value + @param c Destination for a * b + */ +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) +{ +#if defined(LTC_GCM_PCLMUL) + if(s_pclmul_is_supported()) { + s_gcm_gf_mult_pclmul(a, b, c); + return; + } +#endif +#if defined(LTC_GCM_PMULL) + if(s_pmull_is_supported()) { + s_gcm_gf_mult_pmull(a, b, c); + return; + } +#endif + s_gcm_gf_mult_sw(a, b, c); +} + + #endif diff --git a/src/encauth/ocb/ocb_decrypt.c b/src/encauth/ocb/ocb_decrypt.c deleted file mode 100644 index 98f36e48a..000000000 --- a/src/encauth/ocb/ocb_decrypt.c +++ /dev/null @@ -1,59 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_decrypt.c - OCB implementation, decrypt data, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Decrypt a block with OCB. - @param ocb The OCB state - @param ct The ciphertext (length of the block size of the block cipher) - @param pt [out] The plaintext (length of ct) - @return CRYPT_OK if successful -*/ -int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) -{ - unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; - int err, x; - - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - - /* can't use a encrypt-only descriptor */ - LTC_ARGCHK(cipher_descriptor[ocb->key.cipher].ecb_decrypt != NULL); - - /* Get Z[i] value */ - ocb_shift_xor(ocb, Z); - - /* xor ct in, encrypt, xor Z out */ - for (x = 0; x < ocb->block_len; x++) { - tmp[x] = ct[x] ^ Z[x]; - } - if ((err = ecb_decrypt_block(tmp, pt, &ocb->key)) != CRYPT_OK) { - return err; - } - for (x = 0; x < ocb->block_len; x++) { - pt[x] ^= Z[x]; - } - - /* compute checksum */ - for (x = 0; x < ocb->block_len; x++) { - ocb->checksum[x] ^= pt[x]; - } - - -#ifdef LTC_CLEAN_STACK - zeromem(Z, sizeof(Z)); - zeromem(tmp, sizeof(tmp)); -#endif - return CRYPT_OK; -} - -#endif - diff --git a/src/encauth/ocb/ocb_decrypt_verify_memory.c b/src/encauth/ocb/ocb_decrypt_verify_memory.c deleted file mode 100644 index 0f4dcb78a..000000000 --- a/src/encauth/ocb/ocb_decrypt_verify_memory.c +++ /dev/null @@ -1,74 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_decrypt_verify_memory.c - OCB implementation, helper to decrypt block of memory, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Decrypt and compare the tag with OCB. - @param cipher The index of the cipher desired - @param key The secret key - @param keylen The length of the secret key (octets) - @param nonce The session nonce (length of the block size of the block cipher) - @param ct The ciphertext - @param ctlen The length of the ciphertext (octets) - @param pt [out] The plaintext - @param tag The tag to compare against - @param taglen The length of the tag (octets) - @param stat [out] The result of the tag comparison (1==valid, 0==invalid) - @return CRYPT_OK if successful regardless of the tag comparison -*/ -int ocb_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, - int *stat) -{ - int err; - ocb_state *ocb; - - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(nonce != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); - LTC_ARGCHK(stat != NULL); - - /* allocate memory */ - ocb = XMALLOC(sizeof(ocb_state)); - if (ocb == NULL) { - return CRYPT_MEM; - } - - if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { - goto LBL_ERR; - } - - while (ctlen > (unsigned long)ocb->block_len) { - if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) { - goto LBL_ERR; - } - ctlen -= ocb->block_len; - pt += ocb->block_len; - ct += ocb->block_len; - } - - err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat); -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(ocb, sizeof(ocb_state)); -#endif - - XFREE(ocb); - - return err; -} - -#endif diff --git a/src/encauth/ocb/ocb_done_decrypt.c b/src/encauth/ocb/ocb_done_decrypt.c deleted file mode 100644 index 3d516c9b9..000000000 --- a/src/encauth/ocb/ocb_done_decrypt.c +++ /dev/null @@ -1,68 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_done_decrypt.c - OCB implementation, terminate decryption, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Terminate a decrypting OCB state - @param ocb The OCB state - @param ct The ciphertext (if any) - @param ctlen The length of the ciphertext (octets) - @param pt [out] The plaintext - @param tag The authentication tag (to compare against) - @param taglen The length of the authentication tag provided - @param stat [out] The result of the tag comparison - @return CRYPT_OK if the process was successful regardless if the tag is valid -*/ -int ocb_done_decrypt(ocb_state *ocb, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, int *stat) -{ - int err; - unsigned char *tagbuf; - unsigned long tagbuflen; - - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); - LTC_ARGCHK(stat != NULL); - - /* default to failed */ - *stat = 0; - - /* allocate memory */ - tagbuf = XMALLOC(MAXBLOCKSIZE); - if (tagbuf == NULL) { - return CRYPT_MEM; - } - - tagbuflen = MAXBLOCKSIZE; - if ((err = s_ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) { - goto LBL_ERR; - } - - if (taglen <= tagbuflen && XMEM_NEQ(tagbuf, tag, taglen) == 0) { - *stat = 1; - } - - err = CRYPT_OK; -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(tagbuf, MAXBLOCKSIZE); -#endif - - XFREE(tagbuf); - - return err; -} - -#endif - diff --git a/src/encauth/ocb/ocb_done_encrypt.c b/src/encauth/ocb/ocb_done_encrypt.c deleted file mode 100644 index 5cd39adc4..000000000 --- a/src/encauth/ocb/ocb_done_encrypt.c +++ /dev/null @@ -1,34 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_done_encrypt.c - OCB implementation, terminate encryption, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Terminate an encryption OCB state - @param ocb The OCB state - @param pt Remaining plaintext (if any) - @param ptlen The length of the plaintext (octets) - @param ct [out] The ciphertext (if any) - @param tag [out] The tag for the OCB stream - @param taglen [in/out] The max size and resulting size of the tag - @return CRYPT_OK if successful -*/ -int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, unsigned char *tag, unsigned long *taglen) -{ - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); - LTC_ARGCHK(taglen != NULL); - return s_ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0); -} - -#endif - diff --git a/src/encauth/ocb/ocb_encrypt.c b/src/encauth/ocb/ocb_encrypt.c deleted file mode 100644 index a38765a7b..000000000 --- a/src/encauth/ocb/ocb_encrypt.c +++ /dev/null @@ -1,54 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_encrypt.c - OCB implementation, encrypt data, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Encrypt a block of data with OCB. - @param ocb The OCB state - @param pt The plaintext (length of the block size of the block cipher) - @param ct [out] The ciphertext (same size as the pt) - @return CRYPT_OK if successful -*/ -int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) -{ - unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; - int err, x; - - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - - /* compute checksum */ - for (x = 0; x < ocb->block_len; x++) { - ocb->checksum[x] ^= pt[x]; - } - - /* Get Z[i] value */ - ocb_shift_xor(ocb, Z); - - /* xor pt in, encrypt, xor Z out */ - for (x = 0; x < ocb->block_len; x++) { - tmp[x] = pt[x] ^ Z[x]; - } - if ((err = ecb_encrypt_block(tmp, ct, &ocb->key)) != CRYPT_OK) { - return err; - } - for (x = 0; x < ocb->block_len; x++) { - ct[x] ^= Z[x]; - } - -#ifdef LTC_CLEAN_STACK - zeromem(Z, sizeof(Z)); - zeromem(tmp, sizeof(tmp)); -#endif - return CRYPT_OK; -} - -#endif diff --git a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c deleted file mode 100644 index 7560a6e71..000000000 --- a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c +++ /dev/null @@ -1,72 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_encrypt_authenticate_memory.c - OCB implementation, encrypt block of memory, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Encrypt and generate an authentication code for a buffer of memory - @param cipher The index of the cipher desired - @param key The secret key - @param keylen The length of the secret key (octets) - @param nonce The session nonce (length of the block ciphers block size) - @param pt The plaintext - @param ptlen The length of the plaintext (octets) - @param ct [out] The ciphertext - @param tag [out] The authentication tag - @param taglen [in/out] The max size and resulting size of the authentication tag - @return CRYPT_OK if successful -*/ -int ocb_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen) -{ - int err; - ocb_state *ocb; - - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(nonce != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); - LTC_ARGCHK(taglen != NULL); - - /* allocate ram */ - ocb = XMALLOC(sizeof(ocb_state)); - if (ocb == NULL) { - return CRYPT_MEM; - } - - if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { - goto LBL_ERR; - } - - while (ptlen > (unsigned long)ocb->block_len) { - if ((err = ocb_encrypt(ocb, pt, ct)) != CRYPT_OK) { - goto LBL_ERR; - } - ptlen -= ocb->block_len; - pt += ocb->block_len; - ct += ocb->block_len; - } - - err = ocb_done_encrypt(ocb, pt, ptlen, ct, tag, taglen); -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(ocb, sizeof(ocb_state)); -#endif - - XFREE(ocb); - - return err; -} - -#endif diff --git a/src/encauth/ocb/ocb_init.c b/src/encauth/ocb/ocb_init.c deleted file mode 100644 index 9460e4044..000000000 --- a/src/encauth/ocb/ocb_init.c +++ /dev/null @@ -1,131 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_init.c - OCB implementation, initialize state, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -#define polys ocb_polys -static const struct { - int len; - unsigned char poly_div[MAXBLOCKSIZE], - poly_mul[MAXBLOCKSIZE]; -} polys[] = { -{ - 8, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } -}, { - 16, - { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } -} -}; - -/** - Initialize an OCB context. - @param ocb [out] The destination of the OCB state - @param cipher The index of the desired cipher - @param key The secret key - @param keylen The length of the secret key (octets) - @param nonce The session nonce (length of the block size of the cipher) - @return CRYPT_OK if successful -*/ -int ocb_init(ocb_state *ocb, int cipher, - const unsigned char *key, unsigned long keylen, const unsigned char *nonce) -{ - int poly, x, y, m, err; - - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(nonce != NULL); - - /* valid cipher? */ - if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { - return err; - } - - /* determine which polys to use */ - ocb->block_len = cipher_descriptor[cipher].block_length; - x = (int)LTC_ARRAY_SIZE(polys); - for (poly = 0; poly < x; poly++) { - if (polys[poly].len == ocb->block_len) { - break; - } - } - if (poly == x) { - return CRYPT_INVALID_ARG; /* block_len not found in polys */ - } - if (polys[poly].len != ocb->block_len) { - return CRYPT_INVALID_ARG; - } - - /* schedule the key */ - if ((err = ecb_start(cipher, key, keylen, 0, &ocb->key)) != CRYPT_OK) { - return err; - } - - /* find L = E[0] */ - zeromem(ocb->L, ocb->block_len); - if ((err = ecb_encrypt_block(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { - return err; - } - - /* find R = E[N xor L] */ - for (x = 0; x < ocb->block_len; x++) { - ocb->R[x] = ocb->L[x] ^ nonce[x]; - } - if ((err = ecb_encrypt_block(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { - return err; - } - - /* find Ls[i] = L << i for i == 0..31 */ - XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); - for (x = 1; x < 32; x++) { - m = ocb->Ls[x-1][0] >> 7; - for (y = 0; y < ocb->block_len-1; y++) { - ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; - } - ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; - - if (m == 1) { - for (y = 0; y < ocb->block_len; y++) { - ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; - } - } - } - - /* find Lr = L / x */ - m = ocb->L[ocb->block_len-1] & 1; - - /* shift right */ - for (x = ocb->block_len - 1; x > 0; x--) { - ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; - } - ocb->Lr[0] = ocb->L[0] >> 1; - - if (m == 1) { - for (x = 0; x < ocb->block_len; x++) { - ocb->Lr[x] ^= polys[poly].poly_div[x]; - } - } - - /* set Li, checksum */ - zeromem(ocb->Li, ocb->block_len); - zeromem(ocb->checksum, ocb->block_len); - - /* set other params */ - ocb->block_index = 1; - - return CRYPT_OK; -} - -#undef polys - -#endif diff --git a/src/encauth/ocb/ocb_ntz.c b/src/encauth/ocb/ocb_ntz.c deleted file mode 100644 index bf933fd94..000000000 --- a/src/encauth/ocb/ocb_ntz.c +++ /dev/null @@ -1,36 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_ntz.c - OCB implementation, internal function, by Tom St Denis -*/ - -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Returns the number of leading zero bits [from lsb up] - @param x The 32-bit value to observe - @return The number of bits [from the lsb up] that are zero -*/ -int ocb_ntz(unsigned long x) -{ -#if defined(LTC_HAVE_CTZL_BUILTIN) - if (x == 0) - return sizeof(unsigned long) * CHAR_BIT; - return __builtin_ctzl(x); -#else - int c; - x &= 0xFFFFFFFFUL; - c = 0; - while ((x & 1) == 0) { - ++c; - x >>= 1; - } - return c; -#endif -} - -#endif diff --git a/src/encauth/ocb/ocb_shift_xor.c b/src/encauth/ocb/ocb_shift_xor.c deleted file mode 100644 index 2f7bb3b88..000000000 --- a/src/encauth/ocb/ocb_shift_xor.c +++ /dev/null @@ -1,27 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_shift_xor.c - OCB implementation, internal function, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Compute the shift/xor for OCB (internal function) - @param ocb The OCB state - @param Z The destination of the shift -*/ -void ocb_shift_xor(ocb_state *ocb, unsigned char *Z) -{ - int x, y; - y = ocb_ntz(ocb->block_index++); - for (x = 0; x < ocb->block_len; x++) { - ocb->Li[x] ^= ocb->Ls[y][x]; - Z[x] = ocb->Li[x] ^ ocb->R[x]; - } -} - -#endif diff --git a/src/encauth/ocb/ocb_test.c b/src/encauth/ocb/ocb_test.c deleted file mode 100644 index 03cef84d0..000000000 --- a/src/encauth/ocb/ocb_test.c +++ /dev/null @@ -1,205 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file ocb_test.c - OCB implementation, self-test by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/** - Test the OCB protocol - @return CRYPT_OK if successful -*/ -int ocb_test(void) -{ -#ifndef LTC_TEST - return CRYPT_NOP; -#else - static const struct { - int ptlen; - unsigned char key[16], nonce[16], pt[34], ct[34], tag[16]; - } tests[] = { - - /* OCB-AES-128-0B */ -{ - 0, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0 }, - /* ct */ - { 0 }, - /* tag */ - { 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6, - 0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee }, -}, - - - /* OCB-AES-128-3B */ -{ - 3, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0x00, 0x01, 0x02 }, - /* ct */ - { 0xfc, 0xd3, 0x7d }, - /* tag */ - { 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a, - 0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba }, -}, - - /* OCB-AES-128-16B */ -{ - 16, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* ct */ - { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3, - 0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 }, - /* tag */ - { 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71, - 0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf }, -}, - - /* OCB-AES-128-20B */ -{ - 20, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13 }, - /* ct */ - { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, - 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, - 0x70, 0x03, 0xeb, 0x55}, - /* tag */ - { 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77, - 0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb }, -}, - - /* OCB-AES-128-32B */ -{ - 32, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, - /* ct */ - { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, - 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, - 0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8, - 0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa }, - - /* tag */ - { 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c, - 0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf }, -}, - - /* OCB-AES-128-34B */ -{ - 34, - /* key */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - /* nonce */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, - /* pt */ - { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21 }, - /* ct */ - { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, - 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, - 0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa, - 0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f, - 0xa9, 0x5d }, - - /* tag */ - { 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf, - 0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab }, -}, - -}; - - int err, x, idx, res; - unsigned long len; - unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; - - /* AES can be under rijndael or aes... try to find it */ - if ((idx = find_cipher("aes")) == -1) { - if ((idx = find_cipher("rijndael")) == -1) { - return CRYPT_NOP; - } - } - - for (x = 0; x < (int)LTC_ARRAY_SIZE(tests); x++) { - len = sizeof(outtag); - if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16, - tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) { - return err; - } - - if (ltc_compare_testvector(outtag, len, tests[x].tag, sizeof(tests[x].tag), "OCB Tag", x) || - ltc_compare_testvector(outct, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "OCB CT", x)) { - return CRYPT_FAIL_TESTVECTOR; - } - - if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen, - outct, tests[x].tag, len, &res)) != CRYPT_OK) { - return err; - } - if ((res != 1) || ltc_compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB", x)) { -#ifdef LTC_TEST_DBG - printf("\n\nOCB: Failure-decrypt - res = %d\n", res); -#endif - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; -#endif /* LTC_TEST */ -} - -#endif /* LTC_OCB_MODE */ - - -/* some comments - - -- it's hard to seek - -- hard to stream [you can't emit ciphertext until full block] - -- The setup is somewhat complicated... -*/ diff --git a/src/encauth/ocb/s_ocb_done.c b/src/encauth/ocb/s_ocb_done.c deleted file mode 100644 index 9336b754c..000000000 --- a/src/encauth/ocb/s_ocb_done.c +++ /dev/null @@ -1,132 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/** - @file s_ocb_done.c - OCB implementation, internal helper, by Tom St Denis -*/ -#include "tomcrypt_private.h" - -#ifdef LTC_OCB_MODE - -/* Since the last block is encrypted in CTR mode the same code can - * be used to finish a decrypt or encrypt stream. The only difference - * is we XOR the final ciphertext into the checksum so we have to xor it - * before we CTR [decrypt] or after [encrypt] - * - * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... - */ - -/** - Shared code to finish an OCB stream - @param ocb The OCB state - @param pt The remaining plaintext [or input] - @param ptlen The length of the input (octets) - @param ct [out] The output buffer - @param tag [out] The destination for the authentication tag - @param taglen [in/out] The max size and resulting size of the authentication tag - @param mode The mode we are terminating, 0==encrypt, 1==decrypt - @return CRYPT_OK if successful -*/ -int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode) - -{ - unsigned char *Z, *Y, *X; - int err, x; - - LTC_ARGCHK(ocb != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); - LTC_ARGCHK(taglen != NULL); - if ((int)ptlen > ocb->block_len || (int)ptlen < 0) { - return CRYPT_INVALID_ARG; - } - - /* allocate ram */ - Z = XMALLOC(MAXBLOCKSIZE); - Y = XMALLOC(MAXBLOCKSIZE); - X = XMALLOC(MAXBLOCKSIZE); - if (X == NULL || Y == NULL || Z == NULL) { - if (X != NULL) { - XFREE(X); - } - if (Y != NULL) { - XFREE(Y); - } - if (Z != NULL) { - XFREE(Z); - } - return CRYPT_MEM; - } - - /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */ - ocb_shift_xor(ocb, X); - XMEMCPY(Z, X, ocb->block_len); - - X[ocb->block_len-1] ^= (ptlen*8)&255; - X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255; - for (x = 0; x < ocb->block_len; x++) { - X[x] ^= ocb->Lr[x]; - } - - /* Y[m] = E(X[m])) */ - if ((err = ecb_encrypt_block(X, Y, &ocb->key)) != CRYPT_OK) { - goto error; - } - - if (mode == 1) { - /* decrypt mode, so let's xor it first */ - /* xor C[m] into checksum */ - for (x = 0; x < (int)ptlen; x++) { - ocb->checksum[x] ^= ct[x]; - } - } - - /* C[m] = P[m] xor Y[m] */ - for (x = 0; x < (int)ptlen; x++) { - ct[x] = pt[x] ^ Y[x]; - } - - if (mode == 0) { - /* encrypt mode */ - /* xor C[m] into checksum */ - for (x = 0; x < (int)ptlen; x++) { - ocb->checksum[x] ^= ct[x]; - } - } - - /* xor Y[m] and Z[m] into checksum */ - for (x = 0; x < ocb->block_len; x++) { - ocb->checksum[x] ^= Y[x] ^ Z[x]; - } - - /* encrypt checksum, er... tag!! */ - if ((err = ecb_encrypt_block(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { - goto error; - } - ecb_done(&ocb->key); - - /* now store it */ - for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { - tag[x] = X[x]; - } - *taglen = x; - -#ifdef LTC_CLEAN_STACK - zeromem(X, MAXBLOCKSIZE); - zeromem(Y, MAXBLOCKSIZE); - zeromem(Z, MAXBLOCKSIZE); - zeromem(ocb, sizeof(*ocb)); -#endif -error: - XFREE(X); - XFREE(Y); - XFREE(Z); - - return err; -} - -#endif - diff --git a/src/encauth/siv/siv.c b/src/encauth/siv/siv.c index c07a9eac1..bd6d5b45b 100644 --- a/src/encauth/siv/siv.c +++ b/src/encauth/siv/siv.c @@ -18,34 +18,35 @@ */ static const unsigned long s_siv_max_aad_components = 126; -static LTC_INLINE void s_siv_dbl(unsigned char *inout) +LTC_ALIGN_MSVC(16) +typedef struct siv_buf_t { + union { +#ifdef LTC_FAST + LTC_FAST_TYPE word[16/sizeof(LTC_FAST_TYPE)]; +#endif + unsigned char byte[16]; + } u; +} siv_buf_t LTC_ALIGN(16); + +LTC_STATIC_ASSERT(size_of_siv_buf_t_is_16_bytes, sizeof(siv_buf_t) == 16); + +static LTC_INLINE void s_siv_dbl(siv_buf_t *D_) { - int y, mask, msb, len; + unsigned char *D = D_->u.byte; + unsigned int y, mask, msb, len; /* setup the system */ mask = 0x87; len = 16; /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ - msb = inout[0] >> 7; + msb = D[0] >> 7; /* shift left */ for (y = 0; y < (len - 1); y++) { - inout[y] = ((inout[y] << 1) | (inout[y + 1] >> 7)) & 255; + D[y] = ((D[y] << 1) | (D[y + 1] >> 7)) & 255; } - inout[len - 1] = ((inout[len - 1] << 1) ^ (msb ? mask : 0)) & 255; -} - -static LTC_INLINE int s_siv_S2V_one(int cipher, - const unsigned char *key, unsigned long keylen, - unsigned char *V, unsigned long *Vlen) -{ - /* if n = 0 then - * return V = AES-CMAC(K, ) - */ - unsigned char zero_or_one[16] = {0}; - zero_or_one[0] = 1; - return omac_memory(cipher, key, keylen, zero_or_one, sizeof(zero_or_one), V, Vlen); + D[len - 1] = ((D[len - 1] << 1) ^ (msb ? mask : 0)) & 255; } typedef struct siv_omac_ctx_t { @@ -53,6 +54,26 @@ typedef struct siv_omac_ctx_t { int cipher; } siv_omac_ctx_t; +static LTC_INLINE void s_siv_xor_buf(const siv_buf_t *a, siv_buf_t *b) +{ + unsigned int n; +#ifdef LTC_FAST +#ifdef ENDIAN_64BITWORD + LTC_UNUSED_PARAM(n); + b->u.word[0] ^= a->u.word[0]; + b->u.word[1] ^= a->u.word[1]; +#else + for (n = 0; n < LTC_ARRAY_SIZE(a->u.word); ++n) { + b->u.word[n] ^= a->u.word[n]; + } +#endif +#else + for (n = 0; n < LTC_ARRAY_SIZE(a->u.byte); ++n) { + b->u.byte[n] ^= a->u.byte[n]; + } +#endif +} + static LTC_INLINE int s_siv_ctx_init(int cipher, const unsigned char *key, unsigned long keylen, siv_omac_ctx_t *ctx) @@ -63,73 +84,69 @@ static LTC_INLINE int s_siv_ctx_init(int cipher, static LTC_INLINE int s_siv_omac_memory(siv_omac_ctx_t *ctx, const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) + siv_buf_t *out) { int err; + unsigned long len = sizeof(*out); omac_state omac = ctx->omac; if ((err = omac_process(&omac, in, inlen)) != CRYPT_OK) { return err; } - err = omac_done(&omac, out, outlen); + err = omac_done(&omac, out->u.byte, &len); zeromem(&omac, sizeof(omac)); return err; } -static LTC_INLINE int s_siv_S2V_zero(siv_omac_ctx_t *ctx, - unsigned char *D, unsigned long *Dlen) +static LTC_INLINE int s_siv_S2V_zero(siv_omac_ctx_t *ctx, siv_buf_t *D) { /* D = AES-CMAC(K, ) */ - const unsigned char zero_or_one[16] = {0}; - return s_siv_omac_memory(ctx, zero_or_one, sizeof(zero_or_one), D, Dlen); + const siv_buf_t zero = {0}; + return s_siv_omac_memory(ctx, zero.u.byte, sizeof(zero), D); } static LTC_INLINE int s_siv_S2V_dbl_xor_cmac(siv_omac_ctx_t *ctx, const unsigned char *aad, unsigned long aadlen, - unsigned char *D, unsigned long Dlen) + siv_buf_t *D) { /* for i = 1 to n-1 do * D = dbl(D) xor AES-CMAC(K, Si) * done */ int err; - unsigned char TMP[16]; - unsigned long i, TMPlen = sizeof(TMP); - s_siv_dbl(D); - if ((err = s_siv_omac_memory(ctx, aad, aadlen, TMP, &TMPlen)) != CRYPT_OK) { + siv_buf_t TMP; + if ((err = s_siv_omac_memory(ctx, aad, aadlen, &TMP)) != CRYPT_OK) { return err; } - for (i = 0; i < Dlen; ++i) { - D[i] ^= TMP[i]; - } + s_siv_dbl(D); + s_siv_xor_buf(&TMP, D); return err; } static LTC_INLINE int s_siv_omac_memory_multi(siv_omac_ctx_t *ctx, - unsigned char *out, unsigned long *outlen, + siv_buf_t *out, const unsigned char *in, unsigned long inlen, ...) { int err; va_list args; + unsigned long len = sizeof(*out); omac_state omac = ctx->omac; va_start(args, inlen); if ((err = omac_vprocess(&omac, in, inlen, args)) != CRYPT_OK) { return err; } - err = omac_done(&omac, out, outlen); + err = omac_done(&omac, out->u.byte, &len); zeromem(&omac, sizeof(omac)); return err; } static LTC_INLINE int s_siv_S2V_T(siv_omac_ctx_t *ctx, - const unsigned char *in, unsigned long inlen, - unsigned char *D, - unsigned char *V, unsigned long *Vlen) + const unsigned char *in, unsigned long inlen, + siv_buf_t *D, siv_buf_t *V) { + siv_buf_t T; int err; - unsigned long i; - unsigned char T[16]; /* if len(Sn) >= 128 then * T = Sn xorend D @@ -138,73 +155,60 @@ static LTC_INLINE int s_siv_S2V_T(siv_omac_ctx_t *ctx, * fi */ if (inlen >= 16) { - XMEMCPY(T, &in[inlen - 16], 16); - for(i = 0; i < 16; ++i) { - T[i] ^= D[i]; - } - err = s_siv_omac_memory_multi(ctx, V, Vlen, in, inlen - 16, T, 16uL, NULL); + XMEMCPY(&T, &in[inlen - 16], 16); + s_siv_xor_buf(D, &T); + err = s_siv_omac_memory_multi(ctx, V, in, inlen - 16, &T, sizeof(T), LTC_NULL); } else { s_siv_dbl(D); - XMEMCPY(T, in, inlen); - T[inlen] = 0x80; - for (i = inlen + 1; i < 16; ++i) { - T[i] = 0x0; - } - for(i = 0; i < 16; ++i) { - T[i] ^= D[i]; - } + XMEMSET(&T, 0, sizeof(T)); + XMEMCPY(&T, in, inlen); + T.u.byte[inlen] = 0x80; + s_siv_xor_buf(D, &T); - err = s_siv_omac_memory(ctx, T, 16, V, Vlen); + err = s_siv_omac_memory(ctx, T.u.byte, sizeof(T), V); } return err; } static int s_siv_S2V(int cipher, const unsigned char *key, unsigned long keylen, + unsigned long adnum, const unsigned char **ad, unsigned long *adlen, const unsigned char *in, unsigned long inlen, - unsigned char *V, unsigned long *Vlen) + siv_buf_t *V) { int err; - unsigned char D[16]; - unsigned long Dlen = sizeof(D), n = 0; + siv_buf_t D; + unsigned long n = 0; siv_omac_ctx_t ctx; - if(ad == NULL || adlen == NULL || ad[0] == NULL || adlen[0] == 0) { - err = s_siv_S2V_one(cipher, key, keylen, V, Vlen); - } else { - if ((err = s_siv_ctx_init(cipher, key, keylen, &ctx)) != CRYPT_OK) { - return err; + if ((err = s_siv_ctx_init(cipher, key, keylen, &ctx)) != CRYPT_OK) { + return err; + } + /* RFC 5297 sec 2.6: S2V(K1, AD1..ADm, P). With zero ADs this is n=1 + * (P only), not n=0 - the plaintext must still be folded into V. */ + if ((err = s_siv_S2V_zero(&ctx, &D)) != CRYPT_OK) { + return err; + } + + do { + if (n >= s_siv_max_aad_components) { + return CRYPT_INPUT_TOO_LONG; } - Dlen = sizeof(D); - if ((err = s_siv_S2V_zero(&ctx, D, &Dlen)) != CRYPT_OK) { + if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, ad ? ad[n] : NULL, adlen ? adlen[n] : 0, &D)) != CRYPT_OK) { return err; } + n++; + } while(n < adnum); - while(ad[n] != NULL && adlen[n] != 0) { - if (n >= s_siv_max_aad_components) { - return CRYPT_INPUT_TOO_LONG; - } - if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, ad[n], adlen[n], D, Dlen)) != CRYPT_OK) { - return err; - } - n++; - } - - err = s_siv_S2V_T(&ctx, in, inlen, D, V, Vlen); - } - - return err; + return s_siv_S2V_T(&ctx, in, inlen, &D, V); } -static LTC_INLINE void s_siv_bitand(const unsigned char* V, unsigned char* Q) +static LTC_INLINE void s_siv_bitand(const void* V, siv_buf_t* Q) { - int n; - XMEMSET(Q, 0xff, 16); - Q[8] = Q[12] = 0x7f; - for (n = 0; n < 16; ++n) { - Q[n] &= V[n]; - } + XMEMCPY(Q, V, sizeof(*Q)); + Q->u.byte[8] &= 0x7F; + Q->u.byte[12] &= 0x7F; } static LTC_INLINE int s_ctr_crypt_memory(int cipher, @@ -227,12 +231,14 @@ static LTC_INLINE int s_ctr_crypt_memory(int cipher, } out: +#ifdef LTC_CLEAN_STACK zeromem(&ctr, sizeof(ctr)); +#endif return err; } typedef struct { - unsigned char Q[16], V[16]; + siv_buf_t Q, V; } siv_state; /** @@ -251,19 +257,20 @@ typedef struct { */ int siv_encrypt_memory( int cipher, const unsigned char *key, unsigned long keylen, + unsigned long adnum, const unsigned char *ad[], unsigned long adlen[], const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned long *ctlen) { int err; const unsigned char *K1, *K2; - unsigned long Vlen; + void *work = NULL; siv_state siv; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(ad != NULL); - LTC_ARGCHK(adlen != NULL); - LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ad != NULL || adnum == 0); + LTC_ARGCHK(adlen != NULL || adnum == 0); + LTC_ARGCHK(pt != NULL || ptlen == 0); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctlen != NULL); @@ -278,33 +285,33 @@ int siv_encrypt_memory( int cipher, return err; } + work = XMALLOC(ptlen + 16); + if (work == NULL) { + return CRYPT_MEM; + } K1 = key; K2 = &key[keylen/2]; - Vlen = sizeof(siv.V); - err = s_siv_S2V(cipher, K1, keylen/2, ad, adlen, pt, ptlen, siv.V, &Vlen); -#ifdef LTC_CLEAN_STACK - burn_stack(3 * 16 + 7 * sizeof(unsigned long) + 1 * sizeof(void*)); -#endif - if (err != CRYPT_OK) { - return err; + if ((err = s_siv_S2V(cipher, K1, keylen/2, adnum, ad, adlen, pt, ptlen, &siv.V)) != CRYPT_OK) { + goto out; } - s_siv_bitand(siv.V, siv.Q); - XMEMCPY(ct, siv.V, 16); - ct += 16; + s_siv_bitand(&siv.V, &siv.Q); - if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, pt, ct, ptlen)) != CRYPT_OK) { - zeromem(ct, ptlen + 16); + if ((err = s_ctr_crypt_memory(cipher, siv.Q.u.byte, K2, keylen/2, pt, work, ptlen)) != CRYPT_OK) { goto out; } + XMEMCPY(ct, &siv.V, 16); + XMEMCPY(ct + 16, work, ptlen); *ctlen = ptlen + 16; out: #ifdef LTC_CLEAN_STACK zeromem(&siv, sizeof(siv)); #endif + zeromem(work, ptlen + 16); + XFREE(work); return err; } @@ -325,6 +332,7 @@ int siv_encrypt_memory( int cipher, */ int siv_decrypt_memory( int cipher, const unsigned char *key, unsigned long keylen, + unsigned long adnum, const unsigned char *ad[], unsigned long adlen[], const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned long *ptlen) @@ -332,12 +340,11 @@ int siv_decrypt_memory( int cipher, int err; unsigned char *pt_work; const unsigned char *K1, *K2, *ct_work; - unsigned long Vlen; siv_state siv; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(ad != NULL); - LTC_ARGCHK(adlen != NULL); + LTC_ARGCHK(ad != NULL || adnum == 0); + LTC_ARGCHK(adlen != NULL || adnum == 0); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ptlen != NULL); @@ -363,18 +370,17 @@ int siv_decrypt_memory( int cipher, K2 = &key[keylen/2]; ct_work = ct; - s_siv_bitand(ct_work, siv.Q); + s_siv_bitand(ct_work, &siv.Q); ct_work += 16; - if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, ct_work, pt_work, *ptlen)) != CRYPT_OK) { + if ((err = s_ctr_crypt_memory(cipher, siv.Q.u.byte, K2, keylen/2, ct_work, pt_work, *ptlen)) != CRYPT_OK) { goto out; } - Vlen = sizeof(siv.V); - if ((err = s_siv_S2V(cipher, K1, keylen/2, ad, adlen, pt_work, *ptlen, siv.V, &Vlen)) != CRYPT_OK) { + if ((err = s_siv_S2V(cipher, K1, keylen/2, adnum, ad, adlen, pt_work, *ptlen, &siv.V)) != CRYPT_OK) { goto out; } - err = XMEM_NEQ(siv.V, ct, Vlen); + err = XMEM_NEQ(&siv.V, ct, sizeof(siv.V)); copy_or_zeromem(pt_work, pt, *ptlen, err); out: #ifdef LTC_CLEAN_STACK @@ -404,17 +410,20 @@ int siv_memory( int cipher, int direction, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, + unsigned long adnum, ...) { int err; va_list args; + siv_omac_ctx_t ctx; siv_state siv; - unsigned char D[16], *in_buf = NULL, *out_work; + siv_buf_t D; + unsigned char *buf = NULL; const unsigned char *aad, *K1, *K2, *in_work; - unsigned long n = 0, aadlen, Dlen = sizeof(D), Vlen = sizeof(siv.V), in_work_len; + unsigned long n = 0, aadlen, in_work_len, buf_len; LTC_ARGCHK(key != NULL); - LTC_ARGCHK(in != NULL); + LTC_ARGCHK(in != NULL || inlen == 0); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -433,83 +442,80 @@ int siv_memory( int cipher, int direction, K2 = &key[keylen/2]; in_work = in; in_work_len = inlen; - out_work = out; if (direction == LTC_DECRYPT) { in_work_len -= 16; - in_buf = XMALLOC(in_work_len); - if (in_buf == NULL) - return CRYPT_MEM; - s_siv_bitand(in_work, siv.Q); + buf_len = in_work_len; + } else { + buf_len = inlen; + } + buf = XMALLOC(buf_len); + if (buf == NULL) + return CRYPT_MEM; + + if (direction == LTC_DECRYPT) { + s_siv_bitand(in_work, &siv.Q); in_work += 16; - if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, in_work, in_buf, in_work_len)) != CRYPT_OK) { + if ((err = s_ctr_crypt_memory(cipher, siv.Q.u.byte, K2, keylen/2, in_work, buf, in_work_len)) != CRYPT_OK) { goto err_out; } - in_work = in_buf; + in_work = buf; } - va_start(args, outlen); - aad = va_arg(args, const unsigned char*); - aadlen = aad ? va_arg(args, unsigned long) : 0; - if (aad == NULL || aadlen == 0) { - if ((err = s_siv_S2V_one(cipher, K1, keylen/2, siv.V, &Vlen)) != CRYPT_OK) { - goto err_out; + if ((err = s_siv_ctx_init(cipher, K1, keylen/2, &ctx)) != CRYPT_OK) { + goto err_out; + } + if ((err = s_siv_S2V_zero(&ctx, &D)) != CRYPT_OK) { + goto err_out; + } + va_start(args, adnum); + do { + if (adnum) { + aad = va_arg(args, const unsigned char*); + aadlen = va_arg(args, unsigned long); + } else { + aad = NULL; + aadlen = 0; } - } else { - siv_omac_ctx_t ctx; - if ((err = s_siv_ctx_init(cipher, K1, keylen/2, &ctx)) != CRYPT_OK) { - goto err_out; + if (n >= s_siv_max_aad_components) { + err = CRYPT_INPUT_TOO_LONG; + goto err_out2; } - if ((err = s_siv_S2V_zero(&ctx, D, &Dlen)) != CRYPT_OK) { - goto err_out; + if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, aad, aadlen, &D)) != CRYPT_OK) { + goto err_out2; } + n++; + } while (n < adnum); - do { - if (n >= s_siv_max_aad_components) { - err = CRYPT_INPUT_TOO_LONG; - goto err_out; - } - if ((err = s_siv_S2V_dbl_xor_cmac(&ctx, aad, aadlen, D, Dlen)) != CRYPT_OK) { - goto err_out; - } - aad = va_arg(args, const unsigned char*); - if (aad == NULL) - break; - aadlen = va_arg(args, unsigned long); - n++; - } while (aadlen); - - if ((err = s_siv_S2V_T(&ctx, in_work, in_work_len, D, siv.V, &Vlen)) != CRYPT_OK) { - goto err_out; - } + if ((err = s_siv_S2V_T(&ctx, in_work, in_work_len, &D, &siv.V)) != CRYPT_OK) { + goto err_out2; } if (direction == LTC_DECRYPT) { - err = XMEM_NEQ(siv.V, in, Vlen); + err = XMEM_NEQ(&siv.V, in, sizeof(siv.V)); copy_or_zeromem(in_work, out, in_work_len, err); *outlen = in_work_len; } else { - s_siv_bitand(siv.V, siv.Q); - XMEMCPY(out_work, siv.V, 16); - out_work += 16; + s_siv_bitand(&siv.V, &siv.Q); - if ((err = s_ctr_crypt_memory(cipher, siv.Q, K2, keylen/2, in, out_work, inlen)) != CRYPT_OK) { - zeromem(out, inlen + 16); - goto err_out; + if ((err = s_ctr_crypt_memory(cipher, siv.Q.u.byte, K2, keylen/2, in_work, buf, inlen)) != CRYPT_OK) { + goto err_out2; } + XMEMCPY(out, &siv.V, 16); + XMEMCPY(out + 16, buf, inlen); *outlen = inlen + 16; } -err_out: - if (in_buf) { - zeromem(in_buf, in_work_len); - XFREE(in_buf); - } +err_out2: va_end(args); +err_out: #ifdef LTC_CLEAN_STACK - zeromem(D, sizeof(D)); + zeromem(&ctx, sizeof(ctx)); zeromem(&siv, sizeof(siv)); + zeromem(&D, sizeof(D)); #endif + zeromem(buf, in_work_len); + XFREE(buf); return err; } @@ -580,6 +586,34 @@ int siv_test(void) { AD1_A2, AD2_A2, AD3_A2, NULL }; unsigned long adlen_A2[] = { sizeof(AD1_A2), sizeof(AD2_A2), sizeof(AD3_A2), 0 }; + const unsigned char *ad_ossl0[] = + { AD1_A2, NULL, AD3_A2, NULL }; + unsigned long adlen_ossl0[] = + { sizeof(AD1_A2), 0, sizeof(AD3_A2), 0 }; + const unsigned char output_ossl0[] = + { 0x83, 0xce, 0x65, 0x93, 0xa8, 0xfa, 0x67, 0xeb, + 0x6f, 0xcd, 0x28, 0x19, 0xce, 0xdf, 0xc0, 0x11, + 0x30, 0xd9, 0x37, 0xb4, 0x2f, 0x71, 0xf7, 0x1f, + 0x93, 0xfc, 0x2d, 0x8d, 0x70, 0x2d, 0x3e, 0xac, + 0x8d, 0xc7, 0x65, 0x1e, 0xef, 0xcd, 0x81, 0x12, + 0x00, 0x81, 0xff, 0x29, 0xd6, 0x26, 0xf9, 0x7f, + 0x3d, 0xe1, 0x7f, 0x29, 0x69, 0xb6, 0x91, 0xc9, + 0x1b, 0x69, 0xb6, 0x52, 0xbf, 0x3a, 0x6d }; + const unsigned char *ad_ossl1[] = + { NULL, AD1_A2, AD3_A2, NULL }; + unsigned long adlen_ossl1[] = + { 0, sizeof(AD1_A2), sizeof(AD3_A2), 0 }; + const unsigned char output_ossl1[] = + { 0x77, 0xdd, 0x4a, 0x44, 0xf5, 0xa6, 0xb4, 0x13, + 0x02, 0x12, 0x1e, 0xe7, 0xf3, 0x78, 0xde, 0x25, + 0x0f, 0xcd, 0x66, 0x4c, 0x92, 0x24, 0x64, 0xc8, + 0x89, 0x39, 0xd7, 0x1f, 0xad, 0x7a, 0xef, 0xb8, + 0x64, 0xe5, 0x01, 0xb0, 0x84, 0x8a, 0x07, 0xd3, + 0x92, 0x01, 0xc1, 0x06, 0x7a, 0x72, 0x88, 0xf3, + 0xda, 0xdf, 0x01, 0x31, 0xa8, 0x23, 0xa0, 0xbc, + 0x3d, 0x58, 0x8e, 0x85, 0x64, 0xa5, 0xfe }; + + #define PL_PAIR(n) n, sizeof(n) struct { @@ -587,14 +621,17 @@ int siv_test(void) unsigned long Keylen; const unsigned char* Plaintext; unsigned long Plaintextlen; + unsigned long ADnum; const void* ADs; void* ADlens; const unsigned char* output; unsigned long outputlen; const char* name; } siv_tests[] = { - { PL_PAIR(Key_A1), PL_PAIR(Plaintext_A1), &ad_A1, &adlen_A1, PL_PAIR(output_A1), "RFC5297 - A.1. Deterministic Authenticated Encryption Example" }, - { PL_PAIR(Key_A2), PL_PAIR(Plaintext_A2), &ad_A2, &adlen_A2, PL_PAIR(output_A2), "RFC5297 - A.2. Nonce-Based Authenticated Encryption Example" } + { PL_PAIR(Key_A1), PL_PAIR(Plaintext_A1), 1, &ad_A1, &adlen_A1, PL_PAIR(output_A1), "RFC5297 - A.1. Deterministic Authenticated Encryption Example" }, + { PL_PAIR(Key_A2), PL_PAIR(Plaintext_A2), 3, &ad_A2, &adlen_A2, PL_PAIR(output_A2), "RFC5297 - A.2. Nonce-Based Authenticated Encryption Example" }, + { PL_PAIR(Key_A2), PL_PAIR(Plaintext_A2), 3, &ad_ossl0, &adlen_ossl0, PL_PAIR(output_ossl0), "OpenSSL based example 0" }, + { PL_PAIR(Key_A2), PL_PAIR(Plaintext_A2), 3, &ad_ossl1, &adlen_ossl1, PL_PAIR(output_ossl1), "OpenSSL based example 1" }, }; #undef PL_PAIR @@ -603,7 +640,7 @@ int siv_test(void) unsigned long buflen, tmplen; unsigned char buf[MAX(sizeof(output_A1), sizeof(output_A2))]; const unsigned long niter = 1000; - unsigned char *tmpe, *tmpd; + unsigned char *tmp[3] = {0}; const unsigned long tmpmax = 16 + niter * 16; cipher = find_cipher("aes"); @@ -612,6 +649,7 @@ int siv_test(void) buflen = sizeof(buf); if ((err = siv_encrypt_memory(cipher, siv_tests[n].Key, siv_tests[n].Keylen, + siv_tests[n].ADnum, (const unsigned char **)siv_tests[n].ADs, siv_tests[n].ADlens, siv_tests[n].Plaintext, siv_tests[n].Plaintextlen, buf, &buflen)) != CRYPT_OK) { @@ -623,6 +661,7 @@ int siv_test(void) buflen = sizeof(buf); if ((err = siv_decrypt_memory(cipher, siv_tests[n].Key, siv_tests[n].Keylen, + siv_tests[n].ADnum, (const unsigned char **)siv_tests[n].ADs, siv_tests[n].ADlens, siv_tests[n].output, siv_tests[n].outputlen, buf, &buflen)) != CRYPT_OK) { @@ -639,6 +678,7 @@ int siv_test(void) siv_tests[0].Key, siv_tests[0].Keylen, siv_tests[0].Plaintext, siv_tests[0].Plaintextlen, buf, &buflen, + 1, AD_A1, sizeof(AD_A1), NULL)) != CRYPT_OK) { return err; @@ -652,6 +692,7 @@ int siv_test(void) siv_tests[0].Key, siv_tests[0].Keylen, siv_tests[0].output, siv_tests[0].outputlen, buf, &buflen, + 1, AD_A1, sizeof(AD_A1), NULL)) != CRYPT_OK) { return err; @@ -668,6 +709,7 @@ int siv_test(void) siv_tests[1].Key, siv_tests[1].Keylen, siv_tests[1].Plaintext, siv_tests[1].Plaintextlen, buf, &buflen, + 3, ad_A2[0], adlen_A2[0], ad_A2[1], adlen_A2[1], ad_A2[2], adlen_A2[2], @@ -683,6 +725,7 @@ int siv_test(void) siv_tests[1].Key, siv_tests[1].Keylen, siv_tests[1].output, siv_tests[1].outputlen, buf, &buflen, + 3, ad_A2[0], adlen_A2[0], ad_A2[1], adlen_A2[1], ad_A2[2], adlen_A2[2], @@ -693,51 +736,86 @@ int siv_test(void) return CRYPT_FAIL_TESTVECTOR; } - tmpe = XCALLOC(1, tmpmax); - if (tmpe == NULL) { - return CRYPT_MEM; + for (n = 0; n < LTC_ARRAY_SIZE(tmp); ++n) { + tmp[n] = XCALLOC(1, tmpmax); + if (tmp[n] == NULL) { + err = CRYPT_MEM; + goto out; + } + + } + tmplen = 16; + for (n = 0; n < niter; ++n) { + buflen = tmpmax; + if ((err = siv_encrypt_memory(cipher, + siv_tests[0].Key, siv_tests[0].Keylen, + 0, + NULL, NULL, + tmp[0], tmplen, + tmp[0], &buflen)) != CRYPT_OK) { + goto out; + } + tmplen = buflen; } - tmpd = XCALLOC(1, tmpmax); - if (tmpd == NULL) { - err = CRYPT_MEM; - goto out_tmpd; + if (ltc_compare_testvector(&buflen, sizeof(buflen), &tmpmax, sizeof(tmpmax), "Multiple encrypt length", -(int)niter)) { + err = CRYPT_FAIL_TESTVECTOR; + goto out; + } + XMEMCPY(tmp[1], tmp[0], buflen); + for (n = 0; n < niter; ++n) { + buflen = tmpmax; + if ((err = siv_decrypt_memory(cipher, + siv_tests[0].Key, siv_tests[0].Keylen, + 0, + NULL, NULL, + tmp[1], tmplen, + tmp[1], &buflen)) != CRYPT_OK) { + goto out; + } + tmplen = buflen; + } + if (ltc_compare_testvector(tmp[1], tmplen, tmp[2], tmplen, "Multi decrypt", niter + 0x2000)) { + err = CRYPT_FAIL_TESTVECTOR; } tmplen = 16; + XMEMSET(tmp[0], 0, tmplen); for (n = 0; n < niter; ++n) { buflen = tmpmax; if ((err = siv_memory(cipher, LTC_ENCRYPT, siv_tests[0].Key, siv_tests[0].Keylen, - tmpe, tmplen, - tmpe, &buflen, + tmp[0], tmplen, + tmp[0], &buflen, + 0, NULL)) != CRYPT_OK) { goto out; } tmplen = buflen; } - if (ltc_compare_testvector(&buflen, sizeof(buflen), &tmpmax, sizeof(tmpmax), "Multiple encrypt length", -(int)niter)) { + if (ltc_compare_testvector(&buflen, sizeof(buflen), &tmpmax, sizeof(tmpmax), "Multiple encrypt length", -(int)(niter + 0x4000))) { err = CRYPT_FAIL_TESTVECTOR; goto out; } - XMEMCPY(tmpd, tmpe, buflen); + XMEMCPY(tmp[1], tmp[0], buflen); for (n = 0; n < niter; ++n) { buflen = tmpmax; if ((err = siv_memory(cipher, LTC_DECRYPT, siv_tests[0].Key, siv_tests[0].Keylen, - tmpd, tmplen, - tmpd, &buflen, + tmp[1], tmplen, + tmp[1], &buflen, + 0, NULL)) != CRYPT_OK) { goto out; } tmplen = buflen; } - if (ltc_compare_testvector(tmpd, tmplen, tmpe, tmplen, "Multi decrypt", niter + 0x2000)) { + if (ltc_compare_testvector(tmp[1], tmplen, tmp[2], tmplen, "Multi decrypt", niter + 0x4000)) { err = CRYPT_FAIL_TESTVECTOR; } out: - XFREE(tmpd); -out_tmpd: - XFREE(tmpe); + for (n = LTC_ARRAY_SIZE(tmp); n --> 0;) { + XFREE(tmp[n]); + } return err; #endif diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 13d913c43..72ef692d1 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -4,13 +4,21 @@ /** @file sha1.c - LTC_SHA1 code by Tom St Denis + SHA1 code by Tom St Denis */ #ifdef LTC_SHA1 -const struct ltc_hash_descriptor sha1_desc = +/* While implementing the SMALL STACK option in https://github.com/libtom/libtomcrypt/pull/709 + * we came to the conclusion that SHA1 profits from the SMALL STACK option when the SMALL CODE + * option is enabled, so let's do that. + */ +#if defined(LTC_SMALL_STACK) || defined(LTC_SMALL_CODE) +#define LTC_SMALL_STACK_SHA1 +#endif + +const struct ltc_hash_descriptor sha1_portable_desc = { "sha1", 2, @@ -21,10 +29,10 @@ const struct ltc_hash_descriptor sha1_desc = { 1, 3, 14, 3, 2, 26, }, 6, - &sha1_init, - &sha1_process, - &sha1_done, - &sha1_test, + &sha1_c_init, + &sha1_c_process, + &sha1_c_done, + &sha1_c_test, NULL }; @@ -34,12 +42,17 @@ const struct ltc_hash_descriptor sha1_desc = #define F3(x,y,z) (x ^ y ^ z) #ifdef LTC_CLEAN_STACK -static int ss_sha1_compress(hash_state *md, const unsigned char *buf) +static int ss_sha1_c_compress(hash_state *md, const unsigned char *buf) #else -static int s_sha1_compress(hash_state *md, const unsigned char *buf) +static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) #endif { - ulong32 a,b,c,d,e,W[80],i; + ulong32 a,b,c,d,e,i; +#ifdef LTC_SMALL_STACK_SHA1 + ulong32 W[16]; +#else + ulong32 W[80]; +#endif #ifdef LTC_SMALL_CODE ulong32 t; #endif @@ -56,71 +69,86 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) d = md->sha1.state[3]; e = md->sha1.state[4]; +#ifdef LTC_SMALL_STACK_SHA1 + #define Wi(i) do { W[(i) % 16] = ROL(W[((i) - 3) % 16] ^ W[((i) - 8) % 16] ^ W[((i) - 14) % 16] ^ W[((i) - 16) % 16], 1); } while(0) + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) /* expand it */ for (i = 16; i < 80; i++) { W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); } +#endif /* compress */ /* round one */ - #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); - #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); + #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[Windex(i)] + 0x5a827999UL); b = ROLc(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[Windex(i)] + 0x6ed9eba1UL); b = ROLc(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[Windex(i)] + 0x8f1bbcdcUL); b = ROLc(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[Windex(i)] + 0xca62c1d6UL); b = ROLc(b, 30); #ifdef LTC_SMALL_CODE - for (i = 0; i < 20; ) { + for (i = 0; i < 16; ) { FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } + for (; i < 20; ) { + Wi(i); FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + } for (; i < 40; ) { - FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + Wi(i); FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } for (; i < 60; ) { - FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + Wi(i); FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } for (; i < 80; ) { - FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; + Wi(i); FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } #else - for (i = 0; i < 20; ) { + for (i = 0; i < 15; ) { FF0(a,b,c,d,e,i++); FF0(e,a,b,c,d,i++); FF0(d,e,a,b,c,i++); FF0(c,d,e,a,b,i++); FF0(b,c,d,e,a,i++); } + FF0(a,b,c,d,e,i++); + Wi(i); FF0(e,a,b,c,d,i++); + Wi(i); FF0(d,e,a,b,c,i++); + Wi(i); FF0(c,d,e,a,b,i++); + Wi(i); FF0(b,c,d,e,a,i++); /* round two */ for (; i < 40; ) { - FF1(a,b,c,d,e,i++); - FF1(e,a,b,c,d,i++); - FF1(d,e,a,b,c,i++); - FF1(c,d,e,a,b,i++); - FF1(b,c,d,e,a,i++); + Wi(i); FF1(a,b,c,d,e,i++); + Wi(i); FF1(e,a,b,c,d,i++); + Wi(i); FF1(d,e,a,b,c,i++); + Wi(i); FF1(c,d,e,a,b,i++); + Wi(i); FF1(b,c,d,e,a,i++); } /* round three */ for (; i < 60; ) { - FF2(a,b,c,d,e,i++); - FF2(e,a,b,c,d,i++); - FF2(d,e,a,b,c,i++); - FF2(c,d,e,a,b,i++); - FF2(b,c,d,e,a,i++); + Wi(i); FF2(a,b,c,d,e,i++); + Wi(i); FF2(e,a,b,c,d,i++); + Wi(i); FF2(d,e,a,b,c,i++); + Wi(i); FF2(c,d,e,a,b,i++); + Wi(i); FF2(b,c,d,e,a,i++); } /* round four */ for (; i < 80; ) { - FF3(a,b,c,d,e,i++); - FF3(e,a,b,c,d,i++); - FF3(d,e,a,b,c,i++); - FF3(c,d,e,a,b,i++); - FF3(b,c,d,e,a,i++); + Wi(i); FF3(a,b,c,d,e,i++); + Wi(i); FF3(e,a,b,c,d,i++); + Wi(i); FF3(d,e,a,b,c,i++); + Wi(i); FF3(c,d,e,a,b,i++); + Wi(i); FF3(b,c,d,e,a,i++); } #endif @@ -128,6 +156,8 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) #undef FF1 #undef FF2 #undef FF3 + #undef Wi + #undef Windex /* store */ md->sha1.state[0] = md->sha1.state[0] + a; @@ -140,10 +170,10 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) } #ifdef LTC_CLEAN_STACK -static int s_sha1_compress(hash_state *md, const unsigned char *buf) +static int s_sha1_c_compress(hash_state *md, const unsigned char *buf) { int err; - err = ss_sha1_compress(md, buf); + err = ss_sha1_c_compress(md, buf); burn_stack(sizeof(ulong32) * 87); return err; } @@ -154,9 +184,12 @@ static int s_sha1_compress(hash_state *md, const unsigned char *buf) @param md The hash state you wish to initialize @return CRYPT_OK if successful */ -int sha1_init(hash_state * md) +int sha1_c_init(hash_state * md) { LTC_ARGCHK(md != NULL); + + md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + md->sha1.state[0] = 0x67452301UL; md->sha1.state[1] = 0xefcdab89UL; md->sha1.state[2] = 0x98badcfeUL; @@ -174,7 +207,7 @@ int sha1_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64) +HASH_PROCESS(sha1_c_process, s_sha1_c_compress, sha1, 64) /** Terminate the hash to get the digest @@ -182,7 +215,7 @@ HASH_PROCESS(sha1_process, s_sha1_compress, sha1, 64) @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ -int sha1_done(hash_state * md, unsigned char *out) +int sha1_c_done(hash_state * md, unsigned char *out) { int i; @@ -207,7 +240,7 @@ int sha1_done(hash_state * md, unsigned char *out) while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } - s_sha1_compress(md, md->sha1.buf); + s_sha1_c_compress(md, md->sha1.buf); md->sha1.curlen = 0; } @@ -218,7 +251,7 @@ int sha1_done(hash_state * md, unsigned char *out) /* store length */ STORE64H(md->sha1.length, md->sha1.buf+56); - s_sha1_compress(md, md->sha1.buf); + s_sha1_c_compress(md, md->sha1.buf); /* copy output */ for (i = 0; i < 5; i++) { @@ -234,41 +267,9 @@ int sha1_done(hash_state * md, unsigned char *out) Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ -int sha1_test(void) +int sha1_c_test(void) { - #ifndef LTC_TEST - return CRYPT_NOP; - #else - static const struct { - const char *msg; - unsigned char hash[20]; - } tests[] = { - { "abc", - { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, - 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, - 0x9c, 0xd0, 0xd8, 0x9d } - }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, - 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, - 0xE5, 0x46, 0x70, 0xF1 } - } - }; - - int i; - unsigned char tmp[20]; - hash_state md; - - for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha1_init(&md); - sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); - sha1_done(&md, tmp); - if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) { - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; - #endif + return sha1_test_desc(&sha1_portable_desc, "SHA1 portable"); } #undef F0 diff --git a/src/hashes/sha1_desc.c b/src/hashes/sha1_desc.c new file mode 100644 index 000000000..bc6a7de34 --- /dev/null +++ b/src/hashes/sha1_desc.c @@ -0,0 +1,177 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +#ifdef LTC_SHA1 + +const struct ltc_hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, + + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test, + NULL +}; + +#if defined LTC_SHA1_X86 + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_sha1_x86_is_supported(void) +{ + static int initialized = 0; + static int is_supported = 0; + + if (initialized == 0) { + int regs[4]; + int sse2, ssse3, sse41, sha; + /* Leaf 0, Reg 0 contains the number of leafs available */ + s_x86_cpuid(regs, 0); + if(regs[0] >= 7) { + s_x86_cpuid(regs, 1); + sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */ + ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSSE3, leaf 1, ecx, bit 9 */ + sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */ + s_x86_cpuid(regs, 7); + sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */ + is_supported = sse2 && ssse3 && sse41 && sha; + } + initialized = 1; + } + return is_supported; +} +#endif /* LTC_SHA1_X86 */ + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha1_init(hash_state * md) +{ +#if defined LTC_SHA1_X86 + if(s_sha1_x86_is_supported()) { + return sha1_x86_init(md); + } +#endif + return sha1_c_init(md); +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen) +{ +#if defined LTC_SHA1_X86 + if(s_sha1_x86_is_supported()) { + return sha1_x86_process(md, in, inlen); + } +#endif + return sha1_c_process(md, in, inlen); +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int sha1_done(hash_state * md, unsigned char *out) +{ +#if defined LTC_SHA1_X86 + if(s_sha1_x86_is_supported()) { + return sha1_x86_done(md, out); + } +#endif + return sha1_c_done(md, out); +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha1_test(void) +{ + return sha1_test_desc(&sha1_desc, "SHA1"); +} + +int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name) +{ +#ifndef LTC_TEST + (void)desc; + (void)name; + return CRYPT_NOP; +#else + static const struct { + const char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + LTC_ARGCHK(desc != NULL); + LTC_ARGCHK(desc->init != NULL); + LTC_ARGCHK(desc->process != NULL); + LTC_ARGCHK(desc->done != NULL); + LTC_ARGCHK(name != NULL); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + desc->init(&md); + desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); + desc->done(&md, tmp); + if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), name, i)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/hashes/sha1_x86.c b/src/hashes/sha1_x86.c new file mode 100644 index 000000000..c1c5408be --- /dev/null +++ b/src/hashes/sha1_x86.c @@ -0,0 +1,287 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file sha1_x86.c + SHA1 code by Marek Knapek +*/ + +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#pragma GCC diagnostic ignored "-Wuninitialized" +#pragma GCC diagnostic ignored "-Wunused-function" +#elif defined(_MSC_VER) +#include +#endif +#include /* SSE2 _mm_load_si128 _mm_loadu_si128 _mm_store_si128 _mm_set_epi32 _mm_set_epi64x _mm_setzero_si128 _mm_xor_si128 _mm_add_epi32 _mm_shuffle_epi32 */ +#include /* SSSE3 _mm_shuffle_epi8 */ +#include /* SSE4.1 _mm_extract_epi32 */ +#include /* SHA _mm_sha1msg1_epu32 _mm_sha1msg2_epu32 _mm_sha1rnds4_epu32 _mm_sha1nexte_epu32 */ + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +const struct ltc_hash_descriptor sha1_x86_desc = +{ + "sha1", + 2, + 20, + 64, + + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, + + &sha1_x86_init, + &sha1_x86_process, + &sha1_x86_done, + &sha1_x86_test, + NULL +}; + +#ifdef LTC_CLEAN_STACK +static int LTC_SHA_TARGET ss_sha1_x86_compress(hash_state *md, const unsigned char *buf) +#else +static int LTC_SHA_TARGET s_sha1_x86_compress(hash_state *md, const unsigned char *buf) +#endif +{ +#define k_reverse_32 ((0x0 << (3 * 2)) | (0x1 << (2 * 2)) | (0x2 << (1 * 2)) | (0x3 << (0 * 2))) + + __m128i reverse_8; + __m128i abcdx; + __m128i e; + __m128i old_abcd; + __m128i old_e; + __m128i msg_0; + __m128i abcdy; + __m128i msg_1; + __m128i msg_2; + __m128i msg_3; + + reverse_8 = _mm_set_epi64x(0x0001020304050607ull, 0x08090a0b0c0d0e0full); + abcdx = _mm_load_si128(((__m128i const*)(&md->sha1.state[0]))); + abcdx = _mm_shuffle_epi32(abcdx, k_reverse_32); + e = _mm_set_epi32(*((int const*)(&md->sha1.state[4])), 0, 0, 0); + + old_abcd = abcdx; + old_e = e; + msg_0 = _mm_loadu_si128(((__m128i const*)(&buf[0 * 16]))); + msg_0 = _mm_shuffle_epi8(msg_0, reverse_8); + e = _mm_add_epi32(e, msg_0); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0); + msg_1 = _mm_loadu_si128(((__m128i const*)(&buf[1 * 16]))); + msg_1 = _mm_shuffle_epi8(msg_1, reverse_8); + e = _mm_sha1nexte_epu32(abcdx, msg_1); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 0); + msg_2 = _mm_loadu_si128(((__m128i const*)(&buf[2 * 16]))); + msg_2 = _mm_shuffle_epi8(msg_2, reverse_8); + e = _mm_sha1nexte_epu32(abcdy, msg_2); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0); + msg_3 = _mm_loadu_si128(((__m128i const*)(&buf[3 * 16]))); + msg_3 = _mm_shuffle_epi8(msg_3, reverse_8); + e = _mm_sha1nexte_epu32(abcdx, msg_3); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 0); + msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1); + msg_0 = _mm_xor_si128(msg_0, msg_2); + msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3); + e = _mm_sha1nexte_epu32(abcdy, msg_0); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 0); + msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2); + msg_1 = _mm_xor_si128(msg_1, msg_3); + msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0); + e = _mm_sha1nexte_epu32(abcdx, msg_1); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1); + msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3); + msg_2 = _mm_xor_si128(msg_2, msg_0); + msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1); + e = _mm_sha1nexte_epu32(abcdy, msg_2); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 1); + msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0); + msg_3 = _mm_xor_si128(msg_3, msg_1); + msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2); + e = _mm_sha1nexte_epu32(abcdx, msg_3); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1); + msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1); + msg_0 = _mm_xor_si128(msg_0, msg_2); + msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3); + e = _mm_sha1nexte_epu32(abcdy, msg_0); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 1); + msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2); + msg_1 = _mm_xor_si128(msg_1, msg_3); + msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0); + e = _mm_sha1nexte_epu32(abcdx, msg_1); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 1); + msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3); + msg_2 = _mm_xor_si128(msg_2, msg_0); + msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1); + e = _mm_sha1nexte_epu32(abcdy, msg_2); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2); + msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0); + msg_3 = _mm_xor_si128(msg_3, msg_1); + msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2); + e = _mm_sha1nexte_epu32(abcdx, msg_3); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 2); + msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1); + msg_0 = _mm_xor_si128(msg_0, msg_2); + msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3); + e = _mm_sha1nexte_epu32(abcdy, msg_0); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2); + msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2); + msg_1 = _mm_xor_si128(msg_1, msg_3); + msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0); + e = _mm_sha1nexte_epu32(abcdx, msg_1); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 2); + msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3); + msg_2 = _mm_xor_si128(msg_2, msg_0); + msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1); + e = _mm_sha1nexte_epu32(abcdy, msg_2); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 2); + msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0); + msg_3 = _mm_xor_si128(msg_3, msg_1); + msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2); + e = _mm_sha1nexte_epu32(abcdx, msg_3); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3); + msg_0 = _mm_sha1msg1_epu32(msg_0, msg_1); + msg_0 = _mm_xor_si128(msg_0, msg_2); + msg_0 = _mm_sha1msg2_epu32(msg_0, msg_3); + e = _mm_sha1nexte_epu32(abcdy, msg_0); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 3); + msg_1 = _mm_sha1msg1_epu32(msg_1, msg_2); + msg_1 = _mm_xor_si128(msg_1, msg_3); + msg_1 = _mm_sha1msg2_epu32(msg_1, msg_0); + e = _mm_sha1nexte_epu32(abcdx, msg_1); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3); + msg_2 = _mm_sha1msg1_epu32(msg_2, msg_3); + msg_2 = _mm_xor_si128(msg_2, msg_0); + msg_2 = _mm_sha1msg2_epu32(msg_2, msg_1); + e = _mm_sha1nexte_epu32(abcdy, msg_2); + abcdy = _mm_sha1rnds4_epu32(abcdx, e, 3); + msg_3 = _mm_sha1msg1_epu32(msg_3, msg_0); + msg_3 = _mm_xor_si128(msg_3, msg_1); + msg_3 = _mm_sha1msg2_epu32(msg_3, msg_2); + e = _mm_sha1nexte_epu32(abcdx, msg_3); + abcdx = _mm_sha1rnds4_epu32(abcdy, e, 3); + msg_0 = _mm_setzero_si128(); + e = _mm_sha1nexte_epu32(abcdy, msg_0); + abcdx = _mm_add_epi32(abcdx, old_abcd); + e = _mm_add_epi32(e, old_e); + + abcdx = _mm_shuffle_epi32(abcdx, k_reverse_32); + _mm_store_si128(((__m128i*)(&md->sha1.state[0])), abcdx); + *((int*)(&md->sha1.state[4])) = _mm_extract_epi32(e, 3); + + return CRYPT_OK; + +#undef k_reverse_32 +} + +#ifdef LTC_CLEAN_STACK +static int s_sha1_x86_compress(hash_state *md, const unsigned char *buf) +{ + int err; + err = ss_sha1_x86_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha1_x86_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha1.state = LTC_ALIGN_BUF(md->sha1.state_buf, 16); + + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha1_x86_process, s_sha1_x86_compress, sha1, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (20 bytes) + @return CRYPT_OK if successful +*/ +int sha1_x86_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha1.curlen >= ((int)(sizeof(md->sha1.buf)))) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + s_sha1_x86_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + s_sha1_x86_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha1_x86_test(void) +{ + return sha1_test_desc(&sha1_x86_desc, "SHA1 x86"); +} + +#endif diff --git a/src/hashes/sha2/sha224.c b/src/hashes/sha2/sha224.c index ba3f5b678..15fc36767 100644 --- a/src/hashes/sha2/sha224.c +++ b/src/hashes/sha2/sha224.c @@ -9,7 +9,7 @@ #if defined(LTC_SHA224) && defined(LTC_SHA256) -const struct ltc_hash_descriptor sha224_desc = +const struct ltc_hash_descriptor sha224_portable_desc = { "sha224", 10, @@ -20,9 +20,9 @@ const struct ltc_hash_descriptor sha224_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, 9, - &sha224_init, - &sha256_process, - &sha224_done, + &sha224_c_init, + &sha256_c_process, + &sha224_c_done, &sha224_test, NULL }; @@ -33,10 +33,12 @@ const struct ltc_hash_descriptor sha224_desc = @param md The hash state you wish to initialize @return CRYPT_OK if successful */ -int sha224_init(hash_state * md) +int sha224_c_init(hash_state * md) { LTC_ARGCHK(md != NULL); + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.curlen = 0; md->sha256.length = 0; md->sha256.state[0] = 0xc1059ed8UL; @@ -56,7 +58,7 @@ int sha224_init(hash_state * md) @param out [out] The destination of the hash (28 bytes) @return CRYPT_OK if successful */ -int sha224_done(hash_state * md, unsigned char *out) +int sha224_c_done(hash_state * md, unsigned char *out) { unsigned char buf[32]; int err; @@ -76,43 +78,9 @@ int sha224_done(hash_state * md, unsigned char *out) Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ -int sha224_test(void) +int sha224_c_test(void) { - #ifndef LTC_TEST - return CRYPT_NOP; - #else - static const struct { - const char *msg; - unsigned char hash[28]; - } tests[] = { - { "abc", - { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, - 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, - 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, - 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } - }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, - 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, - 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, - 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } - }, - }; - - int i; - unsigned char tmp[28]; - hash_state md; - - for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha224_init(&md); - sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); - sha224_done(&md, tmp); - if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA224", i)) { - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; - #endif + return sha224_test_desc(&sha224_portable_desc, "SHA224 portable"); } #endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */ diff --git a/src/hashes/sha2/sha224_desc.c b/src/hashes/sha2/sha224_desc.c new file mode 100644 index 000000000..6aa9dfd20 --- /dev/null +++ b/src/hashes/sha2/sha224_desc.c @@ -0,0 +1,169 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +/** + @param sha224.c + LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) +*/ + +#include "tomcrypt_private.h" + +#if defined(LTC_SHA224) && defined(LTC_SHA256) + +const struct ltc_hash_descriptor sha224_desc = +{ + "sha224", + 10, + 28, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, + 9, + + &sha224_init, + &sha256_process, + &sha224_done, + &sha224_test, + NULL +}; + +#if defined LTC_SHA224_X86 + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_sha224_x86_is_supported(void) +{ + static int initialized = 0; + static int is_supported = 0; + + if (initialized == 0) { + int regs[4]; + int sse2, ssse3, sse41, sha; + /* Leaf 0, Reg 0 contains the number of leafs available */ + s_x86_cpuid(regs, 0); + if(regs[0] >= 7) { + s_x86_cpuid(regs, 1); + sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */ + ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSSE3, leaf 1, ecx, bit 9 */ + sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */ + s_x86_cpuid(regs, 7); + sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */ + is_supported = sse2 && ssse3 && sse41 && sha; + } + initialized = 1; + } + return is_supported; +} +#endif /* LTC_SHA224_X86 */ + +/* init the sha256 er... sha224 state ;-) */ +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha224_init(hash_state * md) +{ +#if defined LTC_SHA224_X86 + if(s_sha224_x86_is_supported()) { + return sha224_x86_init(md); + } +#endif + return sha224_c_init(md); +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (28 bytes) + @return CRYPT_OK if successful +*/ +int sha224_done(hash_state * md, unsigned char *out) +{ +#if defined LTC_SHA224_X86 + if(s_sha224_x86_is_supported()) { + return sha224_x86_done(md, out); + } +#endif + return sha224_c_done(md, out); +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha224_test(void) +{ + return sha224_test_desc(&sha224_desc, "SHA224"); +} + +int sha224_test_desc(const struct ltc_hash_descriptor *desc, const char *name) +{ + #ifndef LTC_TEST + (void)desc; + (void)name; + return CRYPT_NOP; + #else + static const struct { + const char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, + 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, + 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, + 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, + 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, + 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, + 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + LTC_ARGCHK(desc != NULL); + LTC_ARGCHK(desc->init != NULL); + LTC_ARGCHK(desc->process != NULL); + LTC_ARGCHK(desc->done != NULL); + LTC_ARGCHK(name != NULL); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + desc->init(&md); + desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); + desc->done(&md, tmp); + if (ltc_compare_testvector(tmp, 28, tests[i].hash, sizeof(tests[i].hash), name, i)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */ + diff --git a/src/hashes/sha2/sha224_x86.c b/src/hashes/sha2/sha224_x86.c new file mode 100644 index 000000000..f562b34a0 --- /dev/null +++ b/src/hashes/sha2/sha224_x86.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +/** + @param sha224.c + LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) +*/ + +#include "tomcrypt_private.h" + +#if defined(LTC_SHA224) && defined(LTC_SHA256) && defined(LTC_SHA224_X86) && defined(LTC_SHA256_X86) + +const struct ltc_hash_descriptor sha224_x86_desc = +{ + "sha224", + 10, + 28, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, + 9, + + &sha224_x86_init, + &sha256_x86_process, + &sha224_x86_done, + &sha224_x86_test, + NULL +}; + +/* init the sha256 er... sha224 state ;-) */ +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha224_x86_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; + return CRYPT_OK; +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (28 bytes) + @return CRYPT_OK if successful +*/ +int sha224_x86_done(hash_state * md, unsigned char *out) +{ + unsigned char buf[32]; + int err; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + err = sha256_x86_done(md, buf); + XMEMCPY(out, buf, 28); +#ifdef LTC_CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha224_x86_test(void) +{ + return sha224_test_desc(&sha224_x86_desc, "SHA224 x86"); +} + +#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */ + diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index 1f4432823..a37028d64 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -4,12 +4,12 @@ /** @file sha256.c - LTC_SHA256 by Tom St Denis + SHA256 by Tom St Denis */ #ifdef LTC_SHA256 -const struct ltc_hash_descriptor sha256_desc = +const struct ltc_hash_descriptor sha256_portable_desc = { "sha256", 0, @@ -20,13 +20,22 @@ const struct ltc_hash_descriptor sha256_desc = { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, 9, - &sha256_init, - &sha256_process, - &sha256_done, - &sha256_test, + &sha256_c_init, + &sha256_c_process, + &sha256_c_done, + &sha256_c_test, NULL }; +/* While implementing the SMALL STACK option in https://github.com/libtom/libtomcrypt/pull/709 + * we came to the conclusion that SHA256 profits from the SMALL STACK option when the SMALL CODE + * option is disabled. + * So enable it either when it's enabled explicitly, or when SMALL CODE is disabled. + */ +#if !defined(LTC_SMALL_CODE) || defined(LTC_SMALL_STACK) +#define LTC_SMALL_STACK_SHA256 +#endif + #ifdef LTC_SMALL_CODE /* the K array */ static const ulong32 K[64] = { @@ -63,7 +72,12 @@ static int ss_sha256_compress(hash_state * md, const unsigned char *buf) static int s_sha256_compress(hash_state * md, const unsigned char *buf) #endif { - ulong32 S[8], W[64], t0, t1; + ulong32 S[8], t0, t1; +#ifdef LTC_SMALL_STACK_SHA256 + ulong32 W[16]; +#else + ulong32 W[64]; +#endif #ifdef LTC_SMALL_CODE ulong32 t; #endif @@ -79,29 +93,51 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) LOAD32H(W[i], buf + (4*i)); } +#ifdef LTC_SMALL_STACK_SHA256 + #define Wi(i) W[(i) % 16] = Gamma1(W[((i) - 2) % 16]) + W[((i) - 7) % 16] + Gamma0(W[((i) - 15) % 16]) + W[((i) - 16) % 16] + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) + /* fill W[16..63] */ for (i = 16; i < 64; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; } +#endif /* Compress */ #ifdef LTC_SMALL_CODE -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; +#ifdef LTC_SMALL_STACK_SHA256 + for (i = 0; i < 16; ++i) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } + for (; i < 64; ++i) { + Wi(i); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); + t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; + S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; + } +#else for (i = 0; i < 64; ++i) { RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; } +#endif /* LTC_SMALL_STACK_SHA256 */ #else -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); @@ -120,56 +156,58 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + Wi(16); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + Wi(17); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + Wi(18); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + Wi(19); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + Wi(20); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + Wi(21); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + Wi(22); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + Wi(23); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + Wi(24); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + Wi(25); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + Wi(26); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + Wi(27); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + Wi(28); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + Wi(29); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + Wi(30); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + Wi(31); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + Wi(32); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + Wi(33); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + Wi(34); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + Wi(35); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + Wi(36); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + Wi(37); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + Wi(38); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + Wi(39); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + Wi(40); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + Wi(41); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + Wi(42); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + Wi(43); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + Wi(44); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + Wi(45); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + Wi(46); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + Wi(47); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + Wi(48); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + Wi(49); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + Wi(50); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + Wi(51); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + Wi(52); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + Wi(53); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + Wi(54); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + Wi(55); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + Wi(56); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + Wi(57); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + Wi(58); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + Wi(59); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + Wi(60); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + Wi(61); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + Wi(62); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + Wi(63); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); #endif #undef RND +#undef Wi +#undef Windex /* feedback */ for (i = 0; i < 8; i++) { @@ -193,10 +231,12 @@ static int s_sha256_compress(hash_state * md, const unsigned char *buf) @param md The hash state you wish to initialize @return CRYPT_OK if successful */ -int sha256_init(hash_state * md) +int sha256_c_init(hash_state * md) { LTC_ARGCHK(md != NULL); + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + md->sha256.curlen = 0; md->sha256.length = 0; md->sha256.state[0] = 0x6A09E667UL; @@ -217,7 +257,7 @@ int sha256_init(hash_state * md) @param inlen The length of the data (octets) @return CRYPT_OK if successful */ -HASH_PROCESS(sha256_process,s_sha256_compress, sha256, 64) +HASH_PROCESS(sha256_c_process,s_sha256_compress, sha256, 64) /** Terminate the hash to get the digest @@ -225,7 +265,7 @@ HASH_PROCESS(sha256_process,s_sha256_compress, sha256, 64) @param out [out] The destination of the hash (32 bytes) @return CRYPT_OK if successful */ -int sha256_done(hash_state * md, unsigned char *out) +int sha256_c_done(hash_state * md, unsigned char *out) { int i; @@ -278,43 +318,9 @@ int sha256_done(hash_state * md, unsigned char *out) Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ -int sha256_test(void) +int sha256_c_test(void) { - #ifndef LTC_TEST - return CRYPT_NOP; - #else - static const struct { - const char *msg; - unsigned char hash[32]; - } tests[] = { - { "abc", - { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } - }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, - 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, - 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, - 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } - }, - }; - - int i; - unsigned char tmp[32]; - hash_state md; - - for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { - sha256_init(&md); - sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); - sha256_done(&md, tmp); - if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA256", i)) { - return CRYPT_FAIL_TESTVECTOR; - } - } - return CRYPT_OK; - #endif + return sha256_test_desc(&sha256_portable_desc, "SHA256 portable"); } #undef Ch diff --git a/src/hashes/sha2/sha256_desc.c b/src/hashes/sha2/sha256_desc.c new file mode 100644 index 000000000..993b0a168 --- /dev/null +++ b/src/hashes/sha2/sha256_desc.c @@ -0,0 +1,188 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +#if defined LTC_ARCH_X86 + +#if !defined (LTC_S_X86_CPUID) +#define LTC_S_X86_CPUID +static LTC_INLINE void s_x86_cpuid(int* regs, int leaf) +{ +#if defined _MSC_VER + __cpuid(regs, leaf); +#else + int a, b, c, d; + + a = leaf; + b = c = d = 0; + asm volatile ("cpuid" + :"=a"(a), "=b"(b), "=c"(c), "=d"(d) + :"a"(a), "c"(c) + ); + regs[0] = a; + regs[1] = b; + regs[2] = c; + regs[3] = d; +#endif +} +#endif /* LTC_S_X86_CPUID */ + +static LTC_INLINE int s_sha256_x86_is_supported(void) +{ + static int initialized = 0; + static int is_supported = 0; + + if (initialized == 0) { + int regs[4]; + int sse2, ssse3, sse41, sha; + /* Leaf 0, Reg 0 contains the number of leafs available */ + s_x86_cpuid(regs, 0); + if(regs[0] >= 7) { + s_x86_cpuid(regs, 1); + sse2 = ((((unsigned int)(regs[3])) >> 26) & 1u) != 0; /* SSE2, leaf 1, edx, bit 26 */ + ssse3 = ((((unsigned int)(regs[2])) >> 9) & 1u) != 0; /* SSSE3, leaf 1, ecx, bit 9 */ + sse41 = ((((unsigned int)(regs[2])) >> 19) & 1u) != 0; /* SSE4.1, leaf 1, ecx, bit 19 */ + s_x86_cpuid(regs, 7); + sha = ((((unsigned int)(regs[1])) >> 29) & 1u) != 0; /* SHA, leaf 7, ebx, bit 29 */ + is_supported = sse2 && ssse3 && sse41 && sha; + } + initialized = 1; + } + return is_supported; +} +#endif /* LTC_ARCH_X86 */ + +int shani_is_supported(void) +{ +#ifdef LTC_ARCH_X86 + return s_sha256_x86_is_supported(); +#else + return 0; +#endif +} + +#ifdef LTC_SHA256 + +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test, + NULL +}; + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha256_init(hash_state * md) +{ +#if defined LTC_SHA256_X86 + if(s_sha256_x86_is_supported()) { + return sha256_x86_init(md); + } +#endif + return sha256_c_init(md); +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen) +{ +#if defined LTC_SHA256_X86 + if(s_sha256_x86_is_supported()) { + return sha256_x86_process(md, in, inlen); + } +#endif + return sha256_c_process(md, in, inlen); +} + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_done(hash_state * md, unsigned char *out) +{ +#if defined LTC_SHA256_X86 + if(s_sha256_x86_is_supported()) { + return sha256_x86_done(md, out); + } +#endif + return sha256_c_done(md, out); +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha256_test(void) +{ + return sha256_test_desc(&sha256_desc, "SHA256"); +} + +int sha256_test_desc(const struct ltc_hash_descriptor *desc, const char *name) +{ +#ifndef LTC_TEST + (void)desc; + (void)name; + return CRYPT_NOP; +#else + static const struct { + const char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + LTC_ARGCHK(desc != NULL); + LTC_ARGCHK(desc->init != NULL); + LTC_ARGCHK(desc->process != NULL); + LTC_ARGCHK(desc->done != NULL); + LTC_ARGCHK(name != NULL); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + desc->init(&md); + desc->process(&md, (unsigned char*)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg)); + desc->done(&md, tmp); + if (ltc_compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), name, i)) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/src/hashes/sha2/sha256_x86.c b/src/hashes/sha2/sha256_x86.c new file mode 100644 index 000000000..43a23c913 --- /dev/null +++ b/src/hashes/sha2/sha256_x86.c @@ -0,0 +1,358 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file sha256_x86.c + SHA256 by Marek Knapek +*/ + +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-align" +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#pragma GCC diagnostic ignored "-Wuninitialized" +#pragma GCC diagnostic ignored "-Wunused-function" +#elif defined(_MSC_VER) +#include +#endif +#include /* SSE2 _mm_load_si128 _mm_loadu_si128 _mm_store_si128 _mm_set_epi64x _mm_add_epi32 _mm_shuffle_epi32 */ +#include /* SSSE3 _mm_alignr_epi8 _mm_shuffle_epi8 */ +#include /* SSE4.1 _mm_blend_epi16 */ +#include /* SHA _mm_sha256msg1_epu32 _mm_sha256msg2_epu32 _mm_sha256rnds2_epu32 */ +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +const struct ltc_hash_descriptor sha256_x86_desc = +{ + "sha256", + 0, + 32, + 64, + + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, + + &sha256_x86_init, + &sha256_x86_process, + &sha256_x86_done, + &sha256_x86_test, + NULL +}; + +/* the K array */ +#define K sha256_x86_K +LTC_ALIGN_MSVC(16) +static const ulong32 K[64] LTC_ALIGN(16) = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* compress 512-bits */ +#ifdef LTC_CLEAN_STACK +static int LTC_SHA_TARGET ss_sha256_x86_compress(hash_state * md, const unsigned char *buf) +#else +static int LTC_SHA_TARGET s_sha256_x86_compress(hash_state * md, const unsigned char *buf) +#endif +{ +#define k_blend_epi16(a, b, c, d, e, f, g, h) ((((a) & 0x1) << 7) | (((b) & 0x1) << 6) | (((c) & 0x1) << 5) | (((d) & 0x1) << 4) | (((e) & 0x1) << 3) | (((f) & 0x1) << 2) | (((g) & 0x1) << 1) | (((h) & 0x1) << 0)) +#define ltc_mm_blend_epi32(a, b, c) _mm_blend_epi16((a), (b), k_blend_epi16((((c) >> 3) & 0x1), (((c) >> 3) & 0x1), (((c) >> 2) & 0x1), (((c) >> 2) & 0x1), (((c) >> 1) & 0x1), (((c) >> 1) & 0x1), (((c) >> 0) & 0x1), (((c) >> 0) & 0x1))) +#define k_shuffle_epi32(a, b, c, d) ((((a) & 0x3) << (3 * 2)) | (((b) & 0x3) << (2 * 2)) | (((c) & 0x3) << (1 * 2)) | (((d) & 0x3) << (0 * 2))) +#define k_blend_epi32(a, b, c, d) ((((a) & 0x1) << (3 * 1)) | (((b) & 0x1) << (2 * 1)) | (((c) & 0x1) << (1 * 1)) | (((d) & 0x1) << (0 * 1))) +#define k_alignr_epi8(a) (((a) & 0x3) * 4) +#define k_any 0x0 + + __m128i reverse; + __m128i state_0; + __m128i state_1; + __m128i tmp; + __m128i old_0; + __m128i old_1; + __m128i msg_0; + __m128i msg; + __m128i msg_1; + __m128i msg_2; + __m128i msg_3; + + reverse = _mm_set_epi64x(0x0c0d0e0f08090a0bull, 0x0405060700010203ull); + state_0 = _mm_load_si128(((__m128i const*)(&md->sha256.state[0]))); + state_1 = _mm_load_si128(((__m128i const*)(&md->sha256.state[4]))); + tmp = _mm_shuffle_epi32(state_0, k_shuffle_epi32(0x2, 0x3, 0x0, 0x1)); + state_1 = _mm_shuffle_epi32(state_1, k_shuffle_epi32(0x0, 0x1, 0x2, 0x3)); + state_0 = _mm_alignr_epi8(tmp, state_1, k_alignr_epi8(2)); + state_1 = ltc_mm_blend_epi32(state_1, tmp, k_blend_epi32(0x1, 0x1, 0x0, 0x0)); + + old_0 = state_0; + old_1 = state_1; + msg_0 = _mm_loadu_si128(((__m128i const*)(&buf[0 * 16]))); + msg_0 = _mm_shuffle_epi8(msg_0, reverse); + tmp = _mm_load_si128(((__m128i const*)(&K[0 * 4]))); + msg = _mm_add_epi32(msg_0, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_1 = _mm_loadu_si128(((__m128i const*)(&buf[1 * 16]))); + msg_1 = _mm_shuffle_epi8(msg_1, reverse); + tmp = _mm_load_si128(((__m128i const*)(&K[1 * 4]))); + msg = _mm_add_epi32(msg_1, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_2 = _mm_loadu_si128(((__m128i const*)(&buf[2 * 16]))); + msg_2 = _mm_shuffle_epi8(msg_2, reverse); + tmp = _mm_load_si128(((__m128i const*)(&K[2 * 4]))); + msg = _mm_add_epi32(msg_2, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_3 = _mm_loadu_si128(((__m128i const*)(&buf[3 * 16]))); + msg_3 = _mm_shuffle_epi8(msg_3, reverse); + tmp = _mm_load_si128(((__m128i const*)(&K[3 * 4]))); + msg = _mm_add_epi32(msg_3, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_0 = _mm_sha256msg1_epu32(msg_0, msg_1); + tmp = _mm_alignr_epi8(msg_3, msg_2, k_alignr_epi8(1)); + msg_0 = _mm_add_epi32(msg_0, tmp); + msg_0 = _mm_sha256msg2_epu32(msg_0, msg_3); + tmp = _mm_load_si128(((__m128i const*)(&K[4 * 4]))); + msg = _mm_add_epi32(msg_0, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_1 = _mm_sha256msg1_epu32(msg_1, msg_2); + tmp = _mm_alignr_epi8(msg_0, msg_3, k_alignr_epi8(1)); + msg_1 = _mm_add_epi32(msg_1, tmp); + msg_1 = _mm_sha256msg2_epu32(msg_1, msg_0); + tmp = _mm_load_si128(((__m128i const*)(&K[5 * 4]))); + msg = _mm_add_epi32(msg_1, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_2 = _mm_sha256msg1_epu32(msg_2, msg_3); + tmp = _mm_alignr_epi8(msg_1, msg_0, k_alignr_epi8(1)); + msg_2 = _mm_add_epi32(msg_2, tmp); + msg_2 = _mm_sha256msg2_epu32(msg_2, msg_1); + tmp = _mm_load_si128(((__m128i const*)(&K[6 * 4]))); + msg = _mm_add_epi32(msg_2, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_3 = _mm_sha256msg1_epu32(msg_3, msg_0); + tmp = _mm_alignr_epi8(msg_2, msg_1, k_alignr_epi8(1)); + msg_3 = _mm_add_epi32(msg_3, tmp); + msg_3 = _mm_sha256msg2_epu32(msg_3, msg_2); + tmp = _mm_load_si128(((__m128i const*)(&K[7 * 4]))); + msg = _mm_add_epi32(msg_3, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_0 = _mm_sha256msg1_epu32(msg_0, msg_1); + tmp = _mm_alignr_epi8(msg_3, msg_2, k_alignr_epi8(1)); + msg_0 = _mm_add_epi32(msg_0, tmp); + msg_0 = _mm_sha256msg2_epu32(msg_0, msg_3); + tmp = _mm_load_si128(((__m128i const*)(&K[8 * 4]))); + msg = _mm_add_epi32(msg_0, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_1 = _mm_sha256msg1_epu32(msg_1, msg_2); + tmp = _mm_alignr_epi8(msg_0, msg_3, k_alignr_epi8(1)); + msg_1 = _mm_add_epi32(msg_1, tmp); + msg_1 = _mm_sha256msg2_epu32(msg_1, msg_0); + tmp = _mm_load_si128(((__m128i const*)(&K[9 * 4]))); + msg = _mm_add_epi32(msg_1, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_2 = _mm_sha256msg1_epu32(msg_2, msg_3); + tmp = _mm_alignr_epi8(msg_1, msg_0, k_alignr_epi8(1)); + msg_2 = _mm_add_epi32(msg_2, tmp); + msg_2 = _mm_sha256msg2_epu32(msg_2, msg_1); + tmp = _mm_load_si128(((__m128i const*)(&K[10 * 4]))); + msg = _mm_add_epi32(msg_2, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_3 = _mm_sha256msg1_epu32(msg_3, msg_0); + tmp = _mm_alignr_epi8(msg_2, msg_1, k_alignr_epi8(1)); + msg_3 = _mm_add_epi32(msg_3, tmp); + msg_3 = _mm_sha256msg2_epu32(msg_3, msg_2); + tmp = _mm_load_si128(((__m128i const*)(&K[11 * 4]))); + msg = _mm_add_epi32(msg_3, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_0 = _mm_sha256msg1_epu32(msg_0, msg_1); + tmp = _mm_alignr_epi8(msg_3, msg_2, k_alignr_epi8(1)); + msg_0 = _mm_add_epi32(msg_0, tmp); + msg_0 = _mm_sha256msg2_epu32(msg_0, msg_3); + tmp = _mm_load_si128(((__m128i const*)(&K[12 * 4]))); + msg = _mm_add_epi32(msg_0, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_1 = _mm_sha256msg1_epu32(msg_1, msg_2); + tmp = _mm_alignr_epi8(msg_0, msg_3, k_alignr_epi8(1)); + msg_1 = _mm_add_epi32(msg_1, tmp); + msg_1 = _mm_sha256msg2_epu32(msg_1, msg_0); + tmp = _mm_load_si128(((__m128i const*)(&K[13 * 4]))); + msg = _mm_add_epi32(msg_1, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_2 = _mm_sha256msg1_epu32(msg_2, msg_3); + tmp = _mm_alignr_epi8(msg_1, msg_0, k_alignr_epi8(1)); + msg_2 = _mm_add_epi32(msg_2, tmp); + msg_2 = _mm_sha256msg2_epu32(msg_2, msg_1); + tmp = _mm_load_si128(((__m128i const*)(&K[14 * 4]))); + msg = _mm_add_epi32(msg_2, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + msg_3 = _mm_sha256msg1_epu32(msg_3, msg_0); + tmp = _mm_alignr_epi8(msg_2, msg_1, k_alignr_epi8(1)); + msg_3 = _mm_add_epi32(msg_3, tmp); + msg_3 = _mm_sha256msg2_epu32(msg_3, msg_2); + tmp = _mm_load_si128(((__m128i const*)(&K[15 * 4]))); + msg = _mm_add_epi32(msg_3, tmp); + state_1 = _mm_sha256rnds2_epu32(state_1, state_0, msg); + msg = _mm_shuffle_epi32(msg, k_shuffle_epi32(k_any, k_any, 0x3, 0x2)); + state_0 = _mm_sha256rnds2_epu32(state_0, state_1, msg); + state_0 = _mm_add_epi32(state_0, old_0); + state_1 = _mm_add_epi32(state_1, old_1); + + tmp = _mm_shuffle_epi32(state_0, k_shuffle_epi32(0x0, 0x1, 0x2, 0x3)); + state_1 = _mm_shuffle_epi32(state_1, k_shuffle_epi32(0x2, 0x3, 0x0, 0x1)); + state_0 = ltc_mm_blend_epi32(tmp, state_1, k_blend_epi32(0x1, 0x1, 0x0, 0x0)); + state_1 = _mm_alignr_epi8(state_1, tmp, k_alignr_epi8(2)); + _mm_store_si128(((__m128i*)(&md->sha256.state[0])), state_0); + _mm_store_si128(((__m128i*)(&md->sha256.state[4])), state_1); + return CRYPT_OK; +} +#undef K + +#ifdef LTC_CLEAN_STACK +static int s_sha256_compress(hash_state * md, const unsigned char *buf) +{ + int err; + err = ss_sha256_compress(md, buf); + burn_stack(sizeof(ulong32) * 74); + return err; +} +#endif + +/** + Initialize the hash state + @param md The hash state you wish to initialize + @return CRYPT_OK if successful +*/ +int sha256_x86_init(hash_state * md) +{ + LTC_ARGCHK(md != NULL); + + md->sha256.state = LTC_ALIGN_BUF(md->sha256.state_buf, 16); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; + return CRYPT_OK; +} + +/** + Process a block of memory though the hash + @param md The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful +*/ +HASH_PROCESS(sha256_x86_process,s_sha256_x86_compress, sha256, 64) + +/** + Terminate the hash to get the digest + @param md The hash state + @param out [out] The destination of the hash (32 bytes) + @return CRYPT_OK if successful +*/ +int sha256_x86_done(hash_state * md, unsigned char *out) +{ + int i; + + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + if (md->sha256.curlen >= sizeof(md->sha256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->sha256.length += md->sha256.curlen * 8; + + /* append the '1' bit */ + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha256.curlen > 56) { + while (md->sha256.curlen < 64) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + s_sha256_x86_compress(md, md->sha256.buf); + md->sha256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha256.curlen < 56) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha256.length, md->sha256.buf+56); + s_sha256_x86_compress(md, md->sha256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->sha256.state[i], out+(4*i)); + } +#ifdef LTC_CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +/** + Self-test the hash + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled +*/ +int sha256_x86_test(void) +{ + return sha256_test_desc(&sha256_x86_desc, "SHA256 x86"); +} + +#endif diff --git a/src/hashes/sha2/sha512.c b/src/hashes/sha2/sha512.c index d6337af12..5086a823e 100644 --- a/src/hashes/sha2/sha512.c +++ b/src/hashes/sha2/sha512.c @@ -4,7 +4,7 @@ /** @param sha512.c - LTC_SHA512 by Tom St Denis + SHA512 by Tom St Denis */ #ifdef LTC_SHA512 @@ -28,6 +28,7 @@ const struct ltc_hash_descriptor sha512_desc = }; /* the K array */ +#define K sha512_K static const ulong64 K[80] = { CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), @@ -88,7 +89,12 @@ static int ss_sha512_compress(hash_state * md, const unsigned char *buf) static int s_sha512_compress(hash_state * md, const unsigned char *buf) #endif { - ulong64 S[8], W[80], t0, t1; + ulong64 S[8], t0, t1; +#ifdef LTC_SMALL_STACK + ulong64 W[16]; +#else + ulong64 W[80]; +#endif int i; /* copy state into S */ @@ -101,15 +107,36 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) LOAD64H(W[i], buf + (8*i)); } +#ifdef LTC_SMALL_STACK + #define Wi(i) W[(i) % 16] = Gamma1(W[((i) - 2) % 16]) + W[((i) - 7) % 16] + Gamma0(W[((i) - 15) % 16]) + W[((i) - 16) % 16]; + #define Windex(i) ((i) % 16) +#else + #define Wi(i) do { } while(0) + #define Windex(i) (i) + /* fill W[16..79] */ for (i = 16; i < 80; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; } +#endif /* Compress */ #ifdef LTC_SMALL_CODE - for (i = 0; i < 80; i++) { - t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; + for (i = 0; i < 16; i++) { + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[Windex(i)]; + t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3] + t0; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t0 + t1; + } + for (; i < 80; i++) { + Wi(i); + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[Windex(i)]; t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); S[7] = S[6]; S[6] = S[5]; @@ -121,13 +148,13 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) S[0] = t0 + t1; } #else -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[Windex(i)]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ h = t0 + t1; - for (i = 0; i < 80; i += 8) { + for (i = 0; i < 16; i += 8) { RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); @@ -137,7 +164,20 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); } + for (; i < 80; i += 8) { + Wi(i+0); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + Wi(i+1); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + Wi(i+2); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + Wi(i+3); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + Wi(i+4); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + Wi(i+5); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + Wi(i+6); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + Wi(i+7); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#undef RND #endif +#undef Wi +#undef Windex /* feedback */ @@ -147,6 +187,7 @@ static int s_sha512_compress(hash_state * md, const unsigned char *buf) return CRYPT_OK; } +#undef K /* compress 1024-bits */ #ifdef LTC_CLEAN_STACK diff --git a/src/hashes/sha3_test.c b/src/hashes/sha3_test.c index 80a3285bf..dfcdc5c2e 100644 --- a/src/hashes/sha3_test.c +++ b/src/hashes/sha3_test.c @@ -388,7 +388,7 @@ int sha3_shake_test(void) #endif } -#if defined LTC_TURBO_SHAKE || defined LTC_KANGAROO_TWELVE +#if (defined LTC_TURBO_SHAKE || defined LTC_KANGAROO_TWELVE) && defined LTC_TEST static LTC_INLINE int s_turbo_shake_generate_ptn(unsigned char* buffer, long offset, long amount) { long i; @@ -405,7 +405,7 @@ static LTC_INLINE int s_turbo_shake_generate_ptn(unsigned char* buffer, long off } #endif -#ifdef LTC_TURBO_SHAKE +#if defined(LTC_TURBO_SHAKE) && defined(LTC_TEST) typedef struct turbo_shake_test_case { int bits_count; unsigned long input_bytes_count, skip_digest_bytes, digest_bytes_count; @@ -509,7 +509,7 @@ int turbo_shake_test(void) } #endif -#ifdef LTC_KANGAROO_TWELVE +#if defined(LTC_KANGAROO_TWELVE) && defined(LTC_TEST) typedef struct kangaroo_twelve_test_case { int bits_count, is_ptn; unsigned long input_bytes_count, customization_bytes_count, skip_digest_bytes, digest_bytes_count; diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index b1f45b932..f0f5051e2 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -31,7 +31,6 @@ LTC_EXPORT void LTC_CALL XFREE(void *p); LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); - /* change the clock function too */ LTC_EXPORT clock_t LTC_CALL XCLOCK(void); @@ -244,7 +243,7 @@ typedef unsigned long ltc_mp_digit; #undef ENDIAN_32BITWORD #undef ENDIAN_64BITWORD #undef LTC_FAST - #define LTC_NO_AES_NI + #define LTC_NO_ACCEL #define LTC_NO_BSWAP #define LTC_NO_CLZL #define LTC_NO_CTZL @@ -252,6 +251,16 @@ typedef unsigned long ltc_mp_digit; #define LTC_NO_ROTATE #endif +/* Just portable C implementations */ +#ifdef LTC_NO_ACCEL + #define LTC_NO_AES_NI + #define LTC_NO_GCM_PCLMUL + #define LTC_NO_GCM_PMULL + #define LTC_NO_SHA1_X86 + #define LTC_NO_SHA224_X86 + #define LTC_NO_SHA256_X86 +#endif + /* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */ #if defined(LTC_NO_FAST) || (__GNUC__ < 4) || defined(__STRICT_ANSI__) #undef LTC_FAST @@ -306,13 +315,34 @@ typedef unsigned long ltc_mp_digit; #define LTC_HAVE_CTZL_BUILTIN #endif -#if !defined(LTC_NO_AES_NI) && (defined(__x86_64__) || defined(_M_X64)) -#define LTC_AES_NI +#if (defined(__x86_64__) || defined(__i386__) || defined(_M_X64) || defined(_M_IX86)) + #define LTC_ARCH_X86 + #if !defined(LTC_NO_AES_NI) + #define LTC_AES_NI + #endif + #if !defined(LTC_NO_GCM_PCLMUL) + #define LTC_GCM_PCLMUL + #undef LTC_GCM_TABLES + #endif + #if !defined(LTC_NO_SHA1_X86) + #define LTC_SHA1_X86 + #endif + #if !defined(LTC_NO_SHA224_X86) + #define LTC_SHA224_X86 + #endif + #if !defined(LTC_NO_SHA256_X86) + #define LTC_SHA256_X86 + #endif #endif #if defined(__GNUC__) + #define LTC_ALIGN_MSVC(n) #define LTC_ALIGN(n) __attribute__((aligned(n))) +#elif defined(_MSC_VER) + #define LTC_ALIGN_MSVC(n) __declspec(align(n)) + #define LTC_ALIGN(n) #else + #define LTC_ALIGN_MSVC(n) #define LTC_ALIGN(n) #endif @@ -367,4 +397,15 @@ typedef unsigned long ltc_mp_digit; # define LTC_ATTRIBUTE(x) #endif +#if !defined(LTC_NO_GCM_PMULL) && (defined(__aarch64__) || defined(_M_ARM64)) +#define LTC_GCM_PMULL +#undef LTC_GCM_TABLES +#endif + +#if defined(LTC_GCM_PMULL) && (defined(__clang__) || defined(__GNUC__)) +#define LTC_GCM_PMULL_TARGET __attribute__((target("+crypto"))) +#else +#define LTC_GCM_PMULL_TARGET +#endif + #endif /* TOMCRYPT_CFG_H */ diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index f2eca0cb8..6e900bb50 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -35,7 +35,7 @@ struct saferp_key { #ifdef LTC_RIJNDAEL struct rijndael_key { - unsigned char K[(60 + 60 + 4) * sizeof(ulong32)]; + unsigned char K[LTC_ALIGNED_BUF_SIZE(ulong32, 60 + 60, 16)]; ulong32 *eK; ulong32 *dK; int Nr; @@ -711,9 +711,9 @@ void rijndael_enc_done(symmetric_key *skey); int rijndael_enc_keysize(int *keysize); extern const struct ltc_cipher_descriptor rijndael_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc; +#endif int aesni_is_supported(void); -#endif #if defined(LTC_AES_NI) int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); @@ -1056,6 +1056,22 @@ int chacha_memory(const unsigned char *key, unsigned long keylen, unsigned l #endif /* LTC_CHACHA */ +#ifdef LTC_XCHACHA20 + +int xchacha20_hchacha20(unsigned char *out, unsigned long outlen, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + int rounds); +int xchacha20_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + int rounds); +int xchacha20_test(void); +int xchacha20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout); + +#endif /* LTC_XCHACHA20 */ + #ifdef LTC_SALSA20 typedef struct { diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index 740506f03..42ab7f5c8 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -126,6 +126,7 @@ #define LTC_RIJNDAEL #define LTC_SHA256 #define LTC_YARROW + #define LTC_ECB_MODE #define LTC_CTR_MODE #define LTC_RNG_MAKE_PRNG @@ -146,6 +147,9 @@ /* Use small code where possible */ /* #define LTC_SMALL_CODE */ +/* Always use small stack sizes where possible */ +/* #define LTC_SMALL_STACK */ + /* clean the stack of functions which put private information on stack */ /* #define LTC_CLEAN_STACK */ @@ -215,6 +219,7 @@ /* stream ciphers */ #define LTC_CHACHA +#define LTC_XCHACHA20 #define LTC_SALSA20 #define LTC_XSALSA20 #define LTC_SOSEMANUK @@ -300,7 +305,6 @@ #define LTC_EAX_MODE -#define LTC_OCB_MODE #define LTC_OCB3_MODE #define LTC_CCM_MODE #define LTC_GCM_MODE @@ -450,6 +454,9 @@ /* Ed25519 & X25519 */ #define LTC_CURVE25519 +/* Ed448 & X448 */ +#define LTC_CURVE448 + /* ECC */ #define LTC_MECC @@ -511,6 +518,10 @@ #define LTC_BCRYPT_DEFAULT_ROUNDS 10 #endif +#define LTC_ARGON2 + +#define LTC_SCRYPT + /* Keep LTC_NO_HKDF for compatibility reasons * superseeded by LTC_NO_MISC*/ #ifndef LTC_NO_HKDF @@ -606,6 +617,10 @@ /* Maximum recursion limit when processing nested ASN.1 types. */ #define LTC_DER_MAX_RECURSION 30 #endif + #ifndef LTC_DER_OID_DEFAULT_NODES + /* Default number of nodes when decoding an OID. */ + #define LTC_DER_OID_DEFAULT_NODES 12 + #endif #endif #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_SSH) @@ -678,6 +693,14 @@ #error LTC_BCRYPT requires LTC_BLOWFISH #endif +#if defined(LTC_ARGON2) && !defined(LTC_BLAKE2B) + #error LTC_ARGON2 requires LTC_BLAKE2B +#endif + +#if defined(LTC_SCRYPT) && (!defined(LTC_PKCS_5) || !defined(LTC_SHA256)) + #error LTC_SCRYPT requires LTC_PKCS_5 and LTC_SHA256 +#endif + #if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305)) #error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305 #endif @@ -686,6 +709,10 @@ #error LTC_CHACHA20_PRNG requires LTC_CHACHA #endif +#if defined(LTC_XCHACHA20) && !defined(LTC_CHACHA) + #error LTC_XCHACHA20 requires LTC_CHACHA +#endif + #if defined(LTC_XSALSA20) && !defined(LTC_SALSA20) #error LTC_XSALSA20 requires LTC_SALSA20 #endif @@ -728,7 +755,7 @@ #error LTC_ECB_MODE not defined, but all other modes depend on it #endif #if defined(LTC_OMAC) || defined(LTC_PMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_EAX_MODE) || \ - defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) ) + defined(LTC_OCB3_MODE) || defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE) ) #error LTC_ECB_MODE not defined, but most MAC and AEAD modes depend on it #endif #endif diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index 9996245a8..c80ad9590 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -37,16 +37,18 @@ struct sha512_state { #ifdef LTC_SHA256 struct sha256_state { ulong64 length; - ulong32 state[8], curlen; + ulong32 *state, curlen; unsigned char buf[64]; + unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 8, 16)]; }; #endif #ifdef LTC_SHA1 struct sha1_state { ulong64 length; - ulong32 state[5], curlen; + ulong32 *state, curlen; unsigned char buf[64]; + unsigned char state_buf[LTC_ALIGNED_BUF_SIZE(ulong32, 5, 16)]; }; #endif @@ -174,7 +176,7 @@ typedef union Hash_state { struct sha256_state sha256; #endif #ifdef LTC_SHA1 - struct sha1_state sha1; + struct sha1_state sha1; #endif #ifdef LTC_MD5 struct md5_state md5; @@ -360,7 +362,7 @@ int sha512_256_init(hash_state * md); int sha512_256_done(hash_state * md, unsigned char *out); int sha512_256_test(void); extern const struct ltc_hash_descriptor sha512_256_desc; -#endif +#endif /* LTC_SHA512_256 */ #ifdef LTC_SHA512_224 #ifndef LTC_SHA512 @@ -371,7 +373,9 @@ int sha512_224_init(hash_state * md); int sha512_224_done(hash_state * md, unsigned char *out); int sha512_224_test(void); extern const struct ltc_hash_descriptor sha512_224_desc; -#endif +#endif /* LTC_SHA512_224 */ + +int shani_is_supported(void); #ifdef LTC_SHA256 int sha256_init(hash_state * md); @@ -380,6 +384,21 @@ int sha256_done(hash_state * md, unsigned char *out); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; +int sha256_c_init(hash_state * md); +int sha256_c_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_c_done(hash_state * md, unsigned char *out); +int sha256_c_test(void); +extern const struct ltc_hash_descriptor sha256_portable_desc; + +#ifdef LTC_SHA256_X86 +int sha256_x86_init(hash_state * md); +int sha256_x86_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_x86_done(hash_state * md, unsigned char *out); +int sha256_x86_test(void); +extern const struct ltc_hash_descriptor sha256_x86_desc; +#endif /* LTC_SHA256_X86 */ +#endif /* LTC_SHA256 */ + #ifdef LTC_SHA224 #ifndef LTC_SHA256 #error LTC_SHA256 is required for LTC_SHA224 @@ -389,8 +408,21 @@ int sha224_init(hash_state * md); int sha224_done(hash_state * md, unsigned char *out); int sha224_test(void); extern const struct ltc_hash_descriptor sha224_desc; -#endif -#endif + +int sha224_c_init(hash_state * md); +#define sha224_c_process sha256_c_process +int sha224_c_done(hash_state * md, unsigned char *out); +int sha224_c_test(void); +extern const struct ltc_hash_descriptor sha224_portable_desc; + +#ifdef LTC_SHA224_X86 +int sha224_x86_init(hash_state * md); +#define sha224_x86_process sha256_x86_process +int sha224_x86_done(hash_state * md, unsigned char *out); +int sha224_x86_test(void); +extern const struct ltc_hash_descriptor sha224_x86_desc; +#endif /* LTC_SHA224_X86 */ +#endif /* LTC_SHA224 */ #ifdef LTC_SHA1 int sha1_init(hash_state * md); @@ -398,7 +430,21 @@ int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_done(hash_state * md, unsigned char *out); int sha1_test(void); extern const struct ltc_hash_descriptor sha1_desc; -#endif + +int sha1_c_init(hash_state * md); +int sha1_c_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_c_done(hash_state * md, unsigned char *out); +int sha1_c_test(void); +extern const struct ltc_hash_descriptor sha1_portable_desc; + +#ifdef LTC_SHA1_X86 +int sha1_x86_init(hash_state * md); +int sha1_x86_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_x86_done(hash_state * md, unsigned char *out); +int sha1_x86_test(void); +extern const struct ltc_hash_descriptor sha1_x86_desc; +#endif /* LTC_SHA1_X86 */ +#endif /* LTC_SHA1 */ #ifdef LTC_BLAKE2S extern const struct ltc_hash_descriptor blake2s_256_desc; diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index 2e067bc87..44f4a3ecd 100644 --- a/src/headers/tomcrypt_mac.h +++ b/src/headers/tomcrypt_mac.h @@ -285,61 +285,6 @@ int eax_decrypt_verify_memory(int cipher, int eax_test(void); #endif /* EAX MODE */ -#ifdef LTC_OCB_MODE -typedef struct { - unsigned char L[MAXBLOCKSIZE], /* L value */ - Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ - Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ - Lr[MAXBLOCKSIZE], /* L * x^-1 */ - R[MAXBLOCKSIZE], /* R value */ - checksum[MAXBLOCKSIZE]; /* current checksum */ - - symmetric_ECB key; /* scheduled key for cipher */ - unsigned long block_index; /* index # for current block */ - int block_len; /* length of block */ -} ocb_state; - -int ocb_init(ocb_state *ocb, int cipher, - const unsigned char *key, unsigned long keylen, const unsigned char *nonce); - -int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); -int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); - -int ocb_done_encrypt(ocb_state *ocb, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_done_decrypt(ocb_state *ocb, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, int *stat); - -int ocb_encrypt_authenticate_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tag, unsigned long *taglen); - -int ocb_decrypt_verify_memory(int cipher, - const unsigned char *key, unsigned long keylen, - const unsigned char *nonce, - const unsigned char *ct, unsigned long ctlen, - unsigned char *pt, - const unsigned char *tag, unsigned long taglen, - int *stat); - -int ocb_test(void); - -/* internal functions */ -void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); -int ocb_ntz(unsigned long x); -int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); - -#endif /* LTC_OCB_MODE */ - #ifdef LTC_OCB3_MODE typedef struct { unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */ @@ -560,11 +505,13 @@ int chacha20poly1305_test(void); int siv_encrypt_memory( int cipher, const unsigned char *key, unsigned long keylen, + unsigned long adnum, const unsigned char *ad[], unsigned long adlen[], const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned long *ctlen); int siv_decrypt_memory( int cipher, const unsigned char *key, unsigned long keylen, + unsigned long adnum, const unsigned char *ad[], unsigned long adlen[], const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned long *ptlen); @@ -572,6 +519,7 @@ int siv_memory( int cipher, int direction, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, + unsigned long adnum, ...) LTC_NULL_TERMINATED; int siv_test(void); diff --git a/src/headers/tomcrypt_macros.h b/src/headers/tomcrypt_macros.h index de2b51e16..16e370545 100644 --- a/src/headers/tomcrypt_macros.h +++ b/src/headers/tomcrypt_macros.h @@ -453,6 +453,11 @@ static inline ulong64 ROR64(ulong64 word, int i) #define LTC_UNUSED_PARAM(x) (void)(x) #endif +/* Calculates the number of bytes required to hold a buffer that will later on be + * aligned by using LTC_ALIGN_BUF(). + */ +#define LTC_ALIGNED_BUF_SIZE(type, n, align) (((n) + ((align)/sizeof(type))) * sizeof(type)) + /* there is no snprintf before Visual C++ 2015 */ #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf diff --git a/src/headers/tomcrypt_misc.h b/src/headers/tomcrypt_misc.h index 573591c0c..be63f5507 100644 --- a/src/headers/tomcrypt_misc.h +++ b/src/headers/tomcrypt_misc.h @@ -53,6 +53,32 @@ int base16_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); #endif +/* ---- Argon2 password hashing function (RFC 9106) ---- */ +#ifdef LTC_ARGON2 +typedef enum argon2_type { + ARGON2_D = 0, + ARGON2_I = 1, + ARGON2_ID = 2 +} argon2_type; + +int argon2_hash(const unsigned char *pwd, unsigned long pwdlen, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *secret, unsigned long secretlen, + const unsigned char *ad, unsigned long adlen, + unsigned int t_cost, unsigned int m_cost, + unsigned int parallelism, + argon2_type type, + unsigned char *out, unsigned long outlen); +#endif /* LTC_ARGON2 */ + +/* ---- scrypt password-based KDF (RFC 7914) ---- */ +#ifdef LTC_SCRYPT +int scrypt_pbkdf(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + unsigned long N, unsigned long r, unsigned long p, + unsigned char *out, unsigned long outlen); +#endif /* LTC_SCRYPT */ + #ifdef LTC_BCRYPT int bcrypt_pbkdf_openbsd(const void *secret, unsigned long secret_len, const unsigned char *salt, unsigned long salt_len, diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index a6b893128..582bedb7d 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -40,6 +40,9 @@ enum ltc_pka_id { LTC_PKA_X25519, LTC_PKA_ED25519, LTC_PKA_DH, + LTC_PKA_RSA_PSS, + LTC_PKA_X448, + LTC_PKA_ED448, LTC_PKA_NUM }; @@ -62,7 +65,16 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng); /* ---- RSA ---- */ #ifdef LTC_MRSA -/** RSA PKCS style key */ +typedef struct ltc_rsa_parameters { + /** saltLength for PSS */ + unsigned long saltlen; + /** Hash algorithm index for OAEP/PSS, -1 if unset */ + int hash_idx; + /** MGF1 hash algorithm index, -1 if unset */ + int mgf1_hash_idx; +} ltc_rsa_parameters; + +/** RSA key */ typedef struct Rsa_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; @@ -82,6 +94,10 @@ typedef struct Rsa_key { void *dP; /** The d mod (q - 1) CRT param */ void *dQ; + /** Key is constrained to PSS/OAEP operations */ + int pss_oaep; + /** PSS/OAEP parameters of the RSA key */ + ltc_rsa_parameters params; } rsa_key; int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); @@ -95,50 +111,131 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, void rsa_free(rsa_key *key); -/* These use PKCS #1 v2.0 padding */ -#define rsa_encrypt_key(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, key) \ - rsa_encrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, prng, prng_idx, hash_idx, -1, LTC_PKCS_1_OAEP, key) - -#define rsa_decrypt_key(in, inlen, out, outlen, lparam, lparamlen, hash_idx, stat, key) \ - rsa_decrypt_key_ex(in, inlen, out, outlen, lparam, lparamlen, hash_idx, -1, LTC_PKCS_1_OAEP, stat, key) - -#define rsa_sign_hash(in, inlen, out, outlen, prng, prng_idx, hash_idx, saltlen, key) \ - rsa_sign_hash_ex(in, inlen, out, outlen, LTC_PKCS_1_PSS, prng, prng_idx, hash_idx, saltlen, key) - -#define rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx, saltlen, stat, key) \ - rsa_verify_hash_ex(sig, siglen, hash, hashlen, LTC_PKCS_1_PSS, hash_idx, saltlen, stat, key) - -#define rsa_sign_saltlen_get_max(hash_idx, key) \ - rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key) +typedef struct ltc_rsa_op_parameters { + ltc_rsa_parameters params; + /* The padding type */ + int padding; + /* The PRNG to use. + * Only required for signing and encryption. */ + int wprng; + prng_state *prng; + /* Operation-specific parameters */ + union { + struct { + const unsigned char *lparam; + unsigned long lparamlen; + } crypt; + /* let's make space for potential future extensions */ + ulong64 dummy[8]; + } u; +} ltc_rsa_op_parameters; + +int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + const rsa_key *key); + +int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key); + +int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen, + unsigned char *sig, unsigned long *siglen, + ltc_rsa_op_parameters *params, + const rsa_key *key); + +int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key); +/* These use PKCS #1 v2.0 padding */ +#define ltc_rsa_encrypt_key(in, inlen, out, outlen, lp, lplen, prng_, prng_idx, hash_idx_, key) \ + rsa_encrypt_key_v2(in, inlen, out, outlen, \ + &(ltc_rsa_op_parameters){ \ + .u.crypt.lparam = lp, \ + .u.crypt.lparamlen = lplen,\ + .prng = prng_, \ + .wprng = prng_idx, \ + .params.mgf1_hash_idx = hash_idx_, \ + .params.hash_idx = hash_idx_, \ + .padding = LTC_PKCS_1_OAEP, \ + }, key) + +#define ltc_rsa_decrypt_key(in, inlen, out, outlen, lp, lplen, hash_idx_, stat, key) \ + rsa_decrypt_key_v2(in, inlen, out, outlen, \ + &(ltc_rsa_op_parameters){ \ + .u.crypt.lparam = lp, \ + .u.crypt.lparamlen = lplen,\ + .params.mgf1_hash_idx = hash_idx_, \ + .params.hash_idx = hash_idx_, \ + .padding = LTC_PKCS_1_OAEP, \ + }, stat, key) + +#define ltc_rsa_sign_hash(hash, hashlen, sig, siglen, prng_, prng_idx, hash_idx_, saltlen_, key) \ + rsa_sign_hash_v2(hash, hashlen, sig, siglen, \ + &(ltc_rsa_op_parameters){ \ + .prng = prng_, \ + .wprng = prng_idx, \ + .params.mgf1_hash_idx = hash_idx_, \ + .params.hash_idx = hash_idx_, \ + .params.saltlen = saltlen_, \ + .padding = LTC_PKCS_1_PSS, \ + }, key) + +#define ltc_rsa_verify_hash(sig, siglen, hash, hashlen, hash_idx_, saltlen_, stat, key) \ + rsa_verify_hash_v2(sig, siglen, hash, hashlen, \ + &(ltc_rsa_op_parameters){ \ + .params.mgf1_hash_idx = hash_idx_, \ + .params.hash_idx = hash_idx_, \ + .params.saltlen = saltlen_, \ + .padding = LTC_PKCS_1_PSS, \ + }, stat, key) + +/* If you used those in v1, they're still working */ +#define rsa_encrypt_key ltc_rsa_encrypt_key +#define rsa_decrypt_key ltc_rsa_decrypt_key +#define rsa_sign_hash ltc_rsa_sign_hash +#define rsa_verify_hash ltc_rsa_verify_hash + +#ifndef LTC_NO_DEPRECATED_APIS /* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ +LTC_DEPRECATED(rsa_encrypt_key_v2) int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, - int mgf_hash, int lparam_hash, - int padding, + int hash_idx, int padding, const rsa_key *key); +LTC_DEPRECATED(rsa_decrypt_key_v2) int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, - int mgf_hash, int lparam_hash, - int padding, + int hash_idx, int padding, int *stat, const rsa_key *key); +LTC_DEPRECATED(rsa_sign_hash_v2) int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int padding, - prng_state *prng, int prng_idx, + prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, const rsa_key *key); +LTC_DEPRECATED(rsa_verify_hash_v2) int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int padding, int hash_idx, unsigned long saltlen, int *stat, const rsa_key *key); +#endif /* LTC_NO_DEPRECATED_APIS */ + +#define rsa_sign_saltlen_get_max(hash_idx, key) \ + rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, hash_idx, key) int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, const rsa_key *key); @@ -309,7 +406,8 @@ typedef struct ltc_ecc_sig_opts { * This must be set in case one requires the recovery ID of a * signature operation. */ - int *recid; + unsigned char enable_recovery_id; + int recovery_id; /** The hash algorithm to use when creating a signature. * Setting this will enable RFC6979 compatible signature generation. @@ -533,6 +631,80 @@ int x25519_shared_secret(const curve25519_key *private_key, #endif /* LTC_CURVE25519 */ + +#ifdef LTC_CURVE448 + +typedef struct { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + enum public_key_type type; + /** Algorithm: LTC_PKA_X448 or LTC_PKA_ED448 */ + enum ltc_pka_id pka; + /** The private key (56 bytes for X448, 57 bytes for Ed448) */ + unsigned char priv[57]; + /** The public key (56 bytes for X448, 57 bytes for Ed448) */ + unsigned char pub[57]; +} curve448_key; + +/** X448 Diffie-Hellman key exchange */ +int x448_make_key(prng_state *prng, int wprng, curve448_key *key); + +int x448_export( unsigned char *out, unsigned long *outlen, + int which, + const curve448_key *key); + +int x448_import(const unsigned char *in, unsigned long inlen, curve448_key *key); +int x448_import_raw(const unsigned char *in, unsigned long inlen, int which, curve448_key *key); +int x448_import_x509(const unsigned char *in, unsigned long inlen, curve448_key *key); +int x448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key); + +int x448_shared_secret(const curve448_key *private_key, + const curve448_key *public_key, + unsigned char *out, unsigned long *outlen); + +/** Ed448 Signature API */ +int ed448_make_key(prng_state *prng, int wprng, curve448_key *key); + +int ed448_export( unsigned char *out, unsigned long *outlen, + int which, + const curve448_key *key); + +int ed448_import(const unsigned char *in, unsigned long inlen, curve448_key *key); +int ed448_import_raw(const unsigned char *in, unsigned long inlen, int which, curve448_key *key); +int ed448_import_x509(const unsigned char *in, unsigned long inlen, curve448_key *key); +int ed448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key); + +int ed448_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const curve448_key *private_key); +int ed448ctx_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key); +int ed448ph_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key); +int ed448_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + int *stat, + const curve448_key *public_key); +int ed448ctx_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key); +int ed448ph_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key); + +#endif /* LTC_CURVE448 */ + #ifdef LTC_MDSA /* Max diff between group and modulus size in bytes (max case: L=8192bits, N=256bits) */ @@ -628,6 +800,10 @@ typedef struct { curve25519_key x25519; curve25519_key ed25519; #endif +#ifdef LTC_CURVE448 + curve448_key x448; + curve448_key ed448; +#endif #ifdef LTC_MDH dh_key dh; #endif diff --git a/src/headers/tomcrypt_pkcs.h b/src/headers/tomcrypt_pkcs.h index cca013c07..f3037f147 100644 --- a/src/headers/tomcrypt_pkcs.h +++ b/src/headers/tomcrypt_pkcs.h @@ -20,14 +20,19 @@ enum ltc_pkcs_1_paddings LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */ }; +#ifndef LTC_NO_DEPRECATED_APIS +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_mgf1( int hash_idx, const unsigned char *seed, unsigned long seedlen, unsigned char *mask, unsigned long masklen); +LTC_DEPRECATED(nothing. API will be removed) int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +LTC_DEPRECATED(nothing. API will be removed) int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); /* *** v1.5 padding */ +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned long msglen, int block_type, @@ -37,6 +42,7 @@ int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_v1_5_decode(const unsigned char *msg, unsigned long msglen, int block_type, @@ -46,30 +52,33 @@ int pkcs_1_v1_5_decode(const unsigned char *msg, int *is_valid); /* *** v2.1 padding */ +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, - int prng_idx, - int mgf_hash, int lparam_hash, + int prng_idx, int hash_idx, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, - int mgf_hash, int lparam_hash, + unsigned long modulus_bitlen, int hash_idx, unsigned char *out, unsigned long *outlen, int *res); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen); +LTC_DEPRECATED(nothing. API will be internal) int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, const unsigned char *sig, unsigned long siglen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res); +#endif /* LTC_NO_DEPRECATED_APIS */ #endif /* LTC_PKCS_1 */ diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 16afb8b9e..557e01db8 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -33,7 +33,7 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*) /* Aligns a `unsigned char` buffer `buf` to `n` bytes and returns that aligned address. * Make sure that the buffer that is passed is huge enough. */ -#define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1))))) +#define LTC_ALIGN_BUF(buf, align) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[(align) - 1] & (~(CONSTPTR(align) - CONSTPTR(1))))) #define LTC_OID_MAX_STRLEN 256 @@ -59,7 +59,12 @@ enum ltc_oid_id { LTC_OID_EC_PRIMEF, LTC_OID_X25519, LTC_OID_ED25519, + LTC_OID_X448, + LTC_OID_ED448, LTC_OID_DH, + LTC_OID_RSA_OAEP, + LTC_OID_RSA_MGF1, + LTC_OID_RSA_PSS, LTC_OID_NUM }; @@ -180,6 +185,18 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) } +#define LTC_SHA_TARGET LTC_ATTRIBUTE((__target__("sse2,ssse3,sse4.1,sha"))) + +#ifdef LTC_SHA1 +int sha1_test_desc(const struct ltc_hash_descriptor *desc, const char *name); +#endif +#ifdef LTC_SHA224 +int sha224_test_desc(const struct ltc_hash_descriptor *desc, const char *name); +#endif +#ifdef LTC_SHA256 +int sha256_test_desc(const struct ltc_hash_descriptor *desc, const char *name); +#endif + /* tomcrypt_mac.h */ int ocb3_int_ntz(unsigned long x); @@ -441,14 +458,60 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size); -/* ---- DH Routines ---- */ +/* ---- RSA Routines ---- */ #ifdef LTC_MRSA +/* Receiving side, i.e. Decrypt or Verify */ +#define LTC_RSA_OP_RECV 0x00u +/* Sending side, i.e. Encrypt or Sign */ +#define LTC_RSA_OP_SEND 0x01u +/* En- or Decrypt */ +#define LTC_RSA_OP_CRYPT 0x00u +/* Sign or Verify */ +#define LTC_RSA_OP_SIGN 0x02u +/* All combinations of the above + * but only the PKCS#1 de-/encoding part */ +#define LTC_RSA_OP_PKCS1 0x04u + +typedef enum ltc_rsa_op { + LTC_RSA_DECRYPT = LTC_RSA_OP_CRYPT | LTC_RSA_OP_RECV, + LTC_RSA_ENCRYPT = LTC_RSA_OP_CRYPT | LTC_RSA_OP_SEND, + LTC_RSA_VERIFY = LTC_RSA_OP_SIGN | LTC_RSA_OP_RECV, + LTC_RSA_SIGN = LTC_RSA_OP_SIGN | LTC_RSA_OP_SEND, + LTC_PKCS1_ENCRYPT = LTC_RSA_OP_PKCS1 | LTC_RSA_ENCRYPT, + LTC_PKCS1_DECRYPT = LTC_RSA_OP_PKCS1 | LTC_RSA_DECRYPT, + LTC_PKCS1_SIGN = LTC_RSA_OP_PKCS1 | LTC_RSA_SIGN, + LTC_PKCS1_VERIFY = LTC_RSA_OP_PKCS1 | LTC_RSA_VERIFY, +} ltc_rsa_op; + +typedef struct ltc_rsa_op_checked { + const rsa_key *key; + ltc_rsa_op_parameters *params; + int hash_alg, mgf1_hash_alg; +} ltc_rsa_op_checked; + +#define ltc_rsa_op_checked_init(k, p) { \ + .key = k, \ + .params = p, \ + .hash_alg = -1, \ + .mgf1_hash_alg = -1, \ +} + +#define ltc_pkcs1_op_checked_init(p) ltc_rsa_op_checked_init(NULL, p) + int rsa_init(rsa_key *key); void rsa_shrink_key(rsa_key *key); +int rsa_args_to_op_params(const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, + int padding, unsigned long saltlen, + ltc_rsa_op_parameters *params); +int rsa_key_valid_op(ltc_rsa_op op, ltc_rsa_op_checked *params); +int rsa_params_equal(const ltc_rsa_parameters *a, const ltc_rsa_parameters *b); int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e, rsa_key *key); /* used by op-tee */ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key); int rsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, rsa_key *key); +int rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key); +int rsa_decode_parameters(const ltc_asn1_list *parameters, rsa_key *key); #endif /* LTC_MRSA */ /* ---- DH Routines ---- */ @@ -608,8 +671,8 @@ int dsa_int_validate(const dsa_key *key, int *stat); int dsa_int_validate_xy(const dsa_key *key, int *stat); int dsa_int_validate_pqg(const dsa_key *key, int *stat); int dsa_int_validate_primes(const dsa_key *key, int *stat); -int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key); int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key); +int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key); #endif /* LTC_MDSA */ @@ -652,6 +715,33 @@ int ec25519_crypto_ctx( unsigned char *out, unsigned long *outlen, const unsigned char *ctx, unsigned long ctxlen); #endif /* LTC_CURVE25519 */ +#ifdef LTC_CURVE448 +int ec448_export(unsigned char *out, unsigned long *outlen, int which, const curve448_key *key); +int ec448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, enum ltc_oid_id id, curve448_key *key); +int ec448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + enum ltc_oid_id id, curve448_key *key); +int x448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + curve448_key *key); +int ec448_keypair_internal(prng_state *prng, int wprng, unsigned char *pk, unsigned char *sk); +int ec448_sk_to_pk_internal(unsigned char *pk, const unsigned char *sk); +int ec448_sign_internal(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk, const unsigned char *pk, + const unsigned char *ctx, unsigned long long cs); +int ec448_verify_internal(int *stat, unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *ctx, unsigned long long cs, + const unsigned char *pk); +int ec448_prehash_internal(unsigned char *out, const unsigned char *msg, unsigned long long msglen); +int ec448_crypto_ctx(unsigned char *out, unsigned long *outlen, unsigned char flag, + const unsigned char *ctx, unsigned long ctxlen); +int ec448_scalarmult_internal(unsigned char *out, const unsigned char *scalar, const unsigned char *point); +int ec448_scalarmult_base_internal(unsigned char *out, const unsigned char *scalar); +int ed448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + curve448_key *key); +#endif /* LTC_CURVE448 */ + #ifdef LTC_DER #define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t))) @@ -724,13 +814,17 @@ int der_teletex_value_decode(int v); int der_utf8_valid_char(const wchar_t c); -typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *ctx); +typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *key); int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, enum ltc_oid_id algorithm, ltc_asn1_type param_type, ltc_asn1_list* parameters, unsigned long *parameters_len, - public_key_decode_cb callback, void *ctx); -int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki); + public_key_decode_cb callback, void *key); +int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, const ltc_asn1_list **spki); +int x509_process_public_key_from_spki(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key); /* SUBJECT PUBLIC KEY INFO */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, @@ -741,7 +835,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i enum ltc_oid_id algorithm, void *public_key, unsigned long *public_key_len, ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); -int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka); +int x509_get_pka(const ltc_asn1_list *pub, enum ltc_pka_id *pka); int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root); int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); @@ -750,6 +844,46 @@ int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); /* tomcrypt_pkcs.h */ +#ifdef LTC_PKCS_1 +int ltc_pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen); + +int ltc_pkcs_1_pss_encode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); +int ltc_pkcs_1_pss_decode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, int *res); +int ltc_pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); +int ltc_pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen, + int *res); + +int ltc_pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); +int ltc_pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); +#endif /* LTC_PKCS_1 */ + #ifdef LTC_PKCS_8 /* Public-Key Cryptography Standards (PKCS) #8: diff --git a/src/mac/hmac/hmac_file.c b/src/mac/hmac/hmac_file.c index c944a285d..d0d1ce005 100644 --- a/src/mac/hmac/hmac_file.c +++ b/src/mac/hmac/hmac_file.c @@ -39,7 +39,7 @@ int hmac_file(int hash, const char *fname, int err; LTC_ARGCHK(fname != NULL); - LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key != NULL || keylen == 0); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); diff --git a/src/mac/hmac/hmac_init.c b/src/mac/hmac/hmac_init.c index 50c5bcc96..a4c40eb2d 100644 --- a/src/mac/hmac/hmac_init.c +++ b/src/mac/hmac/hmac_init.c @@ -27,7 +27,7 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon int err; LTC_ARGCHK(hmac != NULL); - LTC_ARGCHK(key != NULL); + LTC_ARGCHK(key != NULL || keylen == 0); /* valid hash? */ if ((err = hash_is_valid(hash)) != CRYPT_OK) { @@ -36,11 +36,6 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon hmac->hash = hash; hashsize = hash_descriptor[hash].hashsize; - /* valid key length? */ - if (keylen == 0) { - return CRYPT_INVALID_KEYSIZE; - } - /* allocate ram for buf */ buf = XMALLOC(LTC_HMAC_BLOCKSIZE); if (buf == NULL) { @@ -60,7 +55,7 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon goto LBL_ERR; } keylen = hashsize; - } else { + } else if (keylen != 0) { XMEMCPY(hmac->key, key, (size_t)keylen); } diff --git a/src/mac/hmac/hmac_memory.c b/src/mac/hmac/hmac_memory.c index 221be5809..acbb86ab8 100644 --- a/src/mac/hmac/hmac_memory.c +++ b/src/mac/hmac/hmac_memory.c @@ -28,8 +28,8 @@ int hmac_memory(int hash, hmac_state *hmac; int err; - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL || keylen == 0); + LTC_ARGCHK(in != NULL || inlen == 0); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); diff --git a/src/mac/hmac/hmac_memory_multi.c b/src/mac/hmac/hmac_memory_multi.c index a82035c4c..403bd6d79 100644 --- a/src/mac/hmac/hmac_memory_multi.c +++ b/src/mac/hmac/hmac_memory_multi.c @@ -34,8 +34,8 @@ int hmac_memory_multi(int hash, const unsigned char *curptr; unsigned long curlen; - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL || keylen == 0); + LTC_ARGCHK(in != NULL || inlen == 0); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); diff --git a/src/mac/hmac/hmac_process.c b/src/mac/hmac/hmac_process.c index 14738b65e..86d731e4b 100644 --- a/src/mac/hmac/hmac_process.c +++ b/src/mac/hmac/hmac_process.c @@ -20,7 +20,8 @@ int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) { int err; LTC_ARGCHK(hmac != NULL); - LTC_ARGCHK(in != NULL); + LTC_ARGCHK(in != NULL || inlen == 0); + if (inlen == 0) return CRYPT_OK; if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { return err; } diff --git a/src/mac/hmac/hmac_test.c b/src/mac/hmac/hmac_test.c index f22a37096..14aa111cb 100644 --- a/src/mac/hmac/hmac_test.c +++ b/src/mac/hmac/hmac_test.c @@ -48,6 +48,13 @@ int hmac_test(void) return CRYPT_NOP; #else unsigned char digest[MAXBLOCKSIZE]; + static const unsigned char empty_key_sha256_expected[32] = { + 0xfd, 0x7a, 0xdb, 0x15, 0x2c, 0x05, 0xef, 0x80, + 0xdc, 0xcf, 0x50, 0xa1, 0xfa, 0x4c, 0x05, 0xd5, + 0xa3, 0xec, 0x6d, 0xa9, 0x55, 0x75, 0xfc, 0x31, + 0x2a, 0xe7, 0xc5, 0xd0, 0x91, 0x83, 0x63, 0x51 + }; + static const unsigned char empty_key_msg[] = { 'a', 'b', 'c' }; int i; static const unsigned char hmac_test_case_keys[][136] = { @@ -610,6 +617,17 @@ int hmac_test(void) if (tested == 0) { return CRYPT_NOP; } + + i = find_hash("sha256"); + if (i != -1) { + outlen = sizeof(digest); + if ((err = hmac_memory(i, NULL, 0, empty_key_msg, sizeof(empty_key_msg), digest, &outlen)) != CRYPT_OK) { + return err; + } + if (ltc_compare_testvector(digest, outlen, empty_key_sha256_expected, sizeof(empty_key_sha256_expected), "empty-key sha256", (unsigned long)i)) { + return CRYPT_FAIL_TESTVECTOR; + } + } return CRYPT_OK; #endif } diff --git a/src/mac/omac/omac_process.c b/src/mac/omac/omac_process.c index 35ee9d261..d2183d507 100644 --- a/src/mac/omac/omac_process.c +++ b/src/mac/omac/omac_process.c @@ -23,7 +23,7 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) int err; LTC_ARGCHK(omac != NULL); - LTC_ARGCHK(in != NULL); + LTC_ARGCHK(in != NULL || inlen == 0); if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { diff --git a/src/math/rand_prime.c b/src/math/rand_prime.c index 0cd6c0dce..6f13806ce 100644 --- a/src/math/rand_prime.c +++ b/src/math/rand_prime.c @@ -9,21 +9,19 @@ Generate a random prime, Tom St Denis */ -#define USE_BBS 1 - int rand_prime(void *N, long len, prng_state *prng, int wprng) { - int err, res, type; - unsigned char *buf; + int err, res; + unsigned char *buf, bbs; LTC_ARGCHK(N != NULL); - /* get type */ if (len < 0) { - type = USE_BBS; + /* Create BBS (Blum Blum Shub) style prime */ + bbs = 0x02; len = -len; } else { - type = 0; + bbs = 0x00; } /* allow sizes between 2 and 512 bytes for a prime size */ @@ -51,7 +49,7 @@ int rand_prime(void *N, long len, prng_state *prng, int wprng) /* munge bits */ buf[0] |= 0x80 | 0x40; - buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + buf[len-1] |= 0x01 | bbs; /* load value */ if ((err = ltc_mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { diff --git a/src/misc/argon2/argon2.c b/src/misc/argon2/argon2.c new file mode 100644 index 000000000..1af2b2858 --- /dev/null +++ b/src/misc/argon2/argon2.c @@ -0,0 +1,564 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file argon2.c + Argon2 password hashing function (RFC 9106) +*/ +#ifdef LTC_ARGON2 + +#define ARGON2_BLOCK_SIZE 1024 +#define ARGON2_QWORDS_IN_BLOCK 128 +#define ARGON2_ADDRESSES_IN_BLOCK 128 +#define ARGON2_PREHASH_DIGEST_LEN 64 +#define ARGON2_PREHASH_SEED_LEN 72 +#define ARGON2_SYNC_POINTS 4 +#define ARGON2_VERSION 0x13 +#define ARGON2_MIN_OUTLEN 4 +#define ARGON2_BLAKE2B_OUTBYTES 64 + +/* 1024-byte memory block */ +typedef struct argon2_block { + ulong64 v[ARGON2_QWORDS_IN_BLOCK]; +} argon2_block; + +/* instance state */ +typedef struct argon2_instance { + argon2_block *memory; + ulong32 passes; + ulong32 memory_blocks; + ulong32 segment_length; + ulong32 lane_length; + ulong32 lanes; + int type; /* 0=d 1=i 2=id */ +} argon2_instance; + +/* position within the memory matrix */ +typedef struct argon2_position { + ulong32 pass; + ulong32 lane; + unsigned char slice; + ulong32 index; +} argon2_position; + +static void s_block_init(argon2_block *b, unsigned char v) +{ + XMEMSET(b->v, v, sizeof(b->v)); +} + +static void s_block_copy(argon2_block *dst, const argon2_block *src) +{ + XMEMCPY(dst->v, src->v, sizeof(dst->v)); +} + +static void s_block_xor(argon2_block *dst, const argon2_block *src) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +static void s_block_load(argon2_block *dst, const unsigned char *input) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + LOAD64L(dst->v[i], input + i * 8); + } +} + +static void s_block_store(unsigned char *output, const argon2_block *src) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + STORE64L(src->v[i], output + i * 8); + } +} + +/* Variable-length hash H' (RFC 9106 Section 3.2) */ +static int s_blake2b_hash(unsigned char *out, unsigned long outlen, const unsigned char *in, unsigned long inlen) +{ + hash_state md; + int err; + + if ((err = blake2b_init(&md, outlen, NULL, 0)) != CRYPT_OK) return err; + if ((err = blake2b_process(&md, in, inlen)) != CRYPT_OK) return err; + if ((err = blake2b_done(&md, out)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +static int s_blake2b_long(unsigned char *out, unsigned long outlen, const unsigned char *in, unsigned long inlen) +{ + unsigned char outlen_le[4]; + int err; + + STORE32L((ulong32)outlen, outlen_le); + + if (outlen <= ARGON2_BLAKE2B_OUTBYTES) { + /* single hash with truncated output */ + hash_state md; + if ((err = blake2b_init(&md, outlen, NULL, 0)) != CRYPT_OK) return err; + if ((err = blake2b_process(&md, outlen_le, 4)) != CRYPT_OK) return err; + if ((err = blake2b_process(&md, in, inlen)) != CRYPT_OK) return err; + if ((err = blake2b_done(&md, out)) != CRYPT_OK) return err; + } + else { + /* chained hashing for longer outputs */ + ulong32 toproduce; + unsigned char out_buffer[ARGON2_BLAKE2B_OUTBYTES]; + unsigned char in_buffer[ARGON2_BLAKE2B_OUTBYTES]; + hash_state md; + + if ((err = blake2b_init(&md, ARGON2_BLAKE2B_OUTBYTES, NULL, 0)) != CRYPT_OK) return err; + if ((err = blake2b_process(&md, outlen_le, 4)) != CRYPT_OK) return err; + if ((err = blake2b_process(&md, in, inlen)) != CRYPT_OK) return err; + if ((err = blake2b_done(&md, out_buffer)) != CRYPT_OK) return err; + + XMEMCPY(out, out_buffer, ARGON2_BLAKE2B_OUTBYTES / 2); + out += ARGON2_BLAKE2B_OUTBYTES / 2; + toproduce = (ulong32)outlen - ARGON2_BLAKE2B_OUTBYTES / 2; + + while (toproduce > ARGON2_BLAKE2B_OUTBYTES) { + XMEMCPY(in_buffer, out_buffer, ARGON2_BLAKE2B_OUTBYTES); + if ((err = s_blake2b_hash(out_buffer, ARGON2_BLAKE2B_OUTBYTES, in_buffer, ARGON2_BLAKE2B_OUTBYTES)) != CRYPT_OK) return err; + XMEMCPY(out, out_buffer, ARGON2_BLAKE2B_OUTBYTES / 2); + out += ARGON2_BLAKE2B_OUTBYTES / 2; + toproduce -= ARGON2_BLAKE2B_OUTBYTES / 2; + } + + XMEMCPY(in_buffer, out_buffer, ARGON2_BLAKE2B_OUTBYTES); + if ((err = s_blake2b_hash(out_buffer, toproduce, in_buffer, ARGON2_BLAKE2B_OUTBYTES)) != CRYPT_OK) return err; + XMEMCPY(out, out_buffer, toproduce); + } + return CRYPT_OK; +} + +/* BlaMka compression G (RFC 9106 Section 3.4 / 3.5) */ +static LTC_INLINE ulong64 s_fBlaMka(ulong64 x, ulong64 y) +{ + ulong64 m = CONST64(0xFFFFFFFF); + ulong64 xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define ARGON2_GB(a, b, c, d) \ + do { \ + a = s_fBlaMka(a, b); \ + d = ROR64(d ^ a, 32); \ + c = s_fBlaMka(c, d); \ + b = ROR64(b ^ c, 24); \ + a = s_fBlaMka(a, b); \ + d = ROR64(d ^ a, 16); \ + c = s_fBlaMka(c, d); \ + b = ROR64(b ^ c, 63); \ + } while (0) + +#define ARGON2_ROUND(v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15) \ + do { \ + ARGON2_GB(v0, v4, v8, v12); \ + ARGON2_GB(v1, v5, v9, v13); \ + ARGON2_GB(v2, v6, v10, v14); \ + ARGON2_GB(v3, v7, v11, v15); \ + ARGON2_GB(v0, v5, v10, v15); \ + ARGON2_GB(v1, v6, v11, v12); \ + ARGON2_GB(v2, v7, v8, v13); \ + ARGON2_GB(v3, v4, v9, v14); \ + } while (0) + +/* Fill a new block from prev_block and ref_block. If with_xor, XOR result with existing next_block content. */ +static void s_fill_block(const argon2_block *prev_block, const argon2_block *ref_block, argon2_block *next_block, int with_xor) +{ + argon2_block blockR, block_tmp; + unsigned i; + + s_block_copy(&blockR, ref_block); + s_block_xor(&blockR, prev_block); + s_block_copy(&block_tmp, &blockR); + + if (with_xor) { + s_block_xor(&block_tmp, next_block); + } + + /* Apply P on columns: (0..15), (16..31), ..., (112..127) */ + for (i = 0; i < 8; ++i) { + ARGON2_ROUND( + blockR.v[16*i], blockR.v[16*i+1], blockR.v[16*i+2], blockR.v[16*i+3], + blockR.v[16*i+4], blockR.v[16*i+5], blockR.v[16*i+6], blockR.v[16*i+7], + blockR.v[16*i+8], blockR.v[16*i+9], blockR.v[16*i+10], blockR.v[16*i+11], + blockR.v[16*i+12], blockR.v[16*i+13], blockR.v[16*i+14], blockR.v[16*i+15]); + } + + /* Apply P on rows: (0,1,16,17,32,33,...,112,113), etc. */ + for (i = 0; i < 8; ++i) { + ARGON2_ROUND( + blockR.v[2*i], blockR.v[2*i+1], blockR.v[2*i+16], blockR.v[2*i+17], + blockR.v[2*i+32], blockR.v[2*i+33], blockR.v[2*i+48], blockR.v[2*i+49], + blockR.v[2*i+64], blockR.v[2*i+65], blockR.v[2*i+80], blockR.v[2*i+81], + blockR.v[2*i+96], blockR.v[2*i+97], blockR.v[2*i+112],blockR.v[2*i+113]); + } + + s_block_copy(next_block, &block_tmp); + s_block_xor(next_block, &blockR); +} + +/* Generate next pseudo-random addresses for data-independent indexing */ +static void s_next_addresses(argon2_block *address_block, argon2_block *input_block, const argon2_block *zero_block) +{ + input_block->v[6]++; + s_fill_block(zero_block, input_block, address_block, 0); + s_fill_block(zero_block, address_block, address_block, 0); +} + +/* Index computation (RFC 9106 Section 3.3) */ +static ulong32 s_index_alpha(const argon2_instance *instance, const argon2_position *position, ulong32 pseudo_rand, int same_lane) +{ + ulong32 reference_area_size; + ulong64 relative_position; + ulong32 start_position, absolute_position; + + if (position->pass == 0) { + if (position->slice == 0) { + reference_area_size = position->index - 1; + } + else { + if (same_lane) { + reference_area_size = position->slice * instance->segment_length + position->index - 1; + } + else { + reference_area_size = position->slice * instance->segment_length + ((position->index == 0) ? ((ulong32)-1) : 0); + } + } + } + else { + if (same_lane) { + reference_area_size = instance->lane_length - instance->segment_length + position->index - 1; + } + else { + reference_area_size = instance->lane_length - instance->segment_length + ((position->index == 0) ? ((ulong32)-1) : 0); + } + } + + /* Map pseudo_rand to 0..reference_area_size-1 */ + relative_position = (ulong64)pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - ((ulong64)reference_area_size * relative_position >> 32); + + start_position = 0; + if (position->pass != 0) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) ? 0 : (position->slice + 1) * instance->segment_length; + } + absolute_position = (start_position + (ulong32)relative_position) % instance->lane_length; + return absolute_position; +} + +/* Fill one segment (lane x slice intersection) */ +static void s_fill_segment(const argon2_instance *instance, argon2_position position) +{ + argon2_block *ref_block, *curr_block; + argon2_block address_block, input_block, zero_block; + ulong64 pseudo_rand; + ulong32 ref_index, prev_offset, curr_offset; + ulong32 starting_index, i; + ulong64 ref_lane; + int data_independent; + + data_independent = (instance->type == ARGON2_I) || (instance->type == ARGON2_ID && position.pass == 0 && position.slice < ARGON2_SYNC_POINTS / 2); + + if (data_independent) { + s_block_init(&zero_block, 0); + s_block_init(&input_block, 0); + input_block.v[0] = position.pass; + input_block.v[1] = position.lane; + input_block.v[2] = position.slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + } + + starting_index = 0; + if (position.pass == 0 && position.slice == 0) { + starting_index = 2; + if (data_independent) { + s_next_addresses(&address_block, &input_block, &zero_block); + } + } + + curr_offset = position.lane * instance->lane_length + position.slice * instance->segment_length + starting_index; + + if (curr_offset % instance->lane_length == 0) { + prev_offset = curr_offset + instance->lane_length - 1; + } + else { + prev_offset = curr_offset - 1; + } + + for (i = starting_index; i < instance->segment_length; ++i, ++curr_offset, ++prev_offset) { + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* Get pseudo-random value */ + if (data_independent) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + s_next_addresses(&address_block, &input_block, &zero_block); + } + pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + else { + pseudo_rand = instance->memory[prev_offset].v[0]; + } + + ref_lane = (pseudo_rand >> 32) % instance->lanes; + if (position.pass == 0 && position.slice == 0) { + ref_lane = position.lane; + } + + position.index = i; + ref_index = s_index_alpha(instance, &position, (ulong32)(pseudo_rand & CONST64(0xFFFFFFFF)), ref_lane == position.lane); + ref_block = instance->memory + instance->lane_length * (ulong32)ref_lane + ref_index; + curr_block = instance->memory + curr_offset; + + if (position.pass == 0) { + s_fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); + } + else { + s_fill_block(instance->memory + prev_offset, ref_block, curr_block, 1); + } + } +} + +/* Initial hash H_0 (RFC 9106 Section 3.1 step 1) */ +static int s_initial_hash(unsigned char *blockhash, + const unsigned char *pwd, unsigned long pwdlen, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *secret, unsigned long secretlen, + const unsigned char *ad, unsigned long adlen, + ulong32 t_cost, ulong32 m_cost, ulong32 parallelism, + ulong32 outlen, int type) +{ + hash_state md; + unsigned char value[4]; + int err; + + if ((err = blake2b_init(&md, ARGON2_PREHASH_DIGEST_LEN, NULL, 0)) != CRYPT_OK) return err; + + STORE32L(parallelism, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L(outlen, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L(m_cost, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L(t_cost, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L((ulong32)ARGON2_VERSION, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L((ulong32)type, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + + STORE32L((ulong32)pwdlen, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + if (pwdlen > 0) { + if ((err = blake2b_process(&md, pwd, pwdlen)) != CRYPT_OK) return err; + } + + STORE32L((ulong32)saltlen, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + if (saltlen > 0) { + if ((err = blake2b_process(&md, salt, saltlen)) != CRYPT_OK) return err; + } + + STORE32L((ulong32)secretlen, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + if (secretlen > 0 && secret != NULL) { + if ((err = blake2b_process(&md, secret, secretlen)) != CRYPT_OK) return err; + } + + STORE32L((ulong32)adlen, value); + if ((err = blake2b_process(&md, value, 4)) != CRYPT_OK) return err; + if (adlen > 0 && ad != NULL) { + if ((err = blake2b_process(&md, ad, adlen)) != CRYPT_OK) return err; + } + + if ((err = blake2b_done(&md, blockhash)) != CRYPT_OK) return err; + return CRYPT_OK; +} + +/* Generate first two blocks in each lane */ + +static int s_fill_first_blocks(unsigned char *blockhash, const argon2_instance *instance) +{ + ulong32 l; + unsigned char blockhash_bytes[ARGON2_BLOCK_SIZE]; + int err; + + for (l = 0; l < instance->lanes; ++l) { + /* B[i][0] = H'(H_0 || LE32(0) || LE32(i)) */ + STORE32L(0, blockhash + ARGON2_PREHASH_DIGEST_LEN); + STORE32L(l, blockhash + ARGON2_PREHASH_DIGEST_LEN + 4); + if ((err = s_blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, ARGON2_PREHASH_SEED_LEN)) != CRYPT_OK) return err; + s_block_load(&instance->memory[l * instance->lane_length + 0], blockhash_bytes); + + /* B[i][1] = H'(H_0 || LE32(1) || LE32(i)) */ + STORE32L(1, blockhash + ARGON2_PREHASH_DIGEST_LEN); + if ((err = s_blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, ARGON2_PREHASH_SEED_LEN)) != CRYPT_OK) return err; + s_block_load(&instance->memory[l * instance->lane_length + 1], blockhash_bytes); + } + + zeromem(blockhash_bytes, ARGON2_BLOCK_SIZE); + return CRYPT_OK; +} + +/* Finalize: XOR last blocks, produce tag */ +static int s_finalize(unsigned char *out, unsigned long outlen, + const argon2_instance *instance) +{ + argon2_block blockhash; + unsigned char blockhash_bytes[ARGON2_BLOCK_SIZE]; + ulong32 l; + int err; + + s_block_copy(&blockhash, instance->memory + instance->lane_length - 1); + + for (l = 1; l < instance->lanes; ++l) { + ulong32 last = l * instance->lane_length + (instance->lane_length - 1); + s_block_xor(&blockhash, instance->memory + last); + } + + s_block_store(blockhash_bytes, &blockhash); + err = s_blake2b_long(out, outlen, blockhash_bytes, ARGON2_BLOCK_SIZE); + + zeromem(blockhash.v, ARGON2_BLOCK_SIZE); + zeromem(blockhash_bytes, ARGON2_BLOCK_SIZE); + return err; +} + +/* Fill the entire memory */ +static void s_fill_memory(argon2_instance *instance) +{ + ulong32 r, s, l; + + for (r = 0; r < instance->passes; ++r) { + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + for (l = 0; l < instance->lanes; ++l) { + argon2_position position; + position.pass = r; + position.lane = l; + position.slice = (unsigned char)s; + position.index = 0; + s_fill_segment(instance, position); + } + } + } +} + +/** + Hash a password with Argon2 (RFC 9106) + + @param pwd Password (or message) + @param pwdlen Length of password + @param salt Salt + @param saltlen Length of salt + @param secret Optional secret value (may be NULL) + @param secretlen Length of secret + @param ad Optional associated data (may be NULL) + @param adlen Length of associated data + @param t_cost Number of passes (iterations), minimum 1 + @param m_cost Memory size in KiB, minimum 8*parallelism + @param parallelism Degree of parallelism (number of lanes), minimum 1 + @param type ARGON2_D, ARGON2_I, or ARGON2_ID + @param out [out] Output tag + @param outlen Desired output length (4..2^32-1) + @return CRYPT_OK on success +*/ +int argon2_hash(const unsigned char *pwd, unsigned long pwdlen, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *secret, unsigned long secretlen, + const unsigned char *ad, unsigned long adlen, + unsigned int t_cost, unsigned int m_cost, + unsigned int parallelism, + argon2_type type, + unsigned char *out, unsigned long outlen) +{ + argon2_instance instance; + unsigned char blockhash[ARGON2_PREHASH_SEED_LEN]; + ulong32 memory_blocks, segment_length; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen >= ARGON2_MIN_OUTLEN); + LTC_ARGCHK(pwd != NULL || pwdlen == 0); + LTC_ARGCHK(salt != NULL || saltlen == 0); + LTC_ARGCHK(secret != NULL || secretlen == 0); + LTC_ARGCHK(ad != NULL || adlen == 0); + LTC_ARGCHK(t_cost >= 1); + LTC_ARGCHK(parallelism >= 1); + LTC_ARGCHK(m_cost >= 8 * parallelism); + LTC_ARGCHK(type == ARGON2_D || type == ARGON2_I || type == ARGON2_ID); + + /* Align memory: ensure memory_blocks is a multiple of 4*parallelism */ + memory_blocks = (ulong32)m_cost; + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * (ulong32)parallelism) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * (ulong32)parallelism; + } + segment_length = memory_blocks / ((ulong32)parallelism * ARGON2_SYNC_POINTS); + memory_blocks = segment_length * ((ulong32)parallelism * ARGON2_SYNC_POINTS); + + /* Set up instance */ + instance.passes = (ulong32)t_cost; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = (ulong32)parallelism; + instance.type = (int)type; + instance.memory = NULL; + + /* Allocate memory */ + { + unsigned long alloc_size = (unsigned long)memory_blocks * sizeof(argon2_block); + /* overflow check */ + if (alloc_size / sizeof(argon2_block) != memory_blocks) { + return CRYPT_OVERFLOW; + } + instance.memory = XMALLOC(alloc_size); + if (instance.memory == NULL) { + return CRYPT_MEM; + } + } + + /* Initial hash H_0 */ + err = s_initial_hash(blockhash, pwd, pwdlen, salt, saltlen, + secret, secretlen, ad, adlen, + (ulong32)t_cost, (ulong32)m_cost, + (ulong32)parallelism, (ulong32)outlen, + (int)type); + if (err != CRYPT_OK) goto cleanup; + + /* Zero the extra 8 bytes after digest */ + XMEMSET(blockhash + ARGON2_PREHASH_DIGEST_LEN, 0, ARGON2_PREHASH_SEED_LEN - ARGON2_PREHASH_DIGEST_LEN); + + /* Generate first blocks */ + err = s_fill_first_blocks(blockhash, &instance); + if (err != CRYPT_OK) goto cleanup; + + /* Fill memory */ + s_fill_memory(&instance); + + /* Finalize */ + err = s_finalize(out, outlen, &instance); + +cleanup: + if (instance.memory != NULL) { + zeromem(instance.memory, (unsigned long)memory_blocks * sizeof(argon2_block)); + XFREE(instance.memory); + } + zeromem(blockhash, ARGON2_PREHASH_SEED_LEN); + return err; +} + +#endif /* LTC_ARGON2 */ diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 90120bff3..ca27e75f3 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -13,9 +13,12 @@ const char *crypt_build_settings = "LibTomCrypt " SCRYPT " (www.libtom.net)\n" "LibTomCrypt is public domain software.\n" #if defined(INCLUDE_BUILD_DATE) - "Built on " __DATE__ " at " __TIME__ "\n" + "Built on " __DATE__ " at " __TIME__ "\n\n" #endif - "\n\nEndianness: " +#if defined(LTC_ARCH_X86) + "LTC_ARCH_X86\n" +#endif + "\nEndianness: " #if defined(ENDIAN_NEUTRAL) "neutral/" #endif @@ -134,6 +137,9 @@ const char *crypt_build_settings = #if defined(LTC_CHACHA) " ChaCha\n" #endif +#if defined(LTC_XCHACHA20) + " XChaCha20\n" +#endif #if defined(LTC_SALSA20) " Salsa20\n" #endif @@ -378,6 +384,10 @@ const char *crypt_build_settings = " X25519\n" #endif #endif +#if defined(LTC_CURVE448) + " Ed448\n" + " X448\n" +#endif #if defined(LTC_PK_MAX_RETRIES) " "NAME_VALUE(LTC_PK_MAX_RETRIES)"\n" #endif @@ -451,16 +461,23 @@ const char *crypt_build_settings = #if defined(LTC_BASE16) " BASE16 " #endif +#if defined(LTC_ARGON2) + " ARGON2 " +#endif #if defined(LTC_BCRYPT) " BCRYPT " " " NAME_VALUE(LTC_BCRYPT_DEFAULT_ROUNDS) " " #endif +#if defined(LTC_SCRYPT) + " SCRYPT " +#endif #if defined(LTC_CRC32) " CRC32 " #endif #if defined(LTC_DER) " DER " " " NAME_VALUE(LTC_DER_MAX_RECURSION) " " + " " NAME_VALUE(LTC_DER_OID_DEFAULT_NODES) " " #endif #if defined(LTC_PKCS_1) " PKCS#1 " @@ -495,6 +512,15 @@ const char *crypt_build_settings = #if defined(LTC_PEM_SSH) " OpenSSH-PEM " #endif +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) + " SHA1-NI " +#endif +#if defined(LTC_SHA224) && defined(LTC_SHA224_X86) + " SHA224-NI " +#endif +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) + " SHA256-NI " +#endif #if defined(LTC_DEVRANDOM) " LTC_DEVRANDOM " #endif @@ -528,6 +554,9 @@ const char *crypt_build_settings = #if defined(LTC_SMALL_CODE) " LTC_SMALL_CODE " #endif +#if defined(LTC_SMALL_STACK) + " LTC_SMALL_STACK " +#endif #if defined(LTC_NO_FILE) " LTC_NO_FILE " #endif diff --git a/src/misc/crypt/crypt_register_all_hashes.c b/src/misc/crypt/crypt_register_all_hashes.c index 93d32fc34..91f1cadb1 100644 --- a/src/misc/crypt/crypt_register_all_hashes.c +++ b/src/misc/crypt/crypt_register_all_hashes.c @@ -19,6 +19,9 @@ int register_all_hashes(void) REGISTER_HASH(&sha512_desc); #endif #ifdef LTC_SHA256 + /* `sha256_desc` does the multiplexing into `sha256_x86_desc` resp. `sha256_portable_desc` + * depending on the capabilities of the CPU. + */ REGISTER_HASH(&sha256_desc); #endif #ifdef LTC_SHA3 @@ -34,12 +37,18 @@ int register_all_hashes(void) REGISTER_HASH(&sha512_224_desc); #endif #ifdef LTC_SHA224 + /* `sha224_desc` does the multiplexing into `sha224_x86_desc` resp. `sha224_portable_desc` + * depending on the capabilities of the CPU. + */ REGISTER_HASH(&sha224_desc); #endif #ifdef LTC_SHA384 REGISTER_HASH(&sha384_desc); #endif #ifdef LTC_SHA1 + /* `sha1_desc` does the multiplexing into `sha1_x86_desc` resp. `sha1_portable_desc` + * depending on the capabilities of the CPU. + */ REGISTER_HASH(&sha1_desc); #endif #ifdef LTC_MD5 diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c index 26f2d13fc..47830aed1 100644 --- a/src/misc/crypt/crypt_sizes.c +++ b/src/misc/crypt/crypt_sizes.c @@ -206,9 +206,6 @@ static const crypt_size s_crypt_sizes[] = { #ifdef LTC_EAX_MODE SZ_STRINGIFY_T(eax_state), #endif -#ifdef LTC_OCB_MODE - SZ_STRINGIFY_T(ocb_state), -#endif #ifdef LTC_OCB3_MODE SZ_STRINGIFY_T(ocb3_state), #endif diff --git a/src/misc/deprecated.c b/src/misc/deprecated.c index ae434eb25..6043007a4 100644 --- a/src/misc/deprecated.c +++ b/src/misc/deprecated.c @@ -79,10 +79,366 @@ int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, } #endif /* LTC_MECC */ +#ifdef LTC_MRSA +/** + (PKCS #1 v2.0) OAEP pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param lparam The system "lparam" for the encryption + @param lparamlen The length of lparam (octets) + @param prng An active PRNG + @param prng_idx The index of the desired prng + @param hash_idx The index of the desired hash + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param key The RSA key to encrypt to + @return CRYPT_OK if successful +*/ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, + int hash_idx, int padding, + const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + prng, prng_idx, + hash_idx, + padding, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_encrypt_key_v2(in, inlen, out, outlen, ¶ms, key); +} + +/** + PKCS #1 decrypt then v1.5 or OAEP depad + @param in The ciphertext + @param inlen The length of the ciphertext (octets) + @param out [out] The plaintext + @param outlen [in/out] The max size and resulting size of the plaintext (octets) + @param lparam The system "lparam" value + @param lparamlen The length of the lparam value (octets) + @param hash_idx The hash algorithm used + @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param stat [out] Result of the decryption, 1==valid, 0==invalid + @param key The corresponding private RSA key + @return CRYPT_OK if succcessul (even if invalid) +*/ +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + NULL, -1, + hash_idx, + padding, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_decrypt_key_v2(in, inlen, out, outlen, ¶ms, stat, key); +} + +/** + PKCS #1 pad then sign + @param in The hash to sign + @param inlen The length of the hash to sign (octets) + @param out [out] The signature + @param outlen [in/out] The max size and resulting size of the signature + @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param saltlen The length of the salt desired (octets) + @param key The private RSA key to use + @return CRYPT_OK if successful +*/ +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + prng, prng_idx, + hash_idx, + padding, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_sign_hash_v2(in, inlen, out, outlen, ¶ms, key); +} + +/** + PKCS #1 de-sign then v1.5 or PSS depad + @param sig The signature data + @param siglen The length of the signature data (octets) + @param hash The hash of the message that was signed + @param hashlen The length of the hash of the message that was signed (octets) + @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) + @param hash_idx The index of the desired hash + @param saltlen The length of the salt used during signature + @param stat [out] The result of the signature comparison, 1==valid, 0==invalid + @param key The public RSA key corresponding to the key that performed the signature + @return CRYPT_OK on success (even if the signature is invalid) +*/ +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, const rsa_key *key) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + NULL, -1, + hash_idx, + padding, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return rsa_verify_hash_v2(sig, siglen, hash, hashlen, ¶ms, stat, key); +} + +int rsa_args_to_op_params(const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, + int padding, unsigned long saltlen, + ltc_rsa_op_parameters *params) +{ + int err; + ltc_rsa_op_parameters p = { + .u.crypt.lparam = lparam, + .u.crypt.lparamlen = lparamlen, + .prng = prng, + .wprng = prng_idx, + .padding = padding, + .params.saltlen = saltlen, + .params.hash_idx = -1, + .params.mgf1_hash_idx = -1, + }; + if ((err = hash_is_valid(hash_idx)) == CRYPT_OK) { + p.params.hash_idx = hash_idx; + p.params.mgf1_hash_idx = hash_idx; + *params = p; + } else if (padding == LTC_PKCS_1_V1_5 || padding == LTC_PKCS_1_V1_5_NA1) { + /* PKCS#1 1.5 does not necessarily require a hash */ + err = CRYPT_OK; + *params = p; + } + return err; +} +#endif /* LTC_MRSA */ + + +#ifdef LTC_PKCS_1 +/** + Perform PKCS #1 MGF1 (internal) + @param hash_idx The index of the hash desired + @param seed The seed for MGF1 + @param seedlen The length of the seed + @param mask [out] The destination + @param masklen The length of the mask desired + @return CRYPT_OK if successful +*/ +int pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen) +{ + return ltc_pkcs_1_mgf1(hash_idx, seed, seedlen, mask, masklen); +} +/** + PKCS #1 v2.00 OAEP encode + @param msg The data to encode + @param msglen The length of the data to encode (octets) + @param lparam A session or system parameter (can be NULL) + @param lparamlen The length of the lparam data + @param modulus_bitlen The bit length of the RSA modulus + @param prng An active PRNG state + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param out [out] The destination for the encoded data + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + prng, prng_idx, + hash_idx, + LTC_PKCS_1_OAEP, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_oaep_encode(msg, msglen, ¶ms, modulus_bitlen, out, outlen); +} + +/** + PKCS #1 v2.00 OAEP decode + @param msg The encoded data to decode + @param msglen The length of the encoded data (octets) + @param lparam The session or system data (can be NULL) + @param lparamlen The length of the lparam + @param modulus_bitlen The bit length of the RSA modulus + @param mgf_hash The hash algorithm used for the MGF + @param lparam_hash The hash algorithm used when hashing the lparam (can be -1) + @param out [out] Destination of decoding + @param outlen [in/out] The max size and resulting size of the decoding + @param res [out] Result of decoding, 1==valid, 0==invalid + @return CRYPT_OK if successful +*/ +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(lparam, lparamlen, + NULL, -1, + hash_idx, + LTC_PKCS_1_OAEP, 0, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_oaep_decode(msg, msglen, ¶ms, modulus_bitlen, out, outlen, res); +} + +/** + PKCS #1 v2.00 Signature Encoding using MGF1 and both hashes are the same + @param msghash The hash to encode + @param msghashlen The length of the hash (octets) + @param saltlen The length of the salt desired (octets) + @param prng An active PRNG context + @param prng_idx The index of the PRNG desired + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param out [out] The destination of the encoding + @param outlen [in/out] The max size and resulting size of the encoded data + @return CRYPT_OK if successful +*/ +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + prng, prng_idx, + hash_idx, + LTC_PKCS_1_PSS, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_pss_encode_mgf1(msghash, msghashlen, ¶ms, modulus_bitlen, out, outlen); +} + +/** + PKCS #1 v2.00 PSS decode + @param msghash The hash to verify + @param msghashlen The length of the hash (octets) + @param sig The signature data (encoded data) + @param siglen The length of the signature data (octets) + @param saltlen The length of the salt used (octets) + @param hash_idx The index of the hash desired + @param modulus_bitlen The bit length of the RSA modulus + @param res [out] The result of the comparison, 1==valid, 0==invalid + @return CRYPT_OK if successful (even if the comparison failed) +*/ +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res) +{ + int err; + ltc_rsa_op_parameters params; + if ((err = rsa_args_to_op_params(NULL, 0, + NULL, -1, + hash_idx, + LTC_PKCS_1_PSS, saltlen, + ¶ms)) != CRYPT_OK) { + return err; + } + return ltc_pkcs_1_pss_decode_mgf1(msghash, msghashlen, sig, siglen, ¶ms, modulus_bitlen, res); +} + + +/*! \brief PKCS #1 v1.5 encode. + * + * \param msg The data to encode + * \param msglen The length of the data to encode (octets) + * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * \param modulus_bitlen The bit length of the RSA modulus + * \param prng An active PRNG state (only for LTC_PKCS_1_EME) + * \param prng_idx The index of the PRNG desired (only for LTC_PKCS_1_EME) + * \param out [out] The destination for the encoded data + * \param outlen [in/out] The max size and resulting size of the encoded data + * + * \return CRYPT_OK if successful + */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen) +{ + return ltc_pkcs_1_v1_5_encode(msg, msglen, + block_type, modulus_bitlen, + prng, prng_idx, + out, outlen); +} + +/** @brief PKCS #1 v1.5 decode. + * + * @param msg The encoded data to decode + * @param msglen The length of the encoded data (octets) + * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) + * @param modulus_bitlen The bit length of the RSA modulus + * @param out [out] Destination of decoding + * @param outlen [in/out] The max size and resulting size of the decoding + * @param is_valid [out] Boolean whether the padding was valid + * + * @return CRYPT_OK if successful + */ +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid) +{ + return ltc_pkcs_1_v1_5_decode(msg, msglen, + block_type, modulus_bitlen, + out, outlen, + is_valid); +} +#endif /* LTC_PKCS_1 */ + int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which) { return ltc_compare_testvector(is, is_len, should, should_len, what, which); } - #endif /* LTC_NO_DEPRECATED_APIS */ diff --git a/src/misc/padding/padding_depad.c b/src/misc/padding/padding_depad.c index e3f715112..a784f1af7 100644 --- a/src/misc/padding/padding_depad.c +++ b/src/misc/padding/padding_depad.c @@ -17,7 +17,7 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned long mode) { unsigned long padded_length, unpadded_length, n; - unsigned char pad; + unsigned char pad, data_xor_pad = 0; enum padding_type type; LTC_ARGCHK(data != NULL); @@ -30,9 +30,12 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon if (type < LTC_PAD_ONE_AND_ZERO) { pad = data[padded_length - 1]; - if (pad > padded_length || pad == 0) return CRYPT_INVALID_ARG; - - unpadded_length = padded_length - pad; + if (pad > padded_length || pad == 0) { + unpadded_length = padded_length - (padded_length > 16 ? padded_length - 16 : padded_length); + data_xor_pad = 1; + } else { + unpadded_length = padded_length - pad; + } } else { /* init pad to calm old compilers */ pad = 0x0; @@ -45,7 +48,7 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon /* FALLTHROUGH */ case LTC_PAD_PKCS7: for (n = unpadded_length; n < padded_length - 1; ++n) { - if (data[n] != pad) return CRYPT_INVALID_PACKET; + data_xor_pad |= data[n] ^ pad; } break; #ifdef LTC_RNG_GET_BYTES @@ -56,17 +59,17 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon case LTC_PAD_SSH: pad = 0x1; for (n = unpadded_length; n < padded_length; ++n) { - if (data[n] != pad++) return CRYPT_INVALID_PACKET; + data_xor_pad |= data[n] ^ pad++; } break; case LTC_PAD_ONE_AND_ZERO: while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) { - if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET; + data_xor_pad |= data[unpadded_length - 1]; unpadded_length--; } - if (unpadded_length == 0) return CRYPT_INVALID_PACKET; - unpadded_length--; - if (data[unpadded_length] != 0x80) return CRYPT_INVALID_PACKET; + if (unpadded_length == 0) data_xor_pad |= 1; + else unpadded_length--; + if (data[unpadded_length] != 0x80) data_xor_pad |= 1; break; case LTC_PAD_ZERO: case LTC_PAD_ZERO_ALWAYS: @@ -82,6 +85,9 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon return CRYPT_INVALID_ARG; } + if (data_xor_pad != 0) + return CRYPT_INVALID_PACKET; + *length = unpadded_length; return CRYPT_OK; diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index 17aa47705..6a6d4e457 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -63,6 +63,10 @@ static const struct { [LTC_OID_X25519] = { LTC_PKA_X25519, (pkcs8_import_fn)x25519_import_pkcs8_asn1 }, [LTC_OID_ED25519] = { LTC_PKA_ED25519, (pkcs8_import_fn)ed25519_import_pkcs8_asn1 }, #endif +#ifdef LTC_CURVE448 + [LTC_OID_X448] = { LTC_PKA_X448, (pkcs8_import_fn)x448_import_pkcs8_asn1 }, + [LTC_OID_ED448] = { LTC_PKA_ED448, (pkcs8_import_fn)ed448_import_pkcs8_asn1 }, +#endif }; static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx) @@ -111,6 +115,7 @@ typedef int (*import_fn)(const unsigned char *, unsigned long, void*); static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA [LTC_PKA_RSA] = (import_fn)rsa_import, + [LTC_PKA_RSA_PSS] = (import_fn)rsa_import, #endif #ifdef LTC_MDSA [LTC_PKA_DSA] = (import_fn)dsa_import, @@ -122,6 +127,10 @@ static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = { [LTC_PKA_X25519] = (import_fn)x25519_import, [LTC_PKA_ED25519] = (import_fn)ed25519_import, #endif +#ifdef LTC_CURVE448 + [LTC_PKA_X448] = (import_fn)x448_import, + [LTC_PKA_ED448] = (import_fn)ed448_import, +#endif }; static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx) diff --git a/src/misc/scrypt/scrypt.c b/src/misc/scrypt/scrypt.c new file mode 100644 index 000000000..44ecde29d --- /dev/null +++ b/src/misc/scrypt/scrypt.c @@ -0,0 +1,179 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file scrypt.c + scrypt password-based key derivation function (RFC 7914) +*/ +#ifdef LTC_SCRYPT + +/* Salsa20/8 Core (RFC 7914 Section 3) */ +#define SCRYPT_QR(a,b,c,d) \ + x[b] ^= ROL(x[a] + x[d], 7); \ + x[c] ^= ROL(x[b] + x[a], 9); \ + x[d] ^= ROL(x[c] + x[b], 13); \ + x[a] ^= ROL(x[d] + x[c], 18); + +static void s_salsa20_8(unsigned char B[64]) +{ + ulong32 x[16], b32[16]; + int i; + + for (i = 0; i < 16; ++i) { + LOAD32L(b32[i], B + i * 4); + } + XMEMCPY(x, b32, sizeof(x)); + for (i = 8; i > 0; i -= 2) { + SCRYPT_QR( 0, 4, 8,12) + SCRYPT_QR( 5, 9,13, 1) + SCRYPT_QR(10,14, 2, 6) + SCRYPT_QR(15, 3, 7,11) + SCRYPT_QR( 0, 1, 2, 3) + SCRYPT_QR( 5, 6, 7, 4) + SCRYPT_QR(10,11, 8, 9) + SCRYPT_QR(15,12,13,14) + } + for (i = 0; i < 16; ++i) { + STORE32L(x[i] + b32[i], B + i * 4); + } +} + +/* scryptBlockMix (RFC 7914 Section 4) */ +static void s_blockmix(unsigned char *B, unsigned char *Y, unsigned long r) +{ + unsigned char X[64]; + unsigned long i; + unsigned long blen = 128 * r; + + /* 1: X = B[2r - 1] */ + XMEMCPY(X, B + blen - 64, 64); + /* 2: for i = 0 to 2r-1 */ + for (i = 0; i < 2 * r; ++i) { + unsigned long j; + for (j = 0; j < 64; ++j) X[j] ^= B[i * 64 + j]; + s_salsa20_8(X); + XMEMCPY(Y + i * 64, X, 64); + } + /* 3: B' = (Y[0], Y[2], ..., Y[2r-2], Y[1], Y[3], ..., Y[2r-1]) */ + for (i = 0; i < r; ++i) { + XMEMCPY(B + i * 64, Y + (2 * i) * 64, 64); + } + for (i = 0; i < r; ++i) { + XMEMCPY(B + (i + r) * 64, Y + (2 * i + 1) * 64, 64); + } +} + +/* Integerify: interpret last 64-byte block as little-endian and return low 64 bits */ +static LTC_INLINE ulong64 s_integerify(const unsigned char *B, unsigned long r) +{ + const unsigned char *X = B + (2 * r - 1) * 64; + ulong64 v; + + LOAD64L(v, X); + return v; +} + +/* scryptROMix (RFC 7914 Section 5) */ +static void s_romix(unsigned char *B, unsigned long r, ulong64 N, unsigned char *V, unsigned char *XY) +{ + unsigned char *X = XY; + unsigned char *Y = XY + 128 * r; + unsigned long blen = 128 * r; + ulong64 i, j; + + /* 1: X = B */ + XMEMCPY(X, B, blen); + /* 2: for i = 0 to N-1: V[i] = X; X = BlockMix(X) */ + for (i = 0; i < N; ++i) { + XMEMCPY(V + i * blen, X, blen); + s_blockmix(X, Y, r); + } + /* 3: for i = 0 to N-1 */ + for (i = 0; i < N; ++i) { + j = s_integerify(X, r) & (N - 1); + { + unsigned long k; + unsigned char *Vj = V + j * blen; + for (k = 0; k < blen; ++k) X[k] ^= Vj[k]; + } + s_blockmix(X, Y, r); + } + /* 4: B' = X */ + XMEMCPY(B, X, blen); +} + +/** + Derive a key using scrypt (RFC 7914) + + @param password Password + @param password_len Length of password + @param salt Salt + @param salt_len Length of salt + @param N CPU/memory cost parameter (must be > 1 and a power of 2) + @param r Block size parameter (minimum 1) + @param p Parallelisation parameter (minimum 1) + @param out [out] Derived key + @param outlen Desired output length + @return CRYPT_OK on success +*/ +int scrypt_pbkdf(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + unsigned long N, unsigned long r, unsigned long p, + unsigned char *out, unsigned long outlen) +{ + unsigned char *B = NULL, *V = NULL, *XY = NULL; + unsigned long Blen, Vlen, XYlen, i; + int err, hash_idx; + + LTC_ARGCHK(out != NULL); + + LTC_ARGCHK(password != NULL || password_len == 0); + LTC_ARGCHK(salt != NULL || salt_len == 0); + LTC_ARGCHK(N >= 2 && (N & (N - 1)) == 0); /* must be > 1 and power of 2 */ + LTC_ARGCHK(r >= 1); + LTC_ARGCHK(p >= 1); + LTC_ARGCHK(outlen >= 1); + LTC_ARGCHK(r <= ULONG_MAX / 128 / p); + LTC_ARGCHK(r <= ULONG_MAX / 256); + LTC_ARGCHK(N <= ULONG_MAX / 128 / r); + + hash_idx = find_hash("sha256"); + if (hash_idx == -1) return CRYPT_INVALID_HASH; + + Blen = 128 * r * p; + Vlen = 128 * r * N; + XYlen = 256 * r; + + B = (unsigned char *)XMALLOC(Blen); + V = (unsigned char *)XMALLOC(Vlen); + XY = (unsigned char *)XMALLOC(XYlen); + if (B == NULL || V == NULL || XY == NULL) { + err = CRYPT_MEM; + goto cleanup; + } + + /* 1: B = PBKDF2-HMAC-SHA256(password, salt, 1, p * 128 * r) */ + { + unsigned long blen_out = Blen; + err = pkcs_5_alg2(password, password_len, salt, salt_len, 1, hash_idx, B, &blen_out); + if (err != CRYPT_OK) goto cleanup; + } + /* 2: for i = 0 to p-1: B[i] = ROMix(r, B[i], N) */ + for (i = 0; i < p; ++i) { + s_romix(B + i * 128 * r, r, (ulong64)N, V, XY); + } + /* 3: DK = PBKDF2-HMAC-SHA256(password, B, 1, dkLen) */ + { + unsigned long outlen_out = outlen; + err = pkcs_5_alg2(password, password_len, B, Blen, 1, hash_idx, out, &outlen_out); + } + +cleanup: + if (XY != NULL) { zeromem(XY, XYlen); XFREE(XY); } + if (V != NULL) { zeromem(V, Vlen); XFREE(V); } + if (B != NULL) { zeromem(B, Blen); XFREE(B); } + return err; +} + +#endif /* LTC_SCRYPT */ diff --git a/src/modes/ctr/ctr_decrypt.c b/src/modes/ctr/ctr_decrypt.c index a55a08fc2..ac421fa28 100644 --- a/src/modes/ctr/ctr_decrypt.c +++ b/src/modes/ctr/ctr_decrypt.c @@ -20,7 +20,7 @@ int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) { LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(ct != NULL || len == 0); LTC_ARGCHK(ctr != NULL); return ctr_encrypt(ct, pt, len, ctr); diff --git a/src/modes/ctr/ctr_encrypt.c b/src/modes/ctr/ctr_encrypt.c index 2859574bc..043b5ae48 100644 --- a/src/modes/ctr/ctr_encrypt.c +++ b/src/modes/ctr/ctr_encrypt.c @@ -81,7 +81,7 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s { int err, fr; - LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(pt != NULL || len == 0); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctr != NULL); diff --git a/src/pk/asn1/der/general/der_encode_asn1_length.c b/src/pk/asn1/der/general/der_encode_asn1_length.c index 7892eea24..e5bf77d62 100644 --- a/src/pk/asn1/der/general/der_encode_asn1_length.c +++ b/src/pk/asn1/der/general/der_encode_asn1_length.c @@ -29,7 +29,7 @@ int der_encode_asn1_length(unsigned long len, unsigned char *out, unsigned long x >>= 8; } if (y == 0) { - return CRYPT_PK_ASN1_ERROR; + y = 1; /* len == 0 is valid: short form, single byte 0x00 */ } if (out == NULL) { diff --git a/src/pk/asn1/oid/pk_get.c b/src/pk/asn1/oid/pk_get.c index 1fd5872e2..11f58283f 100644 --- a/src/pk/asn1/oid/pk_get.c +++ b/src/pk/asn1/oid/pk_get.c @@ -7,18 +7,24 @@ typedef struct { enum ltc_oid_id id; enum ltc_pka_id pka; - const char* oid; + const char *hash; + const char *oid; } oid_table_entry; static const oid_table_entry pka_oids[] = { - { LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL }, - { LTC_OID_RSA, LTC_PKA_RSA, "1.2.840.113549.1.1.1" }, - { LTC_OID_DSA, LTC_PKA_DSA, "1.2.840.10040.4.1" }, - { LTC_OID_EC, LTC_PKA_EC, "1.2.840.10045.2.1" }, - { LTC_OID_EC_PRIMEF, LTC_PKA_EC, "1.2.840.10045.1.1" }, - { LTC_OID_X25519, LTC_PKA_X25519, "1.3.101.110" }, - { LTC_OID_ED25519, LTC_PKA_ED25519, "1.3.101.112" }, - { LTC_OID_DH, LTC_PKA_DH, "1.2.840.113549.1.3.1" }, + { LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL, NULL }, + { LTC_OID_RSA, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.1" }, + { LTC_OID_DSA, LTC_PKA_DSA, NULL, "1.2.840.10040.4.1" }, + { LTC_OID_EC, LTC_PKA_EC, NULL, "1.2.840.10045.2.1" }, + { LTC_OID_EC_PRIMEF, LTC_PKA_EC, NULL, "1.2.840.10045.1.1" }, + { LTC_OID_X25519, LTC_PKA_X25519, NULL, "1.3.101.110" }, + { LTC_OID_ED25519, LTC_PKA_ED25519, NULL, "1.3.101.112" }, + { LTC_OID_X448, LTC_PKA_X448, NULL, "1.3.101.111" }, + { LTC_OID_ED448, LTC_PKA_ED448, NULL, "1.3.101.113" }, + { LTC_OID_DH, LTC_PKA_DH, NULL, "1.2.840.113549.1.3.1" }, + { LTC_OID_RSA_OAEP, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.7" }, + { LTC_OID_RSA_MGF1, LTC_PKA_RSA, NULL, "1.2.840.113549.1.1.8" }, + { LTC_OID_RSA_PSS, LTC_PKA_RSA_PSS, NULL, "1.2.840.113549.1.1.10" }, }; static LTC_INLINE const oid_table_entry* s_get_entry(enum ltc_oid_id id) @@ -43,21 +49,35 @@ int pk_get_oid(enum ltc_oid_id id, const char **st) return CRYPT_INVALID_ARG; } -/* - Returns the PKA ID requested. - @return CRYPT_OK if valid -*/ -int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka) +static LTC_INLINE int s_get_values(enum ltc_oid_id id, enum ltc_pka_id *pka, const char **hash) { const oid_table_entry* e = s_get_entry(id); LTC_ARGCHK(pka != NULL); if (e != NULL) { *pka = e->pka; + if (hash) { + *hash = e->hash; + } else if (e->hash) { + /* If we don't want the hash result, but the entry has a hash, we're most likely + * confused and we prefer to stop processing then, instead of continuing with a + * maybe wrong assumption. + */ + return CRYPT_INVALID_ARG; + } return CRYPT_OK; } return CRYPT_INVALID_ARG; } +/* + Returns the PKA ID requested. + @return CRYPT_OK if valid +*/ +int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka) +{ + return s_get_values(id, pka, NULL); +} + /* Returns the OID ID requested. @return CRYPT_OK if valid diff --git a/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c b/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c index 45a1c6f60..b96db4438 100644 --- a/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c +++ b/src/pk/asn1/x509/x509_decode_public_key_from_certificate.c @@ -10,7 +10,7 @@ #ifdef LTC_DER /** - Try to decode the public key from a X.509 certificate + Process the public key from the SubjectPublicKeyInfo of a X.509 certificate @param in The input buffer @param inlen The length of the input buffer @param algorithm One out of the enum #public_key_algorithms @@ -19,53 +19,82 @@ @param parameters_len [in/out] The number of parameters to include @param callback The callback @param ctx The context passed to the callback - @return CRYPT_OK on success, - CRYPT_NOP if no SubjectPublicKeyInfo was found, - another error if decoding or memory allocation failed + @return CRYPT_OK on success */ -int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, - enum ltc_oid_id algorithm, ltc_asn1_type param_type, - ltc_asn1_list* parameters, unsigned long *parameters_len, - public_key_decode_cb callback, void *ctx) +int x509_process_public_key_from_spki(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key) { int err; unsigned char *tmpbuf = NULL; unsigned long tmpbuf_len; - ltc_asn1_list *decoded_list = NULL, *spki; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != 0); - LTC_ARGCHK(callback != NULL); - - if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { - return err; - } + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(callback != NULL); if (algorithm == LTC_OID_EC) { - err = callback(spki->data, spki->size, ctx); + err = callback(in, inlen, key); } else { tmpbuf_len = inlen; tmpbuf = XCALLOC(1, tmpbuf_len); if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_OUT; + return CRYPT_MEM; } - err = x509_decode_subject_public_key_info(spki->data, spki->size, + err = x509_decode_subject_public_key_info(in, inlen, algorithm, tmpbuf, &tmpbuf_len, param_type, parameters, parameters_len); if (err == CRYPT_OK) { - err = callback(tmpbuf, tmpbuf_len, ctx); - goto LBL_OUT; + err = callback(tmpbuf, tmpbuf_len, key); } } -LBL_OUT: - if (decoded_list) der_free_sequence_flexi(decoded_list); if (tmpbuf != NULL) XFREE(tmpbuf); return err; } +/** + Try to decode the public key from a X.509 certificate + @param in The input buffer + @param inlen The length of the input buffer + @param algorithm One out of the enum #public_key_algorithms + @param param_type The parameters' type out of the enum ltc_asn1_type + @param parameters The parameters to include + @param parameters_len [in/out] The number of parameters to include + @param callback The callback + @param ctx The context passed to the callback + @return CRYPT_OK on success, + CRYPT_NOP if no SubjectPublicKeyInfo was found, + another error if decoding or memory allocation failed +*/ +int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, + enum ltc_oid_id algorithm, ltc_asn1_type param_type, + ltc_asn1_list* parameters, unsigned long *parameters_len, + public_key_decode_cb callback, void *key) +{ + int err; + ltc_asn1_list *decoded_list; + const ltc_asn1_list *spki; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen != 0); + LTC_ARGCHK(callback != NULL); + + if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { + return err; + } + + err = x509_process_public_key_from_spki(spki->data, spki->size, + algorithm, param_type, + parameters, parameters_len, + callback, key); + + if (decoded_list) der_free_sequence_flexi(decoded_list); + + return err; +} + #endif diff --git a/src/pk/asn1/x509/x509_decode_spki.c b/src/pk/asn1/x509/x509_decode_spki.c index 147aaf1c6..144441cd2 100644 --- a/src/pk/asn1/x509/x509_decode_spki.c +++ b/src/pk/asn1/x509/x509_decode_spki.c @@ -26,10 +26,10 @@ @param spki [out] A pointer to the SubjectPublicKeyInfo @return CRYPT_OK on success, CRYPT_NOP if no SubjectPublicKeyInfo was found, another error if decoding failed */ -int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki) +int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, const ltc_asn1_list **spki) { int err; - unsigned long tmp_inlen; + unsigned long tmp_inlen, n, element_is_spki; ltc_asn1_list *decoded_list = NULL, *l; LTC_ARGCHK(in != NULL); @@ -49,29 +49,49 @@ int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) { l = l->child; if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) { + /* TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version MUST be v3 + * } + */ l = l->child; - /* Move forward in the tree until we find this combination - ... - SEQUENCE - SEQUENCE - OBJECT IDENTIFIER - NULL - BIT STRING + /* `l` points now either to 'version' or 'serialNumber', depending on + * whether 'version' is included or defaults to 'v1'. + * 'version' is represented as a LTC_ASN1_CUSTOM_TYPE + * 'serialNumber' is represented as an LTC_ASN1_INTEGER + * Decide now whether to move 5 or 6 elements forward until + * `l` should point to subjectPublicKeyInfo. */ - do { - /* The additional check for l->data is there to make sure - * we won't try to decode a list that has been 'shrunk' - */ - if ((l->type == LTC_ASN1_SEQUENCE) - && (l->data != NULL) - && LOOKS_LIKE_SPKI(l->child)) { - *out = decoded_list; - *spki = l; - return CRYPT_OK; - } + if (l->type == LTC_ASN1_CUSTOM_TYPE) + element_is_spki = 6; + else + element_is_spki = 5; + for (n = 0; n < element_is_spki && l; ++n) { l = l->next; - } while(l); + } + /* The additional check for l->data is there to make sure + * we won't try to decode a list that has been 'shrunk' + */ + if ((l != NULL) + && (l->type == LTC_ASN1_SEQUENCE) + && (l->data != NULL) + && LOOKS_LIKE_SPKI(l->child)) { + *out = decoded_list; + *spki = l; + return CRYPT_OK; + } } } } diff --git a/src/pk/asn1/x509/x509_get_pka.c b/src/pk/asn1/x509/x509_get_pka.c index 23a12edd7..0236c761e 100644 --- a/src/pk/asn1/x509/x509_get_pka.c +++ b/src/pk/asn1/x509/x509_get_pka.c @@ -9,7 +9,7 @@ #ifdef LTC_DER -int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka) +int x509_get_pka(const ltc_asn1_list *pub, enum ltc_pka_id *pka) { der_flexi_check flexi_should[4]; ltc_asn1_list *seqid, *id = NULL; @@ -17,7 +17,7 @@ int x509_get_pka(ltc_asn1_list *pub, enum ltc_pka_id *pka) int err; unsigned long n = 0; LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seqid); - LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); + LTC_SET_DER_FLEXI_CHECK_OPT(flexi_should, n++, LTC_ASN1_BIT_STRING, NULL); LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); if ((err = der_flexi_sequence_cmp(pub, flexi_should)) != CRYPT_OK) { return err; diff --git a/src/pk/asn1/x509/x509_import_spki.c b/src/pk/asn1/x509/x509_import_spki.c index 8b360852e..4e007acf0 100644 --- a/src/pk/asn1/x509/x509_import_spki.c +++ b/src/pk/asn1/x509/x509_import_spki.c @@ -9,28 +9,60 @@ #ifdef LTC_DER -typedef int (*import_fn)(const unsigned char *, unsigned long, void*); +typedef int (*import_fn)(const unsigned char *, unsigned long, void *); -static const import_fn s_import_x509_fns[LTC_PKA_NUM] = { +#ifdef LTC_CURVE25519 +static int s_x25519_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return x25519_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_x25519_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_X25519, + LTC_ASN1_EOL, NULL, NULL, + s_x25519_import_pub, key); +} + +static int s_ed25519_import_pub(const unsigned char *in, unsigned long inlen, void *key) +{ + return ed25519_import_raw(in, inlen, PK_PUBLIC, key); +} +static int s_ed25519_import_spki(const unsigned char *in, unsigned long inlen, void *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_ED25519, + LTC_ASN1_EOL, NULL, NULL, + s_ed25519_import_pub, key); +} +#endif + +static const import_fn s_import_spki_fns[LTC_PKA_NUM] = { #ifdef LTC_MRSA - [LTC_PKA_RSA] = (import_fn)rsa_import_x509, + [LTC_PKA_RSA] = (import_fn)rsa_import_spki, + [LTC_PKA_RSA_PSS] = (import_fn)rsa_import_spki, #endif #ifdef LTC_MDSA - [LTC_PKA_DSA] = (import_fn)dsa_import, + [LTC_PKA_DSA] = (import_fn)dsa_import_spki, #endif #ifdef LTC_MECC - [LTC_PKA_EC] = (import_fn)ecc_import_x509, + [LTC_PKA_EC] = (import_fn)ecc_import_subject_public_key_info, #endif #ifdef LTC_CURVE25519 - [LTC_PKA_X25519] = (import_fn)x25519_import_x509, - [LTC_PKA_ED25519] = (import_fn)ed25519_import_x509, + [LTC_PKA_X25519] = (import_fn)s_x25519_import_spki, + [LTC_PKA_ED25519] = (import_fn)s_ed25519_import_spki, +#endif +#ifdef LTC_CURVE448 + [LTC_PKA_X448] = (import_fn)x448_import_x509, + [LTC_PKA_ED448] = (import_fn)ed448_import_x509, #endif }; int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, ltc_asn1_list **root) { enum ltc_pka_id pka = LTC_PKA_UNDEF; - ltc_asn1_list *d, *spki; + ltc_asn1_list *d; + const ltc_asn1_list *spki; int err; if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) { return err; @@ -39,12 +71,12 @@ int x509_import_spki(const unsigned char *asn1_cert, unsigned long asn1_len, ltc goto err_out; } if (pka < 0 - || pka > LTC_ARRAY_SIZE(s_import_x509_fns) - || s_import_x509_fns[pka] == NULL) { + || pka > LTC_ARRAY_SIZE(s_import_spki_fns) + || s_import_spki_fns[pka] == NULL) { err = CRYPT_PK_INVALID_TYPE; goto err_out; } - if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) { + if ((err = s_import_spki_fns[pka](spki->data, spki->size, &k->u)) == CRYPT_OK) { k->id = pka; } err_out: diff --git a/src/pk/dsa/dsa_import.c b/src/pk/dsa/dsa_import.c index 3db1afd32..91ddcc2be 100644 --- a/src/pk/dsa/dsa_import.c +++ b/src/pk/dsa/dsa_import.c @@ -9,7 +9,7 @@ #ifdef LTC_MDSA -int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) +static int s_dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err; unsigned long zero = 0; @@ -33,7 +33,7 @@ static int s_dsa_import_y(const unsigned char *in, unsigned long inlen, dsa_key return der_decode_integer(in, inlen, key->y); } -LTC_INLINE static int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params) +static LTC_INLINE int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params) { LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); @@ -41,6 +41,24 @@ LTC_INLINE static int s_dsa_set_params(dsa_key *key, ltc_asn1_list *params) return 3; } +static LTC_INLINE int s_dsa_validate(dsa_key *key) +{ + int err, stat; + key->qord = ltc_mp_unsigned_bin_size(key->q); + + /* quick p, q, g validation, without primality testing + * + x, y validation */ + if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) { + return err; + } + + if (stat == 0) { + return CRYPT_INVALID_PACKET; + } + + return CRYPT_OK; +} + static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err; @@ -72,6 +90,28 @@ static int s_dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_k return err; } +int dsa_import_spki(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + + /* init key */ + if ((err = dsa_int_init(key)) != CRYPT_OK) return err; + + if ((err = s_dsa_import_spki(in, inlen, key)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = s_dsa_validate(key)) != CRYPT_OK) { + goto LBL_ERR; + } + + return CRYPT_OK; +LBL_ERR: + dsa_free(key); + return err; +} + static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_key *key) { int err; @@ -100,7 +140,7 @@ static int s_dsa_import_x509(const unsigned char *in, unsigned long inlen, dsa_k */ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { - int err, stat; + int err; unsigned char flags[1]; LTC_ARGCHK(in != NULL); @@ -148,7 +188,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) } } - if (dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) { + if (s_dsa_import_pkcs1(in, inlen, key) == CRYPT_OK) { goto LBL_OK; } if (s_dsa_import_spki(in, inlen, key) == CRYPT_OK) { @@ -159,15 +199,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) } LBL_OK: - key->qord = ltc_mp_unsigned_bin_size(key->q); - - /* quick p, q, g validation, without primality testing - * + x, y validation */ - if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) { - goto LBL_ERR; - } - if (stat == 0) { - err = CRYPT_INVALID_PACKET; + if ((err = s_dsa_validate(key)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/ec25519/tweetnacl.c b/src/pk/ec25519/tweetnacl.c index 37a915c57..48446ef9a 100644 --- a/src/pk/ec25519/tweetnacl.c +++ b/src/pk/ec25519/tweetnacl.c @@ -348,6 +348,16 @@ int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk) static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10}; +static int is_canonical_s(const u8 s[32]) +{ + int i; + for (i = 31; i >= 0; --i) { + if (s[i] < L[i]) return 1; + if (s[i] > L[i]) return 0; + } + return 0; +} + sv modL(u8 *r,i64 x[64]) { i64 carry,i,j; @@ -463,6 +473,7 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen if (*mlen < smlen) return CRYPT_BUFFER_OVERFLOW; *mlen = -1; if (smlen < 64) return CRYPT_INVALID_ARG; + if (!is_canonical_s(sm + 32)) return CRYPT_OK; if (unpackneg(q,pk)) return CRYPT_ERROR; diff --git a/src/pk/ec448/ec448_common.c b/src/pk/ec448/ec448_common.c new file mode 100644 index 000000000..7ea9ad8f0 --- /dev/null +++ b/src/pk/ec448/ec448_common.c @@ -0,0 +1,937 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ec448_common.c + Shared field arithmetic and primitives for Ed448 and X448 + Field arithmetic over p = 2^448 - 2^224 - 1 (Goldilocks prime) + Edwards curve: x^2 + y^2 = 1 + d*x^2*y^2, d = -39081 + RFC 8032 Section 5.2 + + The field representation (16 limbs of 28 bits in long64) and the overall + code structure follow the TweetNaCl pattern used for Curve25519 in + ec25519/tweetnacl.c. TweetNaCl uses 16 limbs of 16 bits for GF(2^255-19); + here the limb width is scaled to 28 bits so that 16 * 28 = 448. This keeps + the same loop bounds, carry propagation shape and multiplication layout, + trading performance for code simplicity. +*/ + +#ifdef LTC_CURVE448 + +/* Field element: 16 limbs of 28 bits each (16 * 28 = 448) + Each limb nominally fits in 28 bits but may temporarily exceed that + during computation; we use long64 for headroom +*/ +typedef long64 gf448[16]; + +/* field constants */ +static const gf448 gf448_0 = {0}; +static const gf448 gf448_1 = {1}; + +/* d = -39081 mod p = p - 39081 + p in 28-bit limbs: all 0x0FFFFFFF except limb 8 = 0x0FFFFFFE + d: limb 0 = 0x0FFFFFFF - 39081 = 0x0FFF6756, limb 8 = 0x0FFFFFFE, rest 0x0FFFFFFF +*/ +static const gf448 ed448_d = { + 0x0FFF6756, 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF, + 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF, + 0x0FFFFFFE, 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF, + 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF, 0x0FFFFFFF +}; + +/* Ed448 base point in compressed bytes (57 bytes, little-endian y, sign bit in top of last byte) */ +static const unsigned char ed448_base_point[57] = { + 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, + 0xad, 0xc8, 0xd7, 0x4e, 0x2c, 0x13, 0xbd, 0xfd, + 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a, + 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, + 0x40, 0x98, 0xa3, 0x6c, 0x73, 0x73, 0xea, 0x4b, + 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88, + 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, + 0x00 +}; + +/* Group order L (little-endian, 57 bytes) */ +static const unsigned char ed448_order[57] = { + 0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23, + 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21, + 0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4, + 0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00 +}; + +/* Group order L as ulong64 array for modular reduction (byte-wise) */ +static const ulong64 L448[57] = { + 0xf3, 0x44, 0x58, 0xab, 0x92, 0xc2, 0x78, 0x23, + 0x55, 0x8f, 0xc5, 0x8d, 0x72, 0xc2, 0x6c, 0x21, + 0x90, 0x36, 0xd6, 0xae, 0x49, 0xdb, 0x4e, 0xc4, + 0xe9, 0x23, 0xca, 0x7c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00 +}; + +/* Field arithmetic for GF(2^448 - 2^224 - 1) - 16 limbs, 28 bits each */ + +static LTC_INLINE void s_gf448_copy(gf448 r, const gf448 a) +{ + int i; + for (i = 0; i < 16; ++i) r[i] = a[i]; +} + +/* Carry propagation + Overflow from limb[15] wraps: 2^448 == 2^224 + 1 (mod p) + So excess from limb 15 adds to limb 0 and limb 8 +*/ +static void s_gf448_carry(gf448 o) +{ + int i; + long64 c; + /* propagate carries from limb 0 to 14 */ + for (i = 0; i < 15; ++i) { + c = o[i] >> 28; + o[i+1] += c; + o[i] -= c << 28; + } + /* limb 15 overflow: 2^(28*16) = 2^448 == 2^224 + 1 */ + c = o[15] >> 28; + o[0] += c; /* + c * 1 */ + o[8] += c; /* + c * 2^224 */ + o[15] -= c << 28; + /* one more pass to settle the extra from limb 0 and 8 */ + for (i = 0; i < 15; ++i) { + c = o[i] >> 28; + o[i+1] += c; + o[i] -= c << 28; + } + c = o[15] >> 28; + o[0] += c; + o[8] += c; + o[15] -= c << 28; +} + +/* Conditional swap: if b==1, swap p and q; if b==0, no-op. Constant-time */ +static void s_gf448_cswap(gf448 p, gf448 q, int b) +{ + long64 t, i, mask = ~((long64)b - 1); + for (i = 0; i < 16; ++i) { + t = mask & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } +} + +/* Pack a field element into 56 bytes (little-endian); fully reduces mod p first */ +static void s_gf448_encode(unsigned char *o, const gf448 n) +{ + int i, j; + long64 b; + gf448 m, t; + for (i = 0; i < 16; ++i) t[i] = n[i]; + + /* carry 3 times to ensure all limbs in [0, 2^28) */ + s_gf448_carry(t); + s_gf448_carry(t); + s_gf448_carry(t); + + /* Subtract p and check borrow p: limbs 0..7 = 0x0FFFFFFF, limb 8 = 0x0FFFFFFE, limbs 9..15 = 0x0FFFFFFF */ + for (j = 0; j < 2; ++j) { + m[0] = t[0] - (long64)0x0FFFFFFF; + for (i = 1; i < 16; i++) { + long64 sub; + if (i == 8) sub = (long64)0x0FFFFFFE; + else sub = (long64)0x0FFFFFFF; + m[i] = t[i] - sub - ((m[i-1] >> 28) & 1); + m[i-1] &= 0x0FFFFFFF; + } + b = (m[15] >> 28) & 1; + m[15] &= 0x0FFFFFFF; + s_gf448_cswap(t, m, 1 - (int)b); + } + + /* Serialize: 16 limbs * 28 bits = 448 bits = 56 bytes + each limb contributes 28 bits = 3.5 bytes + Limb i holds bits [28*i .. 28*i+27] + Byte j holds bits [8*j .. 8*j+7] + */ + XMEMSET(o, 0, 56); + for (i = 0; i < 16; i++) { + /* limb i holds bits starting at bit_offset = 28*i */ + unsigned long bit_off = (unsigned long)i * 28; + unsigned long byte_off = bit_off / 8; + unsigned long bit_shift = bit_off % 8; + /* We need to spread 28 bits starting at byte_off, bit_shift */ + ulong64 val = (ulong64)(t[i] & 0x0FFFFFFF); + val <<= bit_shift; + for (j = 0; j < 5 && byte_off + (unsigned long)j < 56; j++) { + o[byte_off + j] |= (unsigned char)(val & 0xFF); + val >>= 8; + } + } +} + +/* Unpack 56 bytes (little-endian) into a field element */ +static void s_gf448_decode(gf448 o, const unsigned char *n) +{ + int i; + XMEMSET(o, 0, sizeof(gf448)); + for (i = 0; i < 16; i++) { + unsigned long bit_off = (unsigned long)i * 28; + unsigned long byte_off = bit_off / 8; + unsigned long bit_shift = bit_off % 8; + ulong64 val = 0; + int j; + for (j = 0; j < 5 && byte_off + (unsigned long)j < 56; j++) { + val |= ((ulong64)n[byte_off + j]) << (8 * (unsigned long)j); + } + val >>= bit_shift; + o[i] = (long64)(val & 0x0FFFFFFF); + } +} + +/* constant-time equality check */ +static int s_gf448_neq(const gf448 a, const gf448 b) +{ + unsigned char c[56], d[56]; + int i; + ulong32 diff = 0; + s_gf448_encode(c, a); + s_gf448_encode(d, b); + for (i = 0; i < 56; ++i) diff |= (ulong32)(c[i] ^ d[i]); + return (1 & ((diff - 1) >> 8)) - 1; +} + +/* return parity (low bit) of field element */ +static unsigned char s_gf448_parity(const gf448 a) +{ + unsigned char d[56]; + s_gf448_encode(d, a); + return d[0] & 1; +} + +/* Addition */ +static LTC_INLINE void s_gf448_add(gf448 o, const gf448 a, const gf448 b) +{ + int i; + for (i = 0; i < 16; ++i) o[i] = a[i] + b[i]; +} + +/* Subtraction */ +static LTC_INLINE void s_gf448_sub(gf448 o, const gf448 a, const gf448 b) +{ + int i; + for (i = 0; i < 16; ++i) o[i] = a[i] - b[i]; +} + +/* Multiplication: o = a * b mod p + Schoolbook 16x16 -> 31 limbs, then reduce using Goldilocks + 2^448 == 2^224 + 1, so for product limbs t[16..30]: + t[i] += t[i+16] (the "1" part) + t[i+8] += t[i+16] (the "2^224" part, since limb 8 = 224 bits) + Then carry +*/ +static void s_gf448_mul(gf448 o, const gf448 a, const gf448 b) +{ + long64 i, j; + long64 t[31]; + for (i = 0; i < 31; ++i) t[i] = 0; + for (i = 0; i < 16; ++i) + for (j = 0; j < 16; ++j) + t[i + j] += a[i] * b[j]; + + /* reduce t[16..30] */ + for (i = 14; i >= 0; --i) { + t[i] += t[i + 16]; + t[i + 8] += t[i + 16]; + t[i + 16] = 0; + } + /* Now t[0..15] holds the result, but t[8..15] may have gotten extra from + t[16..23] additions. t[15] overflow wraps via Goldilocks + */ + for (i = 0; i < 16; ++i) o[i] = t[i]; + s_gf448_carry(o); + s_gf448_carry(o); +} + +/* Squaring */ +static LTC_INLINE void s_gf448_sqr(gf448 o, const gf448 a) +{ + s_gf448_mul(o, a, a); +} + +/* Inversion: o = a^(p-2) mod p + p-2 = 2^448 - 2^224 - 3 + + p-2 in binary (bit 447 to bit 0): + bits 447..225: all 1 (223 ones) + bit 224: 0 + bits 223..2: all 1 (222 ones) + bit 1: 0 + bit 0: 1 + + Square-and-multiply from MSB: start with a^1, then for each bit: + square, then multiply by a if bit is 1 +*/ +static void s_gf448_inv(gf448 o, const gf448 inp) +{ + gf448 t; + int i; + + s_gf448_copy(t, inp); + + /* Process from bit 446 down (bit 447 is the leading 1, we start with a^1) */ + /* bits 446..225: all 1 (222 bits) */ + for (i = 0; i < 222; i++) { + s_gf448_sqr(t, t); + s_gf448_mul(t, t, inp); + } + + /* bit 224: 0 -> just square */ + s_gf448_sqr(t, t); + + /* bits 223..2: all 1 (222 bits) */ + for (i = 0; i < 222; i++) { + s_gf448_sqr(t, t); + s_gf448_mul(t, t, inp); + } + + /* bit 1: 0 -> just square */ + s_gf448_sqr(t, t); + + /* bit 0: 1 -> square and multiply */ + s_gf448_sqr(t, t); + s_gf448_mul(t, t, inp); + + s_gf448_copy(o, t); +} + +/* Square root: o = a^((p+1)/4) mod p + Since p == 3 (mod 4), this gives the square root of a when it exists + (p+1)/4 = 2^446 - 2^222 = 2^222 * (2^224 - 1) + In binary: 224 ones (bits 445..222) followed by 222 zeros (bits 221..0) +*/ +static void s_gf448_sqrt(gf448 o, const gf448 inp) +{ + gf448 t; + int i; + + s_gf448_copy(t, inp); + + /* bit 445 is the MSB; we start with a^1. bits 444..222: all 1 (223 bits) */ + for (i = 0; i < 223; i++) { + s_gf448_sqr(t, t); + s_gf448_mul(t, t, inp); + } + + /* bits 221..0: all 0 (222 bits) -> just square 222 times */ + for (i = 0; i < 222; i++) { + s_gf448_sqr(t, t); + } + + s_gf448_copy(o, t); +} + + +/* Edwards curve point operations + Curve: x^2 + y^2 = 1 + d*x^2*y^2 (a = 1) + Extended coordinates: (X : Y : Z : T) where x = X/Z, y = Y/Z, T = X*Y/Z +*/ + +/* Unified point addition (works for doubling too) + Extended coordinates on x^2 + y^2 = 1 + d*x^2*y^2 (a=1): + A = X1*X2, B = Y1*Y2, C = d*T1*T2, D = Z1*Z2 + E = (X1+Y1)(X2+Y2) - A - B + F = D - C, G = D + C, H = B - A + X3 = E*F, Y3 = G*H, T3 = E*H, Z3 = F*G +*/ +static void s_ed448_point_add(gf448 p[4], gf448 q[4]) +{ + gf448 a, b, c, d, e, f, g, h, t; + + s_gf448_mul(a, p[0], q[0]); /* A = X1*X2 */ + s_gf448_mul(b, p[1], q[1]); /* B = Y1*Y2 */ + s_gf448_mul(c, p[3], q[3]); + s_gf448_mul(c, c, ed448_d); /* C = d*T1*T2 */ + s_gf448_mul(d, p[2], q[2]); /* D = Z1*Z2 */ + + s_gf448_add(t, p[0], p[1]); /* X1+Y1 */ + s_gf448_add(e, q[0], q[1]); /* X2+Y2 */ + s_gf448_mul(e, t, e); /* (X1+Y1)(X2+Y2) */ + s_gf448_sub(e, e, a); /* - A */ + s_gf448_sub(e, e, b); /* - B -> E */ + + s_gf448_sub(f, d, c); /* F = D - C */ + s_gf448_add(g, d, c); /* G = D + C */ + s_gf448_sub(h, b, a); /* H = B - A (since a=1) */ + + s_gf448_mul(p[0], e, f); /* X3 = E*F */ + s_gf448_mul(p[1], g, h); /* Y3 = G*H */ + s_gf448_mul(p[2], f, g); /* Z3 = F*G */ + s_gf448_mul(p[3], e, h); /* T3 = E*H */ +} + +/* Conditional swap of two points (constant time) */ +static void s_ed448_point_cswap(gf448 p[4], gf448 q[4], unsigned char b) +{ + int i; + for (i = 0; i < 4; ++i) s_gf448_cswap(p[i], q[i], b); +} + +/* Ed448 encoding: 57 bytes = 456 bits + Bytes 0..55 contain the 448-bit little-endian y-coordinate. + Bits 0..6 of byte 56 are zero for canonical encodings. + Bit 7 of byte 56 stores the parity/sign bit of x. +*/ +static void s_ed448_point_encode(unsigned char *r, gf448 p[4]) +{ + gf448 tx, ty, zi; + s_gf448_inv(zi, p[2]); + s_gf448_mul(tx, p[0], zi); + s_gf448_mul(ty, p[1], zi); + s_gf448_encode(r, ty); + /* bit 455 = bit 7 of byte 56 = sign of x */ + r[56] = 0; + r[56] |= s_gf448_parity(tx) << 7; +} + +/* Scalar multiplication: p = [s] * q; Constant-time double-and-add with conditional swap */ +static void s_ed448_scalarmult(gf448 p[4], gf448 q[4], const unsigned char *s) +{ + int i; + /* p = identity = (0, 1, 1, 0) */ + s_gf448_copy(p[0], gf448_0); + s_gf448_copy(p[1], gf448_1); + s_gf448_copy(p[2], gf448_1); + s_gf448_copy(p[3], gf448_0); + + /* Ed448 scalars are 456 bits (57 bytes), but the group order is ~446 bits + Clamped scalar has at most 448 bits (a[56]=0, a[55]|=0x80 sets bit 447) + We scan all 456 bits to be safe + */ + for (i = 455; i >= 0; --i) { + unsigned char b = (s[i / 8] >> (i & 7)) & 1; + s_ed448_point_cswap(p, q, b); + s_ed448_point_add(q, p); + s_ed448_point_add(p, p); + s_ed448_point_cswap(p, q, b); + } +} + +/* Scalar base multiplication: p = [s] * B */ +static void s_ed448_scalarmult_base(gf448 p[4], const unsigned char *s) +{ + gf448 q[4]; + + /* decode base point: unpack y from first 56 bytes */ + s_gf448_decode(q[1], ed448_base_point); + + /* set Z = 1 */ + s_gf448_copy(q[2], gf448_1); + + /* recover x from y: + x^2 + y^2 = 1 + d*x^2*y^2 => x^2 = (1 - y^2) / (1 - d*y^2) */ + { + gf448 y2, num, den, den_inv, x2, x_cand; + s_gf448_sqr(y2, q[1]); /* y^2 */ + s_gf448_sub(num, gf448_1, y2); /* 1 - y^2 */ + s_gf448_mul(den, y2, ed448_d); /* d * y^2 */ + s_gf448_sub(den, gf448_1, den); /* 1 - d*y^2 */ + s_gf448_inv(den_inv, den); + s_gf448_mul(x2, num, den_inv); /* x^2 */ + + /* x = x2^((p+1)/4) -- works since p == 3 mod 4 */ + s_gf448_sqrt(x_cand, x2); + + /* Check sign bit. The base point encoding has sign bit = 0 */ + if (s_gf448_parity(x_cand) != ((ed448_base_point[56] >> 7) & 1)) { + /* negate x */ + s_gf448_sub(x_cand, gf448_0, x_cand); + } + s_gf448_copy(q[0], x_cand); + } + + /* T = X * Y */ + s_gf448_mul(q[3], q[0], q[1]); + + s_ed448_scalarmult(p, q, s); +} + +/* Decode a point from 57-byte encoding; returns 0 on success, -1 on failure */ +static int s_ed448_point_decode(gf448 r[4], const unsigned char p[57]) +{ + gf448 y2, num, den, den_inv, x2, x_cand, chk; + unsigned char sign_bit; + + /* y from the first 56 bytes (448 bits) */ + s_gf448_decode(r[1], p); + /* bit 7 of byte 56 is the x sign bit */ + sign_bit = (p[56] >> 7) & 1; + + s_gf448_copy(r[2], gf448_1); + + /* x^2 = (1 - y^2) / (1 - d*y^2) */ + s_gf448_sqr(y2, r[1]); + s_gf448_sub(num, gf448_1, y2); /* 1 - y^2 */ + s_gf448_mul(den, y2, ed448_d); /* d * y^2 */ + s_gf448_sub(den, gf448_1, den); /* 1 - d*y^2 */ + s_gf448_inv(den_inv, den); + s_gf448_mul(x2, num, den_inv); + + /* Compute square root candidate */ + s_gf448_sqrt(x_cand, x2); + + /* Verify: x_cand^2 == x2 ? */ + s_gf448_sqr(chk, x_cand); + if (s_gf448_neq(chk, x2)) { + /* Not a valid point */ + return -1; + } + + /* Adjust sign */ + if (s_gf448_parity(x_cand) != sign_bit) { + s_gf448_sub(x_cand, gf448_0, x_cand); + } + + s_gf448_copy(r[0], x_cand); + s_gf448_mul(r[3], r[0], r[1]); /* T = X * Y */ + + return 0; +} + +/* Scalar arithmetic modulo L (group order) */ + +/* Reduce x[0..113] modulo L, store 57-byte result in r + + Uses the relation 2^448 == 4*c (mod L), where c = 2^446 - L is a 28-byte number + Byte position i (for i >= 56) represents 2^(8*i) = 2^(8*(i-56)) * 2^448 + == 2^(8*(i-56)) * 4*c (mod L) + So x[i] for i >= 56 folds into positions (i-56)..(i-56+27) as 4*x[i]*c[j] +*/ +static void s_sc448_reduce(unsigned char *r, long64 x[114]) +{ + long64 carry, i, j; + int round; + + /* c = 2^446 - L (28 bytes, little-endian) */ + static const long64 C448[28] = { + 0x0D, 0xBB, 0xA7, 0x54, 0x6D, 0x3D, 0x87, 0xDC, + 0xAA, 0x70, 0x3A, 0x72, 0x8D, 0x3D, 0x93, 0xDE, + 0x6F, 0xC9, 0x29, 0x51, 0xB6, 0x24, 0xB1, 0x3B, + 0x16, 0xDC, 0x35, 0x83 + }; + + /* Perform up to 4 rounds of folding to guarantee full reduction */ + for (round = 0; round < 4; round++) { + /* Fold bytes 56..113 into lower positions */ + for (i = 113; i >= 56; --i) { + if (x[i] == 0) continue; + for (j = 0; j < 28; j++) { + x[i - 56 + j] += 4 * x[i] * C448[j]; + } + x[i] = 0; + } + + /* Carry normalize from 0 to 113 */ + carry = 0; + for (i = 0; i < 114; i++) { + x[i] += carry; + carry = x[i] >> 8; + x[i] &= 255; + } + /* If no overflow into high bytes, we can stop early */ + if (carry == 0) { + int done = 1; + for (i = 56; i < 114; i++) { + if (x[i] != 0) { done = 0; break; } + } + if (done) break; + } + } + + /* Now x[0..55] holds the value, x[56..113] should be zero + Up to 4 conditional subtractions of L ensure x < L */ + for (round = 0; round < 4; round++) { + long64 t[57], borrow; + borrow = 0; + for (i = 0; i < 57; i++) { + t[i] = x[i] - (long64)L448[i] - borrow; + borrow = (t[i] >> 63) & 1; + t[i] &= 255; + } + /* If borrow=0 => x >= L, replace x with t. If borrow=1 => x < L, keep x */ + if (borrow == 0) { + for (i = 0; i < 57; i++) x[i] = t[i]; + } + } + + for (i = 0; i < 57; i++) { + r[i] = (unsigned char)(x[i] & 255); + } +} + +static void s_sc448_reduce_buf(unsigned char *r) +{ + long64 x[114]; + int i; + for (i = 0; i < 114; ++i) x[i] = (ulong64)r[i]; + for (i = 0; i < 114; ++i) r[i] = 0; + s_sc448_reduce(r, x); +} + +/* Check if scalar s < L (group order); returns 1 if s < L, 0 otherwise */ +static int s_sc448_lt_order(const unsigned char *s) +{ + int i; + /* s and ed448_order are both 57 bytes LE */ + for (i = 56; i >= 0; i--) { + if (s[i] < ed448_order[i]) return 1; + if (s[i] > ed448_order[i]) return 0; + } + return 0; /* equal means not strictly less */ +} + +/* Ed448 internal API functions */ + +/** + Derive public key from secret key + RFC 8032 Section 5.2.5: + 1. SHAKE256(sk, 57) -> 114 bytes + 2. Clamp first 57 bytes: a[0] &= 0xFC, a[55] |= 0x80, a[56] = 0 + 3. pk = [a]B +*/ +int ec448_sk_to_pk_internal(unsigned char *pk, const unsigned char *sk) +{ + unsigned char az[114]; + gf448 p[4]; + int err; + + { unsigned long azlen = 114; if ((err = sha3_shake_memory(256, sk, 57, az, &azlen)) != CRYPT_OK) return err; } + + /* clamp */ + az[0] &= 0xFC; + az[55] |= 0x80; + az[56] = 0; + + s_ed448_scalarmult_base(p, az); + s_ed448_point_encode(pk, p); + + zeromem(az, sizeof(az)); + return CRYPT_OK; +} + +/** + Generate Ed448 keypair +*/ +int ec448_keypair_internal(prng_state *prng, int wprng, unsigned char *pk, unsigned char *sk) +{ + int err; + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) return err; + + if (prng_descriptor[wprng].read(sk, 57, prng) != 57) { + return CRYPT_ERROR_READPRNG; + } + + if ((err = ec448_sk_to_pk_internal(pk, sk)) != CRYPT_OK) { + return err; + } + + return CRYPT_OK; +} + +/** + Ed448 sign + + RFC 8032 Section 5.2.6: + 1. SHAKE256(sk, 57) -> (a, prefix) where a is clamped first 57 bytes + 2. r = SHAKE256(DOM4(0,ctx) || prefix || msg) mod L + 3. R = [r]B encoded + 4. h = SHAKE256(DOM4(0,ctx) || R || pk || msg) mod L + 5. S = (r + h*a) mod L + 6. sig = R || S (114 bytes) + + The sm buffer receives R || S || msg (smlen = mlen + 114) + ctx/cs: DOM4 context; for plain Ed448, ctx=NULL, cs=0 but DOM4 is still prepended +*/ +int ec448_sign_internal(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk, const unsigned char *pk, + const unsigned char *ctx, unsigned long long cs) +{ + unsigned char az[114], nonce[114], hram[114]; + long64 x[114]; + long64 i, j; + gf448 p[4]; + int err; + + /* ctx/cs is a pre-built DOM4 prefix that gets prepended to all hashes + The wrapper functions build it: + ed448_sign -> DOM4(0, "") + ed448ctx_sign -> DOM4(0, ctx) + ed448ph_sign -> DOM4(1, ctx) + */ + + /* Hash secret key */ + { unsigned long azlen = 114; if ((err = sha3_shake_memory(256, sk, 57, az, &azlen)) != CRYPT_OK) return err; } + + /* Clamp scalar a */ + az[0] &= 0xFC; + az[55] |= 0x80; + az[56] = 0; + + /* Compute nonce r = SHAKE256(ctx || prefix || msg) mod L */ + /* ctx already contains DOM4 prefix from the wrapper */ + *smlen = mlen + 114; + + if (ctx != NULL && cs > 0) { + hash_state md; + if ((err = sha3_shake_init(&md, 256)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_process(&md, ctx, (unsigned long)cs)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_process(&md, az + 57, 57)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_process(&md, m, (unsigned long)mlen)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_done(&md, nonce, 114)) != CRYPT_OK) goto cleanup; + } + else { + hash_state md; + if ((err = sha3_shake_init(&md, 256)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_process(&md, az + 57, 57)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_process(&md, m, (unsigned long)mlen)) != CRYPT_OK) goto cleanup; + if ((err = sha3_shake_done(&md, nonce, 114)) != CRYPT_OK) goto cleanup; + } + + s_sc448_reduce_buf(nonce); + + /* R = [r]B */ + s_ed448_scalarmult_base(p, nonce); + s_ed448_point_encode(sm, p); /* sm[0..56] = R */ + + /* Compute h = SHAKE256(ctx || R || pk || msg) mod L */ + { + hash_state md; + if ((err = sha3_shake_init(&md, 256)) != CRYPT_OK) goto cleanup; + if (ctx != NULL && cs > 0) { + if ((err = sha3_shake_process(&md, ctx, (unsigned long)cs)) != CRYPT_OK) goto cleanup; + } + if ((err = sha3_shake_process(&md, sm, 57)) != CRYPT_OK) goto cleanup; /* R */ + if ((err = sha3_shake_process(&md, pk, 57)) != CRYPT_OK) goto cleanup; /* pk */ + if ((err = sha3_shake_process(&md, m, (unsigned long)mlen)) != CRYPT_OK) goto cleanup; /* msg */ + if ((err = sha3_shake_done(&md, hram, 114)) != CRYPT_OK) goto cleanup; + } + s_sc448_reduce_buf(hram); + + /* S = (r + h * a) mod L */ + for (i = 0; i < 114; ++i) x[i] = 0; + for (i = 0; i < 57; ++i) x[i] = (ulong64)nonce[i]; + for (i = 0; i < 57; ++i) + for (j = 0; j < 57; ++j) + x[i + j] += (long64)hram[i] * (long64)(ulong64)az[j]; + s_sc448_reduce(sm + 57, x); /* sm[57..113] = S */ + + err = CRYPT_OK; + +cleanup: + zeromem(az, sizeof(az)); + zeromem(nonce, sizeof(nonce)); + zeromem(hram, sizeof(hram)); + zeromem(x, sizeof(x)); + return err; +} + +/** + Ed448 verify + + RFC 8032 Section 5.2.7: + 1. Parse sig as R (57 bytes) || S (57 bytes) + 2. Decode R, pk as points + 3. Check S < L + 4. h = SHAKE256(DOM4(0,ctx) || R || pk || msg) mod L + 5. Check [S]B == R + [h]A + + sm = sig || msg (smlen = siglen + msglen, siglen = 114) + Returns stat=1 if valid, stat=0 if invalid +*/ +int ec448_verify_internal(int *stat, unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *ctx, unsigned long long cs, + const unsigned char *pk) +{ + unsigned char hram[114]; + unsigned char t[57]; + gf448 p[4], q[4], r_point[4]; + unsigned long long i; + int err; + unsigned char s_bytes[57]; + + *stat = 0; + + if (*mlen < smlen) return CRYPT_BUFFER_OVERFLOW; + *mlen = (unsigned long long)-1; + if (smlen < 114) return CRYPT_INVALID_ARG; + + /* Decode public key A */ + if (s_ed448_point_decode(q, pk) != 0) return CRYPT_ERROR; + + /* Copy sm to m for manipulation */ + XMEMMOVE(m, sm, (unsigned long)smlen); + + /* Extract S (bytes 57..113 of signature) */ + XMEMCPY(s_bytes, m + 57, 57); + + /* Check S < L */ + if (!s_sc448_lt_order(s_bytes)) { + for (i = 0; i < smlen - 114; ++i) m[i] = 0; + return CRYPT_OK; + } + + /* Decode R (bytes 0..56 of signature) */ + if (s_ed448_point_decode(r_point, m) != 0) { + for (i = 0; i < smlen - 114; ++i) m[i] = 0; + return CRYPT_OK; + } + + /* Replace S in m with pk for hashing: m = R || pk || msg */ + XMEMCPY(m + 57, pk, 57); + + /* h = SHAKE256(ctx || R || pk || msg) mod L */ + { + hash_state md; + if ((err = sha3_shake_init(&md, 256)) != CRYPT_OK) return err; + if (ctx != NULL && cs > 0) { + if ((err = sha3_shake_process(&md, ctx, (unsigned long)cs)) != CRYPT_OK) return err; + } + if ((err = sha3_shake_process(&md, m, (unsigned long)smlen)) != CRYPT_OK) return err; + if ((err = sha3_shake_done(&md, hram, 114)) != CRYPT_OK) return err; + } + s_sc448_reduce_buf(hram); + + /* Compute [h]A */ + s_ed448_scalarmult(p, q, hram); + + /* Add R: p = R + [h]A */ + s_ed448_point_add(p, r_point); + + /* Compute [S]B */ + s_ed448_scalarmult_base(q, s_bytes); + + /* Compare: [S]B == R + [h]A */ + s_ed448_point_encode(t, q); + { + unsigned char t2[57]; + s_ed448_point_encode(t2, p); + + /* Constant-time comparison */ + { + ulong32 diff = 0; + int idx; + for (idx = 0; idx < 57; idx++) diff |= (ulong32)(t[idx] ^ t2[idx]); + if (diff == 0) { + *stat = 1; + smlen -= 114; + XMEMMOVE(m, m + 114, (unsigned long)smlen); + *mlen = smlen; + } + else { + for (i = 0; i < smlen - 114; ++i) m[i] = 0; + zeromem(m, (unsigned long)(smlen - 114)); + } + } + } + + return CRYPT_OK; +} + +/* Ed448 prehash: SHAKE256(msg) truncated to 64 bytes */ +int ec448_prehash_internal(unsigned char *out, const unsigned char *msg, unsigned long long msglen) +{ + unsigned long phlen = 64; + return sha3_shake_memory(256, msg, (unsigned long)msglen, out, &phlen); +} + + +/* X448 scalar multiplication (RFC 7748 Montgomery ladder) */ +int ec448_scalarmult_internal(unsigned char *out, const unsigned char *scalar, const unsigned char *point) +{ + unsigned char sk[56]; + gf448 x1, x2, z2, x3, z3; + gf448 a, aa, b, bb, e, c, d, da, cb, t; + static const gf448 a24 = {39081}; + int i; + unsigned char swap = 0; + + /* clamp scalar */ + XMEMCPY(sk, scalar, 56); + sk[0] &= 252; + sk[55] |= 128; + + /* decode u-coordinate */ + s_gf448_decode(x1, point); + + /* x_2 = 1, z_2 = 0, x_3 = u, z_3 = 1 */ + s_gf448_copy(x3, x1); + s_gf448_copy(x2, gf448_1); + s_gf448_copy(z2, gf448_0); + s_gf448_copy(z3, gf448_1); + + for (i = 447; i >= 0; --i) { + unsigned char k_t = (sk[i / 8] >> (i & 7)) & 1; + swap ^= k_t; + s_gf448_cswap(x2, x3, swap); + s_gf448_cswap(z2, z3, swap); + swap = k_t; + + s_gf448_add(a, x2, z2); /* A = x_2 + z_2 */ + s_gf448_sqr(aa, a); /* AA = A^2 */ + s_gf448_sub(b, x2, z2); /* B = x_2 - z_2 */ + s_gf448_sqr(bb, b); /* BB = B^2 */ + s_gf448_sub(e, aa, bb); /* E = AA - BB */ + s_gf448_add(c, x3, z3); /* C = x_3 + z_3 */ + s_gf448_sub(d, x3, z3); /* D = x_3 - z_3 */ + s_gf448_mul(da, d, a); /* DA = D * A */ + s_gf448_mul(cb, c, b); /* CB = C * B */ + + s_gf448_add(x3, da, cb); /* x_3 = (DA + CB)^2 */ + s_gf448_sqr(x3, x3); + + s_gf448_sub(z3, da, cb); /* z_3 = x_1*(DA-CB)^2 */ + s_gf448_sqr(z3, z3); + s_gf448_mul(z3, x1, z3); + + s_gf448_mul(x2, aa, bb); /* x_2 = AA * BB */ + + s_gf448_mul(t, a24, e); /* z_2 = E*(AA + a24*E) */ + s_gf448_add(t, aa, t); + s_gf448_mul(z2, e, t); + } + + s_gf448_cswap(x2, x3, swap); + s_gf448_cswap(z2, z3, swap); + + s_gf448_inv(t, z2); + s_gf448_mul(x2, x2, t); + + s_gf448_encode(out, x2); + + zeromem(sk, sizeof(sk)); + return CRYPT_OK; +} + +/* X448 scalar multiplication with base point u=5 */ +static const unsigned char s_x448_basepoint[56] = { + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int ec448_scalarmult_base_internal(unsigned char *out, const unsigned char *scalar) +{ + ec448_scalarmult_internal(out, scalar, s_x448_basepoint); + return CRYPT_OK; +} + +#endif diff --git a/src/pk/ec448/ec448_crypto_ctx.c b/src/pk/ec448/ec448_crypto_ctx.c new file mode 100644 index 000000000..335d3c916 --- /dev/null +++ b/src/pk/ec448/ec448_crypto_ctx.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ec448_crypto_ctx.c + Build DOM4 context prefix for Ed448ctx / Ed448ph (RFC 8032, Section 5.2). + DOM4(x, y) = "SigEd448" || octet(x) || octet(OLEN(y)) || y +*/ + +#ifdef LTC_CURVE448 + +/** + @param out [out] Destination buffer + @param outlen [in/out] Max size / resulting size + @param flag 0 for Ed448/Ed448ctx, 1 for Ed448ph + @param ctx Context string (may be NULL if ctxlen==0) + @param ctxlen Length of context (0..255) + @return CRYPT_OK if successful +*/ +int ec448_crypto_ctx(unsigned char *out, unsigned long *outlen, unsigned char flag, + const unsigned char *ctx, unsigned long ctxlen) +{ + unsigned char *buf = out; + + const char *prefix = "SigEd448"; + const unsigned long prefix_len = 8; + const unsigned char ctxlen8 = (unsigned char)ctxlen; + + if (ctxlen > 255u) return CRYPT_INPUT_TOO_LONG; + if (*outlen < prefix_len + 2u + ctxlen) return CRYPT_BUFFER_OVERFLOW; + + XMEMCPY(buf, prefix, prefix_len); + buf += prefix_len; + XMEMCPY(buf, &flag, 1); + buf++; + XMEMCPY(buf, &ctxlen8, 1); + buf++; + + if (ctxlen > 0u) { + LTC_ARGCHK(ctx != NULL); + XMEMCPY(buf, ctx, ctxlen); + buf += ctxlen; + } + + *outlen = (unsigned long)(buf - out); + + return CRYPT_OK; +} + +#endif diff --git a/src/pk/ec448/ec448_export.c b/src/pk/ec448/ec448_export.c new file mode 100644 index 000000000..7b1934c1e --- /dev/null +++ b/src/pk/ec448/ec448_export.c @@ -0,0 +1,98 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ec448_export.c + Generic export of a Curve448 key to a binary packet +*/ + +#ifdef LTC_CURVE448 + +/** + Generic export of a Curve448 key to a binary packet + @param out [out] The destination for the key + @param outlen [in/out] The max size and resulting size of the key + @param which Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC) + @param key The key you wish to export + @return CRYPT_OK if successful +*/ +int ec448_export( unsigned char *out, unsigned long *outlen, + int which, + const curve448_key *key) +{ + int err, std; + const char* OID; + unsigned long oid[16], oidlen; + ltc_asn1_list alg_id[1]; + enum ltc_oid_id oid_id; + unsigned char private_key[59]; + unsigned long version, private_key_len = sizeof(private_key); + unsigned long key_sz; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + std = which & PK_STD; + which &= ~PK_STD; + if ((err = pk_get_oid_id(key->pka, &oid_id)) != CRYPT_OK) { + return err; + } + + /* X448 keys are 56 bytes, Ed448 keys are 57 bytes */ + key_sz = (key->pka == LTC_PKA_ED448) ? 57uL : 56uL; + + if (which == PK_PRIVATE) { + if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if (std == PK_STD) { + if ((err = pk_get_oid(oid_id, &OID)) != CRYPT_OK) { + return err; + } + oidlen = LTC_ARRAY_SIZE(oid); + if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { + return err; + } + + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen); + + /* encode private key as PKCS#8 */ + if ((err = der_encode_octet_string(key->priv, key_sz, private_key, &private_key_len)) != CRYPT_OK) { + return err; + } + + version = 0; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1uL, &version, + LTC_ASN1_SEQUENCE, 1uL, alg_id, + LTC_ASN1_OCTET_STRING, private_key_len, private_key, + LTC_ASN1_EOL, 0uL, NULL); + } else { + if (*outlen < key_sz) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + XMEMCPY(out, key->priv, key_sz); + err = CRYPT_OK; + } + *outlen = key_sz; + } + } else { + if (std == PK_STD) { + /* encode public key as SubjectPublicKeyInfo */ + err = x509_encode_subject_public_key_info(out, outlen, oid_id, key->pub, key_sz, LTC_ASN1_EOL, NULL, 0); + } else { + if (*outlen < key_sz) { + err = CRYPT_BUFFER_OVERFLOW; + } else { + XMEMCPY(out, key->pub, key_sz); + err = CRYPT_OK; + } + *outlen = key_sz; + } + } + + return err; +} + +#endif diff --git a/src/pk/ec448/ec448_import_pkcs8.c b/src/pk/ec448/ec448_import_pkcs8.c new file mode 100644 index 000000000..0de083472 --- /dev/null +++ b/src/pk/ec448/ec448_import_pkcs8.c @@ -0,0 +1,86 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ec448_import_pkcs8.c + Generic import of a Curve448 private key in PKCS#8 format +*/ + +#ifdef LTC_CURVE448 + +typedef int (*sk_to_pk)(unsigned char *pk, const unsigned char *sk); + +int ec448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + enum ltc_oid_id id, + curve448_key *key) +{ + int err; + unsigned long key_len; + sk_to_pk fp; + + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + LTC_UNUSED_PARAM(alg_id); + + switch (id) { + case LTC_OID_X448: + fp = ec448_scalarmult_base_internal; + break; + case LTC_OID_ED448: + fp = ec448_sk_to_pk_internal; + break; + default: + return CRYPT_PK_INVALID_TYPE; + } + + key_len = sizeof(key->priv); + if ((err = der_decode_octet_string(priv_key->data, priv_key->size, key->priv, &key_len)) == CRYPT_OK) { + fp(key->pub, key->priv); + key->type = PK_PRIVATE; + err = pk_get_pka_id(id, &key->pka); + } + return err; +} + +/** + Generic import of a Curve448 private key in PKCS#8 format + @param in The packet to import from + @param inlen It's length (octets) + @param pw_ctx The password context when decrypting the private key + @param id The type of the private key + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int ec448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, + enum ltc_oid_id id, + curve448_key *key) +{ + int err; + ltc_asn1_list *l = NULL; + ltc_asn1_list *alg_id, *priv_key; + enum ltc_oid_id pka; + + LTC_ARGCHK(in != NULL); + + err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l); + if (err != CRYPT_OK) return err; + + if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) { + goto LBL_DER_FREE; + } + if (pka != id) { + err = CRYPT_INVALID_PACKET; + goto LBL_DER_FREE; + } + + err = ec448_import_pkcs8_asn1(alg_id, priv_key, id, key); + +LBL_DER_FREE: + der_free_sequence_flexi(l); + return err; +} + +#endif diff --git a/src/pk/ecc/ecc_recover_key.c b/src/pk/ecc/ecc_recover_key.c index ebd1a410d..7d1e01e4c 100644 --- a/src/pk/ecc/ecc_recover_key.c +++ b/src/pk/ecc/ecc_recover_key.c @@ -65,7 +65,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen, err = CRYPT_MEM; goto error; } - recid = (opts->recid != NULL) ? *(opts->recid) : -1; + recid = (opts->enable_recovery_id) ? opts->recovery_id : -1; if (opts->type == LTC_ECCSIG_RFC7518) { /* RFC7518 format - raw (r,s) */ diff --git a/src/pk/ecc/ecc_sign_hash_eth27.c b/src/pk/ecc/ecc_sign_hash_eth27.c index 4944d4527..d340070d5 100644 --- a/src/pk/ecc/ecc_sign_hash_eth27.c +++ b/src/pk/ecc/ecc_sign_hash_eth27.c @@ -19,7 +19,7 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ltc_ecc_sig_opts *opts, const ecc_key *key) { - int err, recid; + int err; void *r, *s; unsigned long i; @@ -37,9 +37,9 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } + opts->enable_recovery_id = 1; + if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) return err; - if (opts->recid == NULL) - opts->recid = &recid; if ((err = ecc_sign_hash_internal(in, inlen, r, s, opts, key)) != CRYPT_OK) goto error; zeromem(out, 65); @@ -48,12 +48,10 @@ int ecc_sign_hash_eth27(const unsigned char *in, unsigned long inlen, if ((err = ltc_mp_to_unsigned_bin(r, out + 32 - i)) != CRYPT_OK) goto error; i = ltc_mp_unsigned_bin_size(s); if ((err = ltc_mp_to_unsigned_bin(s, out + 64 - i)) != CRYPT_OK) goto error; - out[64] = (unsigned char)(*(opts->recid) + 27); /* Recovery ID is 27/28 for Ethereum */ + out[64] = (unsigned char)(opts->recovery_id + 27); /* Recovery ID is 27/28 for Ethereum */ err = CRYPT_OK; error: - if (opts->recid == &recid) - opts->recid = NULL; ltc_mp_deinit_multi(r, s, LTC_NULL); return err; } diff --git a/src/pk/ecc/ecc_sign_hash_internal.c b/src/pk/ecc/ecc_sign_hash_internal.c index 9e2db46bc..670fbe66f 100644 --- a/src/pk/ecc/ecc_sign_hash_internal.c +++ b/src/pk/ecc/ecc_sign_hash_internal.c @@ -67,7 +67,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, /* find r = x1 mod n */ if ((err = ltc_mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } - if (opts->recid) { + if (opts->enable_recovery_id) { /* find recovery ID (if needed) */ v = 0; if (ltc_mp_copy(pubkey.pubkey.x, s) != CRYPT_OK) { goto error; } @@ -102,7 +102,7 @@ int ecc_sign_hash_internal(const unsigned char *in, unsigned long inlen, goto errnokey; } - if (opts->recid) *opts->recid = v; + if (opts->enable_recovery_id) opts->recovery_id = v; goto errnokey; error: diff --git a/src/pk/ed448/ed448_export.c b/src/pk/ed448/ed448_export.c new file mode 100644 index 000000000..4e1b58568 --- /dev/null +++ b/src/pk/ed448/ed448_export.c @@ -0,0 +1,31 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_export.c + Export an Ed448 key to a binary packet, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +/** + Export an Ed448 key to a binary packet + @param out [out] The destination for the key + @param outlen [in/out] The max size and resulting size of the Ed448 key + @param which Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC) + @param key The key you wish to export + @return CRYPT_OK if successful +*/ +int ed448_export( unsigned char *out, unsigned long *outlen, + int which, + const curve448_key *key) +{ + LTC_ARGCHK(key != NULL); + + if (key->pka != LTC_PKA_ED448) return CRYPT_PK_INVALID_TYPE; + + return ec448_export(out, outlen, which, key); +} + +#endif diff --git a/src/pk/ed448/ed448_import.c b/src/pk/ed448/ed448_import.c new file mode 100644 index 000000000..f4db0918c --- /dev/null +++ b/src/pk/ed448/ed448_import.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_import.c + Import an Ed448 key from a SubjectPublicKeyInfo, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +/** + Import an Ed448 public key + @param in The packet to read + @param inlen The length of the input packet + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int ed448_import(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + int err; + unsigned long key_len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + key_len = sizeof(key->pub); + if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_ED448, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) { + key->type = PK_PUBLIC; + key->pka = LTC_PKA_ED448; + } + return err; +} + +#endif diff --git a/src/pk/ed448/ed448_import_pkcs8.c b/src/pk/ed448/ed448_import_pkcs8.c new file mode 100644 index 000000000..1a6ab4ed1 --- /dev/null +++ b/src/pk/ed448/ed448_import_pkcs8.c @@ -0,0 +1,33 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_import_pkcs8.c + Import an Ed448 key in PKCS#8 format, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +int ed448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + curve448_key *key) +{ + return ec448_import_pkcs8_asn1(alg_id, priv_key, LTC_OID_ED448, key); +} + +/** + Import an Ed448 private key in PKCS#8 format + @param in The packet to import from + @param inlen It's length (octets) + @param pw_ctx The password context when decrypting the private key + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int ed448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key) +{ + return ec448_import_pkcs8(in, inlen, pw_ctx, LTC_OID_ED448, key); +} + +#endif diff --git a/src/pk/ed448/ed448_import_raw.c b/src/pk/ed448/ed448_import_raw.c new file mode 100644 index 000000000..b887d4b87 --- /dev/null +++ b/src/pk/ed448/ed448_import_raw.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_import_raw.c + Set the parameters of an Ed448 key, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +/** + Set the parameters of an Ed448 key + + @param in The key + @param inlen The length of the key + @param which Which type of key (PK_PRIVATE or PK_PUBLIC) + @param key [out] Destination of the key + @return CRYPT_OK if successful +*/ +int ed448_import_raw(const unsigned char *in, unsigned long inlen, int which, curve448_key *key) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + if (which == PK_PRIVATE) { + LTC_ARGCHK(inlen == 57uL); + XMEMCPY(key->priv, in, sizeof(key->priv)); + ec448_sk_to_pk_internal(key->pub, key->priv); + } else if (which == PK_PUBLIC) { + LTC_ARGCHK(inlen == 57uL); + XMEMCPY(key->pub, in, sizeof(key->pub)); + } else { + return CRYPT_INVALID_ARG; + } + key->pka = LTC_PKA_ED448; + key->type = which; + + return CRYPT_OK; +} + +#endif diff --git a/src/pk/ed448/ed448_import_x509.c b/src/pk/ed448/ed448_import_x509.c new file mode 100644 index 000000000..c90acf42e --- /dev/null +++ b/src/pk/ed448/ed448_import_x509.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_import_x509.c + Import an Ed448 key from a X.509 certificate, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +static int s_ed448_decode(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + if (inlen != sizeof(key->pub)) return CRYPT_PK_INVALID_SIZE; + XMEMCPY(key->pub, in, sizeof(key->pub)); + return CRYPT_OK; +} + +/** + Import an Ed448 public key from a X.509 certificate + @param in The DER encoded X.509 certificate + @param inlen The length of the certificate + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int ed448_import_x509(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = x509_decode_public_key_from_certificate(in, inlen, + LTC_OID_ED448, + LTC_ASN1_EOL, NULL, NULL, + (public_key_decode_cb)s_ed448_decode, key)) != CRYPT_OK) { + return err; + } + key->type = PK_PUBLIC; + key->pka = LTC_PKA_ED448; + + return err; +} + +#endif diff --git a/src/pk/ed448/ed448_make_key.c b/src/pk/ed448/ed448_make_key.c new file mode 100644 index 000000000..0170dff04 --- /dev/null +++ b/src/pk/ed448/ed448_make_key.c @@ -0,0 +1,36 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_make_key.c + Create an Ed448 key, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +/** + Create an Ed448 key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful +*/ +int ed448_make_key(prng_state *prng, int wprng, curve448_key *key) +{ + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = ec448_keypair_internal(prng, wprng, key->pub, key->priv)) != CRYPT_OK) { + return err; + } + + key->type = PK_PRIVATE; + key->pka = LTC_PKA_ED448; + + return err; +} + +#endif diff --git a/src/pk/ed448/ed448_sign.c b/src/pk/ed448/ed448_sign.c new file mode 100644 index 000000000..5f6d2dce3 --- /dev/null +++ b/src/pk/ed448/ed448_sign.c @@ -0,0 +1,136 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_sign.c + Create an Ed448 signature, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +static int s_ed448_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key) +{ + unsigned char *s; + unsigned long long smlen; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(siglen != NULL); + LTC_ARGCHK(private_key != NULL); + + if (private_key->pka != LTC_PKA_ED448) return CRYPT_PK_INVALID_TYPE; + if (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if (*siglen < 114uL) { + *siglen = 114uL; + return CRYPT_BUFFER_OVERFLOW; + } + + smlen = msglen + 114; + s = XMALLOC((unsigned long)smlen); + if (s == NULL) return CRYPT_MEM; + + err = ec448_sign_internal(s, &smlen, + msg, msglen, + private_key->priv, private_key->pub, + ctx, ctxlen); + + XMEMCPY(sig, s, 114uL); + *siglen = 114uL; + +#ifdef LTC_CLEAN_STACK + zeromem(s, (unsigned long)smlen); +#endif + XFREE(s); + + return err; +} + +/** + Create an Ed448ctx signature. + @param msg The data to be signed + @param msglen [in] The size of the data to be signed + @param sig [out] The destination of the signature + @param siglen [in/out] The max size and resulting size of the signature + @param ctx [in] The context + @param ctxlen [in] The size of the context + @param private_key The private Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448ctx_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key) +{ + int err; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + LTC_ARGCHK(ctx != NULL); + + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen)) != CRYPT_OK) + return err; + + return s_ed448_sign(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, private_key); +} + +/** + Create an Ed448ph signature. + @param msg The data to be signed + @param msglen [in] The size of the data to be signed + @param sig [out] The destination of the signature + @param siglen [in/out] The max size and resulting size of the signature + @param ctx [in] The context + @param ctxlen [in] The size of the context + @param private_key The private Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448ph_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const unsigned char *ctx, unsigned long ctxlen, + const curve448_key *private_key) +{ + int err; + unsigned char msg_hash[64]; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK) + return err; + + if ((err = ec448_prehash_internal(msg_hash, msg, msglen)) != CRYPT_OK) + return err; + + return s_ed448_sign(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, private_key); +} + +/** + Create an Ed448 signature (pure mode). + @param msg The data to be signed + @param msglen [in] The size of the data to be signed + @param sig [out] The destination of the signature + @param siglen [in/out] The max size and resulting size of the signature + @param private_key The private Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448_sign(const unsigned char *msg, unsigned long msglen, + unsigned char *sig, unsigned long *siglen, + const curve448_key *private_key) +{ + int err; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + /* Pure Ed448 still uses DOM4 with flag=0 and empty context */ + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, NULL, 0)) != CRYPT_OK) + return err; + + return s_ed448_sign(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, private_key); +} + +#endif diff --git a/src/pk/ed448/ed448_verify.c b/src/pk/ed448/ed448_verify.c new file mode 100644 index 000000000..b39d5185a --- /dev/null +++ b/src/pk/ed448/ed448_verify.c @@ -0,0 +1,143 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file ed448_verify.c + Verify an Ed448 signature, Steffen Jaeckel +*/ + +#ifdef LTC_CURVE448 + +static int s_ed448_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key) +{ + unsigned char *m; + unsigned long long mlen; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(public_key != NULL); + + *stat = 0; + + if (siglen != 114uL) return CRYPT_INVALID_ARG; + if (public_key->pka != LTC_PKA_ED448) return CRYPT_PK_INVALID_TYPE; + + mlen = msglen + siglen; + if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW; + + m = XMALLOC((unsigned long)mlen); + if (m == NULL) return CRYPT_MEM; + + XMEMCPY(m, sig, siglen); + XMEMCPY(m + siglen, msg, msglen); + + err = ec448_verify_internal(stat, + m, &mlen, + m, mlen, + ctx, ctxlen, + public_key->pub); + +#ifdef LTC_CLEAN_STACK + zeromem(m, msglen + siglen); +#endif + XFREE(m); + + return err; +} + +/** + Verify an Ed448ctx signature. + @param msg [in] The data to be verified + @param msglen [in] The size of the data to be verified + @param sig [in] The signature to be verified + @param siglen [in] The size of the signature to be verified + @param ctx [in] The context + @param ctxlen [in] The size of the context + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param public_key [in] The public Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448ctx_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key) +{ + int err; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + LTC_ARGCHK(ctx != NULL); + + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen)) != CRYPT_OK) + return err; + + return s_ed448_verify(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key); +} + +/** + Verify an Ed448ph signature. + @param msg [in] The data to be verified + @param msglen [in] The size of the data to be verified + @param sig [in] The signature to be verified + @param siglen [in] The size of the signature to be verified + @param ctx [in] The context + @param ctxlen [in] The size of the context + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param public_key [in] The public Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448ph_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + const unsigned char *ctx, unsigned long ctxlen, + int *stat, + const curve448_key *public_key) +{ + int err; + unsigned char msg_hash[64]; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK) + return err; + + if ((err = ec448_prehash_internal(msg_hash, msg, msglen)) != CRYPT_OK) + return err; + + return s_ed448_verify(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key); +} + +/** + Verify an Ed448 signature (pure mode). + @param msg [in] The data to be verified + @param msglen [in] The size of the data to be verified + @param sig [in] The signature to be verified + @param siglen [in] The size of the signature to be verified + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param public_key [in] The public Ed448 key in the pair + @return CRYPT_OK if successful +*/ +int ed448_verify(const unsigned char *msg, unsigned long msglen, + const unsigned char *sig, unsigned long siglen, + int *stat, + const curve448_key *public_key) +{ + int err; + unsigned char ctx_prefix[266]; + unsigned long ctx_prefix_size = sizeof(ctx_prefix); + + /* Pure Ed448 still uses DOM4 with flag=0 and empty context */ + if ((err = ec448_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, NULL, 0)) != CRYPT_OK) + return err; + + return s_ed448_verify(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key); +} + +#endif diff --git a/src/pk/pka_key.c b/src/pk/pka_key.c index d88ee3d30..c682cfcbf 100644 --- a/src/pk/pka_key.c +++ b/src/pk/pka_key.c @@ -30,6 +30,7 @@ void pka_key_free(ltc_pka_key *key) #endif break; case LTC_PKA_RSA: + case LTC_PKA_RSA_PSS: #if defined(LTC_MRSA) rsa_free(&key->u.rsa); #endif diff --git a/src/pk/pkcs1/pkcs_1_mgf1.c b/src/pk/pkcs1/pkcs_1_mgf1.c index 7a68e72cd..dfb122cef 100644 --- a/src/pk/pkcs1/pkcs_1_mgf1.c +++ b/src/pk/pkcs1/pkcs_1_mgf1.c @@ -18,9 +18,9 @@ @param masklen The length of the mask desired @return CRYPT_OK if successful */ -int pkcs_1_mgf1(int hash_idx, - const unsigned char *seed, unsigned long seedlen, - unsigned char *mask, unsigned long masklen) +int ltc_pkcs_1_mgf1(int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen) { unsigned long hLen, x; ulong32 counter; diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 14519c1ea..4a2c405fd 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -8,53 +8,41 @@ */ #ifdef LTC_PKCS_1 - /** PKCS #1 v2.00 OAEP decode @param msg The encoded data to decode @param msglen The length of the encoded data (octets) - @param lparam The session or system data (can be NULL) - @param lparamlen The length of the lparam + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus - @param mgf_hash The hash algorithm used for the MGF - @param lparam_hash The hash algorithm used when hashing the lparam (can be -1) @param out [out] Destination of decoding @param outlen [in/out] The max size and resulting size of the decoding @param res [out] Result of decoding, 1==valid, 0==invalid @return CRYPT_OK if successful */ -int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, - int mgf_hash, int lparam_hash, - unsigned char *out, unsigned long *outlen, - int *res) +int ltc_pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen, + int *res) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; - int err, ret, lparam_hash_used; + int err, ret; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msg != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(res != NULL); + if ((err = rsa_key_valid_op(LTC_PKCS1_DECRYPT, &op_checked)) != CRYPT_OK) { + return err; + } + /* default to invalid packet */ *res = 0; - /* test valid hash */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } - if (lparam_hash != -1) { - if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) { - return err; - } - lparam_hash_used = lparam_hash; - } else { - lparam_hash_used = mgf_hash; - } - hLen = hash_descriptor[lparam_hash_used].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test hash/message size */ @@ -104,7 +92,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, x += modulus_len - hLen - 1; /* compute MGF1 of maskedDB (hLen) */ - if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } @@ -114,7 +102,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, } /* compute MGF1 of seed (k - hlen - 1) */ - if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -127,13 +115,13 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, /* compute lhash and store it in seed [reuse temps!] */ x = modulus_len; - if (lparam != NULL) { - if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, seed, &x)) != CRYPT_OK) { + if (op_checked.params->u.crypt.lparam != NULL) { + if ((err = hash_memory(op_checked.hash_alg, op_checked.params->u.crypt.lparam, op_checked.params->u.crypt.lparamlen, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use DB with zero length */ - if ((err = hash_memory(lparam_hash_used, DB, 0, seed, &x)) != CRYPT_OK) { + if ((err = hash_memory(op_checked.hash_alg, DB, 0, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } diff --git a/src/pk/pkcs1/pkcs_1_oaep_encode.c b/src/pk/pkcs1/pkcs_1_oaep_encode.c index 45aa5ce5c..7e323bd46 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -8,55 +8,35 @@ */ #ifdef LTC_PKCS_1 - /** PKCS #1 v2.00 OAEP encode @param msg The data to encode @param msglen The length of the data to encode (octets) - @param lparam A session or system parameter (can be NULL) - @param lparamlen The length of the lparam data + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus - @param prng An active PRNG state - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired @param out [out] The destination for the encoded data @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ -int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, - const unsigned char *lparam, unsigned long lparamlen, - unsigned long modulus_bitlen, prng_state *prng, - int prng_idx, - int mgf_hash, int lparam_hash, - unsigned char *out, unsigned long *outlen) +int ltc_pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; - int err, lparam_hash_used; + int err; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK((msglen == 0) || (msg != NULL)); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - /* test valid hash */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } - if (lparam_hash != -1) { - if ((err = hash_is_valid(lparam_hash)) != CRYPT_OK) { - return err; - } - lparam_hash_used = lparam_hash; - } else { - lparam_hash_used = mgf_hash; - } - - /* valid prng */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_ENCRYPT, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[lparam_hash_used].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test message size */ @@ -84,13 +64,13 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* get lhash */ /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ x = modulus_len; - if (lparam != NULL) { - if ((err = hash_memory(lparam_hash_used, lparam, lparamlen, DB, &x)) != CRYPT_OK) { + if (op_checked.params->u.crypt.lparam != NULL) { + if ((err = hash_memory(op_checked.hash_alg, op_checked.params->u.crypt.lparam, op_checked.params->u.crypt.lparamlen, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use `out` with zero length */ - if ((err = hash_memory(lparam_hash_used, out, 0, DB, &x)) != CRYPT_OK) { + if ((err = hash_memory(op_checked.hash_alg, out, 0, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } @@ -111,13 +91,13 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, } /* now choose a random seed */ - if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { + if (prng_descriptor[op_checked.params->wprng].read(seed, hLen, op_checked.params->prng) != hLen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } /* compute MGF1 of seed (k - hlen - 1) */ - if ((err = pkcs_1_mgf1(mgf_hash, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -127,7 +107,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, } /* compute MGF1 of maskedDB (hLen) */ - if ((err = pkcs_1_mgf1(mgf_hash, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/pk/pkcs1/pkcs_1_pss_decode.c index fad401d1b..3fae71bbc 100644 --- a/src/pk/pkcs1/pkcs_1_pss_decode.c +++ b/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -10,39 +10,41 @@ #ifdef LTC_PKCS_1 /** - PKCS #1 v2.00 PSS decode + PKCS #1 v2.00 Signature Verification @param msghash The hash to verify @param msghashlen The length of the hash (octets) @param sig The signature data (encoded data) @param siglen The length of the signature data (octets) - @param saltlen The length of the salt used (octets) - @param hash_idx The index of the hash desired + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus @param res [out] The result of the comparison, 1==valid, 0==invalid @return CRYPT_OK if successful (even if the comparison failed) */ -int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - unsigned long saltlen, int hash_idx, - unsigned long modulus_bitlen, int *res) +int ltc_pkcs_1_pss_decode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, int *res) { unsigned char *DB, *mask, *salt, *hash; - unsigned long x, y, hLen, modulus_len; + unsigned long x, y, hLen, modulus_len, saltlen; int err; hash_state md; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(params != NULL); LTC_ARGCHK(res != NULL); /* default to invalid */ *res = 0; - /* ensure hash is valid */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_VERIFY, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[hash_idx].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; + saltlen = params->params.saltlen; modulus_bitlen--; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); @@ -95,7 +97,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* generate mask of length modulus_len - hLen - 1 from hash */ - if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } @@ -124,20 +126,20 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ - if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(mask, 8); - if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, mask, 8)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, DB+x, saltlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].done(&md, mask)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_pss_encode.c b/src/pk/pkcs1/pkcs_1_pss_encode.c index 2a4e3728a..bf5c2992a 100644 --- a/src/pk/pkcs1/pkcs_1_pss_encode.c +++ b/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -13,39 +13,34 @@ PKCS #1 v2.00 Signature Encoding @param msghash The hash to encode @param msghashlen The length of the hash (octets) - @param saltlen The length of the salt desired (octets) - @param prng An active PRNG context - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired + @param params The PKCS#1 operation's parameters @param modulus_bitlen The bit length of the RSA modulus @param out [out] The destination of the encoding @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ -int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, - unsigned long saltlen, prng_state *prng, - int prng_idx, int hash_idx, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen) +int ltc_pkcs_1_pss_encode_mgf1(const unsigned char *msghash, unsigned long msghashlen, + ltc_rsa_op_parameters *params, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen) { unsigned char *DB, *mask, *salt, *hash; - unsigned long x, y, hLen, modulus_len; + unsigned long x, y, hLen, modulus_len, saltlen; int err; hash_state md; + ltc_rsa_op_checked op_checked = ltc_pkcs1_op_checked_init(params); LTC_ARGCHK(msghash != NULL); + LTC_ARGCHK(params != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - /* ensure hash and PRNG are valid */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { + if ((err = rsa_key_valid_op(LTC_PKCS1_SIGN, &op_checked)) != CRYPT_OK) { return err; } - hLen = hash_descriptor[hash_idx].hashsize; + hLen = hash_descriptor[op_checked.hash_alg].hashsize; + saltlen = params->params.saltlen; modulus_bitlen--; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); @@ -78,27 +73,27 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, /* generate random salt */ if (saltlen > 0) { - if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { + if (prng_descriptor[params->wprng].read(salt, saltlen, params->prng) != saltlen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } } /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ - if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(DB, 8); - if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, DB, 8)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].process(&md, salt, saltlen)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { + if ((err = hash_descriptor[op_checked.hash_alg].done(&md, hash)) != CRYPT_OK) { goto LBL_ERR; } @@ -111,7 +106,7 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, /* x += saltlen; */ /* generate mask of length modulus_len - hLen - 1 from hash */ - if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_mgf1(op_checked.mgf1_hash_alg, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/pk/pkcs1/pkcs_1_v1_5_decode.c b/src/pk/pkcs1/pkcs_1_v1_5_decode.c index e98806073..950749a62 100644 --- a/src/pk/pkcs1/pkcs_1_v1_5_decode.c +++ b/src/pk/pkcs1/pkcs_1_v1_5_decode.c @@ -21,13 +21,13 @@ * * @return CRYPT_OK if successful */ -int pkcs_1_v1_5_decode(const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - unsigned char *out, - unsigned long *outlen, - int *is_valid) +int ltc_pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid) { unsigned long modulus_len, ps_len, i; int result; diff --git a/src/pk/pkcs1/pkcs_1_v1_5_encode.c b/src/pk/pkcs1/pkcs_1_v1_5_encode.c index a21df4bfe..60ddf8abf 100644 --- a/src/pk/pkcs1/pkcs_1_v1_5_encode.c +++ b/src/pk/pkcs1/pkcs_1_v1_5_encode.c @@ -22,14 +22,14 @@ * * \return CRYPT_OK if successful */ -int pkcs_1_v1_5_encode(const unsigned char *msg, - unsigned long msglen, - int block_type, - unsigned long modulus_bitlen, - prng_state *prng, - int prng_idx, - unsigned char *out, - unsigned long *outlen) +int ltc_pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen) { unsigned long modulus_len, ps_len, i; unsigned char *ps; diff --git a/src/pk/rsa/rsa_decrypt_key.c b/src/pk/rsa/rsa_decrypt_key.c index d8e7a546f..4d9ed518c 100644 --- a/src/pk/rsa/rsa_decrypt_key.c +++ b/src/pk/rsa/rsa_decrypt_key.c @@ -8,53 +8,38 @@ */ #ifdef LTC_MRSA - /** - PKCS #1 decrypt then v1.5 or OAEP depad + Decrypt then (PKCS #1 v2.0) OAEP or (PKCS #1 v1.5) EME depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) - @param lparam The system "lparam" value - @param lparamlen The length of the lparam value (octets) - @param mgf_hash The hash algorithm used for the MGF - @param lparam_hash The hash algorithm used when hashing the lparam (can be -1) - @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) + @param params The RSA operation's parameters @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ -int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, +int rsa_decrypt_key_v2(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - int mgf_hash, int lparam_hash, - int padding, + ltc_rsa_op_parameters *params, int *stat, const rsa_key *key) { - unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; + unsigned long modulus_bitlen, modulus_bytelen, x; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_PKCS_1_OAEP) { - /* valid hash ? */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_DECRYPT, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -72,20 +57,19 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen return CRYPT_MEM; } - /* rsa decode the packet */ + /* rsa exptmod the packet */ x = inlen; if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } - if (padding == LTC_PKCS_1_OAEP) { - /* now OAEP decode the packet */ - err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, mgf_hash, - lparam_hash, out, outlen, stat); + if (params->padding == LTC_PKCS_1_OAEP) { + /* now OAEP depad the packet */ + err = ltc_pkcs_1_oaep_decode(tmp, x, params, modulus_bitlen, out, outlen, stat); } else { /* now PKCS #1 v1.5 depad the packet */ - err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); + err = ltc_pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); } XFREE(tmp); diff --git a/src/pk/rsa/rsa_encrypt_key.c b/src/pk/rsa/rsa_encrypt_key.c index 17dd1af5d..b8797a169 100644 --- a/src/pk/rsa/rsa_encrypt_key.c +++ b/src/pk/rsa/rsa_encrypt_key.c @@ -8,54 +8,31 @@ */ #ifdef LTC_MRSA - /** - (PKCS #1 v2.0) OAEP pad then encrypt - @param in The plaintext - @param inlen The length of the plaintext (octets) - @param out [out] The ciphertext - @param outlen [in/out] The max size and resulting size of the ciphertext - @param lparam The system "lparam" for the encryption - @param lparamlen The length of lparam (octets) - @param prng An active PRNG - @param prng_idx The index of the desired prng - @param hash_idx The index of the desired hash - @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5) - @param key The RSA key to encrypt to - @return CRYPT_OK if successful + (PKCS #1 v2.0) OAEP or (PKCS #1 v1.5) EME pad then encrypt + @param in The plaintext + @param inlen The length of the plaintext (octets) + @param out [out] The ciphertext + @param outlen [in/out] The max size and resulting size of the ciphertext + @param params The RSA operation's parameters + @param key The RSA key to encrypt to + @return CRYPT_OK if successful */ -int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - prng_state *prng, int prng_idx, - int mgf_hash, int lparam_hash, - int padding, - const rsa_key *key) +int rsa_encrypt_key_v2(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ltc_rsa_op_parameters *params, + const rsa_key *key) { - unsigned long modulus_bitlen, modulus_bytelen, x; int err; + unsigned long modulus_bitlen, modulus_bytelen, x; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK((inlen == 0) || (in != NULL)); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } - /* valid prng? */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { - return err; - } - - if (padding == LTC_PKCS_1_OAEP) { - /* valid hash? */ - if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_ENCRYPT, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -68,20 +45,18 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, return CRYPT_BUFFER_OVERFLOW; } - if (padding == LTC_PKCS_1_OAEP) { + if (params->padding == LTC_PKCS_1_OAEP) { /* OAEP pad the key */ x = *outlen; - if ((err = pkcs_1_oaep_encode(in, inlen, lparam, - lparamlen, modulus_bitlen, prng, prng_idx, mgf_hash, - lparam_hash, out, &x)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_oaep_encode(in, inlen, params, modulus_bitlen, out, &x)) != CRYPT_OK) { return err; } } else { /* PKCS #1 v1.5 pad the key */ x = *outlen; - if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME, - modulus_bitlen, prng, prng_idx, - out, &x)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME, + modulus_bitlen, params->prng, params->wprng, + out, &x)) != CRYPT_OK) { return err; } } diff --git a/src/pk/rsa/rsa_import.c b/src/pk/rsa/rsa_import.c index 1240a77e7..bc201ad97 100644 --- a/src/pk/rsa/rsa_import.c +++ b/src/pk/rsa/rsa_import.c @@ -9,6 +9,18 @@ #ifdef LTC_MRSA +#ifndef S_RSA_DECODE +#define S_RSA_DECODE +static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + return der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, key->N, + LTC_ASN1_INTEGER, 1UL, key->e, + LTC_ASN1_EOL, 0UL, NULL); +} +#endif + /** Import an RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only] @@ -33,10 +45,7 @@ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) /* the version would fit into an LTC_ASN1_SHORT_INTEGER * so we try to decode as a public key */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) { + if ((err = s_rsa_decode(in, inlen, key)) == CRYPT_OK) { key->type = PK_PUBLIC; } goto LBL_OUT; @@ -85,57 +94,25 @@ int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key) int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; - unsigned char *tmpbuf=NULL; - unsigned long tmpbuf_len, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); + /* SubjectPublicKeyInfo or X.509 certificate format */ + if (rsa_import_x509(in, inlen, key) == CRYPT_OK) { + return CRYPT_OK; + } + /* init key */ if ((err = rsa_init(key)) != CRYPT_OK) { return err; } - - /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf_len = inlen; - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_ERR; - } - - len = 0; - err = x509_decode_subject_public_key_info(in, inlen, - LTC_OID_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, &len); - - if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ - - /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, - LTC_ASN1_INTEGER, 1UL, key->N, - LTC_ASN1_INTEGER, 1UL, key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - key->type = PK_PUBLIC; - err = CRYPT_OK; - goto LBL_FREE; + /* Try to match against PKCS #1 standards */ + if ((err = rsa_import_pkcs1(in, inlen, key)) != CRYPT_OK) { + rsa_free(key); } - /* not SSL public key, try to match against PKCS #1 standards */ - if ((err = rsa_import_pkcs1(in, inlen, key)) == CRYPT_OK) { - goto LBL_FREE; - } - -LBL_ERR: - rsa_free(key); - -LBL_FREE: - if (tmpbuf != NULL) { - XFREE(tmpbuf); - } return err; } diff --git a/src/pk/rsa/rsa_import_x509.c b/src/pk/rsa/rsa_import_x509.c index 4d157ead4..82d4efcd1 100644 --- a/src/pk/rsa/rsa_import_x509.c +++ b/src/pk/rsa/rsa_import_x509.c @@ -9,6 +9,8 @@ #ifdef LTC_MRSA +#ifndef S_RSA_DECODE +#define S_RSA_DECODE static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *key) { /* now it should be SEQUENCE { INTEGER, INTEGER } */ @@ -17,6 +19,208 @@ static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *k LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_EOL, 0UL, NULL); } +#endif + +typedef struct rsa_pss_parameters_data { + ltc_asn1_list params[4], inner[4], hash_alg[2], mgf[2], mgf_hash_alg[2]; + unsigned long hash_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long mgf_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long mgf1_hash_alg_oid[LTC_DER_OID_DEFAULT_NODES]; + unsigned long salt_length, trailer_field; +} rsa_pss_parameters_data; + +static LTC_INLINE void s_rsa_pss_parameters_data_setup(rsa_pss_parameters_data *d) +{ + unsigned long n; + /* RSASSA-PSS + * + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] TrailerField DEFAULT trailerFieldBC + * } + */ + + /* HashAlgorithm ::= AlgorithmIdentifier { + * {OAEP-PSSDigestAlgorithms} + * } + */ + LTC_SET_ASN1(d->hash_alg, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->hash_alg_oid, LTC_ARRAY_SIZE(d->hash_alg_oid)); + LTC_SET_ASN1(d->hash_alg, 1, LTC_ASN1_NULL, NULL, 0); + d->hash_alg[1].optional = 1; + + /* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} } */ + LTC_SET_ASN1(d->mgf_hash_alg, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->mgf1_hash_alg_oid, LTC_ARRAY_SIZE(d->mgf1_hash_alg_oid)); + LTC_SET_ASN1(d->mgf_hash_alg, 1, LTC_ASN1_NULL, NULL, 0); + d->mgf_hash_alg[1].optional = 1; + + /* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= { + * { OID id-mgf1 PARAMETERS HashAlgorithm }, + * ... -- Allows for future expansion -- + * } + */ + LTC_SET_ASN1(d->mgf, 0, LTC_ASN1_OBJECT_IDENTIFIER, d->mgf_alg_oid, LTC_ARRAY_SIZE(d->mgf_alg_oid)); + LTC_SET_ASN1(d->mgf, 1, LTC_ASN1_SEQUENCE, d->mgf_hash_alg, LTC_ARRAY_SIZE(d->mgf_hash_alg)); + + LTC_SET_ASN1(d->inner, 0, LTC_ASN1_SEQUENCE, d->hash_alg, LTC_ARRAY_SIZE(d->hash_alg)); + LTC_SET_ASN1(d->inner, 1, LTC_ASN1_SEQUENCE, d->mgf, LTC_ARRAY_SIZE(d->mgf)); + LTC_SET_ASN1(d->inner, 2, LTC_ASN1_SHORT_INTEGER, &d->salt_length, 1UL); + LTC_SET_ASN1(d->inner, 3, LTC_ASN1_SHORT_INTEGER, &d->trailer_field, 1UL); + + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 0, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, d->inner); /* context specific 0 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 1, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, d->inner + 1); /* context specific 1 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 2, d->inner + 2); /* context specific 2 */ + LTC_SET_ASN1_CUSTOM_CONSTRUCTED(d->params, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 3, d->inner + 3); /* context specific 3 */ + for (n = 0; n < 4; ++n) { + d->params[n].optional = 1; + } +} + +static int s_rsa_decode_parameters(const rsa_pss_parameters_data *d, ltc_rsa_parameters *rsa_params) +{ + unsigned long n; + enum ltc_oid_id oid_id; + int err, idx; + + rsa_params->saltlen = 20; + rsa_params->hash_idx = find_hash("sha1"); + rsa_params->mgf1_hash_idx = rsa_params->hash_idx; + + for (n = 0; n < 4; ++n) { + if (d->params[n].used == 0) + continue; + switch (n) { + case 0: + idx = find_hash_oid(d->hash_alg->data, d->hash_alg->size); + if (idx == -1) { + return CRYPT_INVALID_HASH; + } + rsa_params->hash_idx = idx; + break; + case 1: + if ((err = pk_get_oid_from_asn1(&d->mgf[0], &oid_id)) != CRYPT_OK) { + return err; + } + if (oid_id != LTC_OID_RSA_MGF1) { + return CRYPT_PK_ASN1_ERROR; + } + idx = find_hash_oid(d->mgf_hash_alg->data, d->mgf_hash_alg->size); + if (idx == -1) { + return CRYPT_INVALID_HASH; + } + rsa_params->mgf1_hash_idx = idx; + break; + case 2: + rsa_params->saltlen = d->salt_length; + break; + case 3: + if (d->trailer_field != 1) { + return CRYPT_PK_ASN1_ERROR; + } + break; + default: + return CRYPT_PK_ASN1_ERROR; + } + } + + return CRYPT_OK; +} + +int rsa_decode_parameters(const ltc_asn1_list *parameters, rsa_key *key) +{ + int err; + rsa_pss_parameters_data d; + + s_rsa_pss_parameters_data_setup(&d); + + if ((err = der_decode_sequence(parameters->data, parameters->size, d.params, 4)) != CRYPT_OK) { + return err; + } + + if ((err = s_rsa_decode_parameters(&d, &key->params)) != CRYPT_OK) { + return err; + } + key->pss_oaep = 1; + return CRYPT_OK; +} + +static LTC_INLINE int s_rsa_1_5_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + return x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA, + LTC_ASN1_NULL, NULL, NULL, + (public_key_decode_cb)s_rsa_decode, key); +} + +static LTC_INLINE int s_rsa_pss_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + rsa_pss_parameters_data d; + unsigned long n_params = LTC_ARRAY_SIZE(d.params); + + if (x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA_PSS, + LTC_ASN1_NULL, NULL, NULL, + (public_key_decode_cb)s_rsa_decode, key) == CRYPT_OK) { + return CRYPT_OK; + } + s_rsa_pss_parameters_data_setup(&d); + if ((err = x509_process_public_key_from_spki(in, inlen, + LTC_OID_RSA_PSS, + LTC_ASN1_SEQUENCE, d.params, &n_params, + (public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) { + return err; + } + if ((err = s_rsa_decode_parameters(&d, &key->params)) != CRYPT_OK) { + return err; + } + key->pss_oaep = 1; + return CRYPT_OK; +} + +static LTC_INLINE int s_rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + if (s_rsa_1_5_import_spki(in, inlen, key) == CRYPT_OK) { + return CRYPT_OK; + } + + if ((err = s_rsa_pss_import_spki(in, inlen, key)) == CRYPT_OK) { + return CRYPT_OK; + } + return err; +} + +/** + Import an RSA key from SubjectPublicKeyInfo + @param in The packet to import from + @param inlen It's length (octets) + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, upon error allocated memory is freed +*/ +int rsa_import_spki(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(ltc_mp.name != NULL); + + /* init key */ + if ((err = rsa_init(key)) != CRYPT_OK) { + return err; + } + + if ((err = s_rsa_import_spki(in, inlen, key)) == CRYPT_OK) { + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + rsa_free(key); + + return err; +} /** Import an RSA key from a X.509 certificate @@ -27,6 +231,8 @@ static int s_rsa_decode(const unsigned char *in, unsigned long inlen, rsa_key *k */ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) { + ltc_asn1_list *decoded_list; + const ltc_asn1_list *spki; int err; LTC_ARGCHK(in != NULL); @@ -38,16 +244,26 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) return err; } - if ((err = x509_decode_public_key_from_certificate(in, inlen, - LTC_OID_RSA, - LTC_ASN1_NULL, NULL, NULL, - (public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) { - rsa_free(key); - } else { + /* First try to decode as SubjectPublicKeyInfo */ + if (s_rsa_import_spki(in, inlen, key) == CRYPT_OK) { key->type = PK_PUBLIC; + return CRYPT_OK; } - return err; + /* Now try to extract the SubjectPublicKeyInfo from the Certificate */ + if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) { + rsa_free(key); + return err; + } + err = s_rsa_import_spki(spki->data, spki->size, key); + + der_free_sequence_flexi(decoded_list); + if (err != CRYPT_OK) { + rsa_free(key); + return err; + } + key->type = PK_PUBLIC; + return CRYPT_OK; } #endif /* LTC_MRSA */ diff --git a/src/pk/rsa/rsa_key.c b/src/pk/rsa/rsa_key.c index 7eb21b843..790157062 100644 --- a/src/pk/rsa/rsa_key.c +++ b/src/pk/rsa/rsa_key.c @@ -85,6 +85,8 @@ void rsa_shrink_key(rsa_key *key) int rsa_init(rsa_key *key) { LTC_ARGCHK(key != NULL); + key->pss_oaep = 0; + XMEMSET(&key->params, 0, sizeof(key->params)); return ltc_mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, LTC_NULL); } @@ -96,6 +98,146 @@ void rsa_free(rsa_key *key) { LTC_ARGCHKVD(key != NULL); ltc_mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, LTC_NULL); + key->pss_oaep = 0; + XMEMSET(&key->params, 0, sizeof(key->params)); +} + +static LTC_INLINE int s_rsa_key_valid_rsa_params(ltc_rsa_op_checked *check) +{ + const ltc_rsa_parameters *key_params; + /* This is called from PKCS#1 de-/encoder code, so we can't check the key */ + if (check->key == NULL) { + return CRYPT_OK; + } + key_params = &check->key->params; + /* Key has no PSS/OAEP constraints */ + if (!check->key->pss_oaep) { + return CRYPT_OK; + } + /* Key is constrained - operation must use matching PSS/OAEP params */ + if (check->params->padding != LTC_PKCS_1_PSS + && check->params->padding != LTC_PKCS_1_OAEP) { + return CRYPT_PK_TYPE_MISMATCH; + } + if (key_params->hash_idx != check->hash_alg) { + return CRYPT_INVALID_HASH; + } + if (key_params->mgf1_hash_idx != check->mgf1_hash_alg) { + return CRYPT_INVALID_HASH; + } + return CRYPT_OK; +} + +static LTC_INLINE int s_rsa_key_set_hash_algs(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if (hash_is_valid(params->params.hash_idx) != CRYPT_OK) { + return CRYPT_INVALID_HASH; + } + check->hash_alg = params->params.hash_idx; + if (params->params.mgf1_hash_idx == -1) { + if (params->padding != LTC_PKCS_1_PSS && params->padding != LTC_PKCS_1_OAEP) + return CRYPT_OK; + } else if (hash_is_valid(params->params.mgf1_hash_idx) == CRYPT_OK) { + check->mgf1_hash_alg = params->params.mgf1_hash_idx; + return CRYPT_OK; + } + return CRYPT_INVALID_HASH; +} + +static LTC_INLINE int s_rsa_key_valid_sign(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if ((params->padding != LTC_PKCS_1_V1_5) + && (params->padding != LTC_PKCS_1_PSS) + && (params->padding != LTC_PKCS_1_V1_5_NA1)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (params->padding != LTC_PKCS_1_V1_5_NA1) { + int err = s_rsa_key_set_hash_algs(check); + if (err != CRYPT_OK) { + return err; + } + } + if (params->padding == LTC_PKCS_1_V1_5) { + /* not all hashes have OIDs... so sad */ + if (check->hash_alg == -1 + || hash_descriptor[check->hash_alg].OIDlen == 0) { + return CRYPT_INVALID_ARG; + } + } + return s_rsa_key_valid_rsa_params(check); +} + +static LTC_INLINE int s_rsa_key_valid_crypt(ltc_rsa_op_checked *check) +{ + ltc_rsa_op_parameters *params = check->params; + if ((params->padding != LTC_PKCS_1_V1_5) && + (params->padding != LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (params->padding == LTC_PKCS_1_OAEP) { + int err = s_rsa_key_set_hash_algs(check); + if (err != CRYPT_OK) { + return err; + } + } + return s_rsa_key_valid_rsa_params(check); +} + +static LTC_INLINE int s_rsa_check_prng(ltc_rsa_op op, ltc_rsa_op_parameters *params) +{ + /* Only PSS signing needs a PRNG, v1.5 signing is deterministic. + * All encryption needs a PRNG (OAEP seed, v1.5 EME random padding). */ + if ((op & LTC_RSA_OP_SIGN) == LTC_RSA_OP_SIGN + && params->padding != LTC_PKCS_1_PSS) + return CRYPT_OK; + if (params->prng == NULL) + return CRYPT_INVALID_PRNG; + /* valid prng ? */ + return prng_is_valid(params->wprng); +} + +int rsa_key_valid_op(ltc_rsa_op op, ltc_rsa_op_checked *check) +{ + int err; + check->hash_alg = check->mgf1_hash_alg = -1; + LTC_ARGCHK(check->params != NULL); + if ((op & LTC_RSA_OP_PKCS1) != LTC_RSA_OP_PKCS1) { + /* PKCS#1 ops don't need an RSA key */ + LTC_ARGCHK(check->key != NULL); + } + if ((op & LTC_RSA_OP_SEND) == LTC_RSA_OP_SEND) { + if ((err = s_rsa_check_prng(op, check->params)) != CRYPT_OK) { + return err; + } + } + switch (op) { + case LTC_RSA_ENCRYPT: + case LTC_RSA_DECRYPT: + case LTC_PKCS1_ENCRYPT: + case LTC_PKCS1_DECRYPT: + return s_rsa_key_valid_crypt(check); + case LTC_RSA_SIGN: + case LTC_RSA_VERIFY: + case LTC_PKCS1_SIGN: + case LTC_PKCS1_VERIFY: + return s_rsa_key_valid_sign(check); + } + return CRYPT_ERROR; +} + +int rsa_params_equal(const ltc_rsa_parameters *a, const ltc_rsa_parameters *b) +{ + if (a->saltlen != b->saltlen) + return 0; + if (a->hash_idx != b->hash_idx) + return 0; + if (a->mgf1_hash_idx != b->mgf1_hash_idx) + return 0; + return 1; } #endif diff --git a/src/pk/rsa/rsa_sign_hash.c b/src/pk/rsa/rsa_sign_hash.c index bc5e0a89f..e6d3dddc8 100644 --- a/src/pk/rsa/rsa_sign_hash.c +++ b/src/pk/rsa/rsa_sign_hash.c @@ -8,72 +8,48 @@ */ #ifdef LTC_MRSA - /** PKCS #1 pad then sign - @param in The hash to sign - @param inlen The length of the hash to sign (octets) - @param out [out] The signature - @param outlen [in/out] The max size and resulting size of the signature - @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) - @param prng An active PRNG state - @param prng_idx The index of the PRNG desired - @param hash_idx The index of the hash desired - @param saltlen The length of the salt desired (octets) + @param hash The hash to sign + @param hashlen The length of the hash to sign (octets) + @param sig [out] The signature + @param siglen [in/out] The max size and resulting size of the signature + @param params The RSA operation parameters @param key The private RSA key to use @return CRYPT_OK if successful */ -int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - int padding, - prng_state *prng, int prng_idx, - int hash_idx, unsigned long saltlen, - const rsa_key *key) +int rsa_sign_hash_v2(const unsigned char *hash, unsigned long hashlen, + unsigned char *sig, unsigned long *siglen, + ltc_rsa_op_parameters *params, + const rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x, y; int err; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(siglen != NULL); LTC_ARGCHK(key != NULL); - /* valid padding? */ - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_PSS) && - (padding != LTC_PKCS_1_V1_5_NA1)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_PKCS_1_PSS) { - /* valid prng ? */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { - return err; - } - } - - if (padding != LTC_PKCS_1_V1_5_NA1) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_SIGN, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ modulus_bitlen = ltc_mp_count_bits((key->N)); - /* outlen must be at least the size of the modulus */ + /* siglen must be at least the size of the modulus */ modulus_bytelen = ltc_mp_unsigned_bin_size((key->N)); - if (modulus_bytelen > *outlen) { - *outlen = modulus_bytelen; + if (modulus_bytelen > *siglen) { + *siglen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } - if (padding == LTC_PKCS_1_PSS) { + if (params->padding == LTC_PKCS_1_PSS) { /* PSS pad the key */ - x = *outlen; - if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, - hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { + x = *siglen; + if ((err = ltc_pkcs_1_pss_encode_mgf1(hash, hashlen, params, modulus_bitlen, sig, &x)) != CRYPT_OK) { return err; } } else { @@ -81,12 +57,8 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *tmpin = NULL; const unsigned char *tmpin_ro; - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { ltc_asn1_list digestinfo[2], siginfo[2]; - /* not all hashes have OIDs... so sad */ - if (hash_descriptor[hash_idx].OIDlen == 0) { - return CRYPT_INVALID_ARG; - } /* construct the SEQUENCE SEQUENCE { @@ -96,10 +68,10 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, hash OCTET STRING } */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[op_checked.hash_alg].OID, hash_descriptor[op_checked.hash_alg].OIDlen); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); - LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, hash, hashlen); /* allocate memory for the encoding */ y = ltc_mp_unsigned_bin_size(key->N); @@ -115,14 +87,14 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, tmpin_ro = tmpin; } else { /* set the pointer and data-length to the input values */ - tmpin_ro = in; - y = inlen; + tmpin_ro = hash; + y = hashlen; } - x = *outlen; - err = pkcs_1_v1_5_encode(tmpin_ro, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, out, &x); + x = *siglen; + err = ltc_pkcs_1_v1_5_encode(tmpin_ro, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, sig, &x); - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { XFREE(tmpin); } @@ -132,7 +104,7 @@ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, } /* RSA encode it */ - return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); + return ltc_mp.rsa_me(sig, x, sig, siglen, PK_PRIVATE, key); } #endif /* LTC_MRSA */ diff --git a/src/pk/rsa/rsa_verify_hash.c b/src/pk/rsa/rsa_verify_hash.c index 9ca1641a6..39666d642 100644 --- a/src/pk/rsa/rsa_verify_hash.c +++ b/src/pk/rsa/rsa_verify_hash.c @@ -8,29 +8,27 @@ */ #ifdef LTC_MRSA - /** PKCS #1 de-sign then v1.5 or PSS depad @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) - @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) - @param hash_idx The index of the desired hash - @param saltlen The length of the salt used during signature + @param params The RSA operation parameters @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ -int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int padding, - int hash_idx, unsigned long saltlen, - int *stat, const rsa_key *key) +int rsa_verify_hash_v2(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ltc_rsa_op_parameters *params, + int *stat, + const rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmpbuf; + ltc_rsa_op_checked op_checked = ltc_rsa_op_checked_init(key, params); LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); @@ -40,19 +38,8 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle /* default to invalid */ *stat = 0; - /* valid padding? */ - - if ((padding != LTC_PKCS_1_V1_5) && - (padding != LTC_PKCS_1_PSS) && - (padding != LTC_PKCS_1_V1_5_NA1)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding != LTC_PKCS_1_V1_5_NA1) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } + if ((err = rsa_key_valid_op(LTC_RSA_VERIFY, &op_checked)) != CRYPT_OK) { + return err; } /* get modulus len in bits */ @@ -83,14 +70,14 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle return CRYPT_INVALID_PACKET; } - if (padding == LTC_PKCS_1_PSS) { + if (params->padding == LTC_PKCS_1_PSS) { /* PSS decode and verify it */ if(modulus_bitlen%8 == 1){ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf+1, x-1, saltlen, hash_idx, modulus_bitlen, stat); + err = ltc_pkcs_1_pss_decode_mgf1(hash, hashlen, tmpbuf+1, x-1, params, modulus_bitlen, stat); } else{ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); + err = ltc_pkcs_1_pss_decode_mgf1(hash, hashlen, tmpbuf, x, params, modulus_bitlen, stat); } } else { @@ -107,21 +94,15 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle goto bail_2; } - if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { + if ((err = ltc_pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { XFREE(out); goto bail_2; } - if (padding == LTC_PKCS_1_V1_5) { + if (params->padding == LTC_PKCS_1_V1_5) { unsigned long loid[16], reallen; ltc_asn1_list digestinfo[2], siginfo[2]; - /* not all hashes have OIDs... so sad */ - if (hash_descriptor[hash_idx].OIDlen == 0) { - err = CRYPT_INVALID_ARG; - goto bail_2; - } - /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ /* construct the SEQUENCE SEQUENCE { @@ -133,16 +114,13 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle */ LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, LTC_ARRAY_SIZE(loid)); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + digestinfo[1].optional = 1; LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); if (der_decode_sequence_strict(out, outlen, siginfo, 2) != CRYPT_OK) { - /* fallback to Legacy:missing NULL */ - LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1); - if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } + XFREE(out); + goto bail_2; } if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) { @@ -152,8 +130,8 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle /* test OID */ if ((reallen == outlen) && - (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && - (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && + (digestinfo[0].size == hash_descriptor[op_checked.hash_alg].OIDlen) && + (XMEMCMP(digestinfo[0].data, hash_descriptor[op_checked.hash_alg].OID, sizeof(unsigned long) * hash_descriptor[op_checked.hash_alg].OIDlen) == 0) && (siginfo[1].size == hashlen) && (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { *stat = 1; diff --git a/src/pk/x448/x448_export.c b/src/pk/x448/x448_export.c new file mode 100644 index 000000000..33d0b1749 --- /dev/null +++ b/src/pk/x448/x448_export.c @@ -0,0 +1,31 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_export.c + Export a X448 key to a binary packet +*/ + +#ifdef LTC_CURVE448 + +/** + Export a X448 key to a binary packet + @param out [out] The destination for the key + @param outlen [in/out] The max size and resulting size of the X448 key + @param which Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC) + @param key The key you wish to export + @return CRYPT_OK if successful +*/ +int x448_export( unsigned char *out, unsigned long *outlen, + int which, + const curve448_key *key) +{ + LTC_ARGCHK(key != NULL); + + if (key->pka != LTC_PKA_X448) return CRYPT_PK_INVALID_TYPE; + + return ec448_export(out, outlen, which, key); +} + +#endif diff --git a/src/pk/x448/x448_import.c b/src/pk/x448/x448_import.c new file mode 100644 index 000000000..ea6f757e8 --- /dev/null +++ b/src/pk/x448/x448_import.c @@ -0,0 +1,35 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_import.c + Import a X448 key from a SubjectPublicKeyInfo +*/ + +#ifdef LTC_CURVE448 + +/** + Import a X448 key + @param in The packet to read + @param inlen The length of the input packet + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int x448_import(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + int err; + unsigned long key_len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + key_len = 56uL; + if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_X448, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) { + key->type = PK_PUBLIC; + key->pka = LTC_PKA_X448; + } + return err; +} + +#endif diff --git a/src/pk/x448/x448_import_pkcs8.c b/src/pk/x448/x448_import_pkcs8.c new file mode 100644 index 000000000..c0512923a --- /dev/null +++ b/src/pk/x448/x448_import_pkcs8.c @@ -0,0 +1,33 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_import_pkcs8.c + Import a X448 key in PKCS#8 format +*/ + +#ifdef LTC_CURVE448 + +int x448_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, + curve448_key *key) +{ + return ec448_import_pkcs8_asn1(alg_id, priv_key, LTC_OID_X448, key); +} + +/** + Import a X448 private key in PKCS#8 format + @param in The packet to import from + @param inlen It's length (octets) + @param pw_ctx The password context when decrypting the private key + @param key [out] Destination for newly imported key + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int x448_import_pkcs8(const unsigned char *in, unsigned long inlen, + const password_ctx *pw_ctx, + curve448_key *key) +{ + return ec448_import_pkcs8(in, inlen, pw_ctx, LTC_OID_X448, key); +} + +#endif diff --git a/src/pk/x448/x448_import_raw.c b/src/pk/x448/x448_import_raw.c new file mode 100644 index 000000000..66ba3114b --- /dev/null +++ b/src/pk/x448/x448_import_raw.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_import_raw.c + Set the parameters of a X448 key +*/ + +#ifdef LTC_CURVE448 + +/** + Set the parameters of a X448 key + + @param in The key + @param inlen The length of the key + @param which Which type of key (PK_PRIVATE or PK_PUBLIC) + @param key [out] Destination of the key + @return CRYPT_OK if successful +*/ +int x448_import_raw(const unsigned char *in, unsigned long inlen, int which, curve448_key *key) +{ + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen == 56uL); + LTC_ARGCHK(key != NULL); + + if (which == PK_PRIVATE) { + XMEMCPY(key->priv, in, 56uL); + ec448_scalarmult_base_internal(key->pub, key->priv); + } else if (which == PK_PUBLIC) { + XMEMCPY(key->pub, in, 56uL); + } else { + return CRYPT_INVALID_ARG; + } + key->pka = LTC_PKA_X448; + key->type = which; + + return CRYPT_OK; +} + +#endif diff --git a/src/pk/x448/x448_import_x509.c b/src/pk/x448/x448_import_x509.c new file mode 100644 index 000000000..f6822908c --- /dev/null +++ b/src/pk/x448/x448_import_x509.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_import_x509.c + Import a X448 key from a X.509 certificate +*/ + +#ifdef LTC_CURVE448 + +static int s_x448_decode(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + if (inlen != 56uL) return CRYPT_PK_INVALID_SIZE; + XMEMCPY(key->pub, in, 56uL); + return CRYPT_OK; +} + +/** + Import a X448 public key from a X.509 certificate + @param in The DER encoded X.509 certificate + @param inlen The length of the certificate + @param key [out] Where to import the key to + @return CRYPT_OK if successful, on error all allocated memory is freed automatically +*/ +int x448_import_x509(const unsigned char *in, unsigned long inlen, curve448_key *key) +{ + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = x509_decode_public_key_from_certificate(in, inlen, + LTC_OID_X448, + LTC_ASN1_EOL, NULL, NULL, + (public_key_decode_cb)s_x448_decode, key)) != CRYPT_OK) { + return err; + } + key->type = PK_PUBLIC; + key->pka = LTC_PKA_X448; + + return err; +} + +#endif diff --git a/src/pk/x448/x448_make_key.c b/src/pk/x448/x448_make_key.c new file mode 100644 index 000000000..07b80ce1a --- /dev/null +++ b/src/pk/x448/x448_make_key.c @@ -0,0 +1,42 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_make_key.c + Create a X448 key +*/ + +#ifdef LTC_CURVE448 + +/** + Create a X448 key + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful +*/ +int x448_make_key(prng_state *prng, int wprng, curve448_key *key) +{ + int err; + + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(key != NULL); + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (prng_descriptor[wprng].read(key->priv, 56uL, prng) != 56uL) { + return CRYPT_ERROR_READPRNG; + } + + ec448_scalarmult_base_internal(key->pub, key->priv); + + key->type = PK_PRIVATE; + key->pka = LTC_PKA_X448; + + return err; +} + +#endif diff --git a/src/pk/x448/x448_shared_secret.c b/src/pk/x448/x448_shared_secret.c new file mode 100644 index 000000000..f53d3e0fe --- /dev/null +++ b/src/pk/x448/x448_shared_secret.c @@ -0,0 +1,43 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/** + @file x448_shared_secret.c + Create a X448 shared secret +*/ + +#ifdef LTC_CURVE448 + +/** + Create a X448 shared secret. + @param private_key The private X448 key in the pair + @param public_key The public X448 key in the pair + @param out [out] The destination of the shared data + @param outlen [in/out] The max size and resulting size of the shared data. + @return CRYPT_OK if successful +*/ +int x448_shared_secret(const curve448_key *private_key, + const curve448_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + LTC_ARGCHK(private_key != NULL); + LTC_ARGCHK(public_key != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (public_key->pka != LTC_PKA_X448) return CRYPT_PK_INVALID_TYPE; + if (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if (*outlen < 56uL) { + *outlen = 56uL; + return CRYPT_BUFFER_OVERFLOW; + } + + ec448_scalarmult_internal(out, private_key->priv, public_key->pub); + *outlen = 56uL; + + return CRYPT_OK; +} + +#endif diff --git a/src/stream/chacha/xchacha20_memory.c b/src/stream/chacha/xchacha20_memory.c new file mode 100644 index 000000000..3d4ccd18b --- /dev/null +++ b/src/stream/chacha/xchacha20_memory.c @@ -0,0 +1,34 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +#ifdef LTC_XCHACHA20 + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with XChaCha20 + @param key The key + @param keylen The key length + @param rounds The number of rounds + @param nonce The nonce + @param noncelen The nonce length, must be 24 (octets) + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int xchacha20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout) +{ + chacha_state st; + int err; + + err = xchacha20_setup(&st, key, keylen, nonce, noncelen, rounds); + if (err == CRYPT_OK) { + err = chacha_crypt(&st, datain, datalen, dataout); + } + chacha_done(&st); + return err; +} + +#endif /* LTC_XCHACHA20 */ diff --git a/src/stream/chacha/xchacha20_setup.c b/src/stream/chacha/xchacha20_setup.c new file mode 100644 index 000000000..c8d84329c --- /dev/null +++ b/src/stream/chacha/xchacha20_setup.c @@ -0,0 +1,144 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +/* The implementation is based on: + draft-irtf-cfrg-xchacha, "XChaCha: eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305" + RFC 8439, "ChaCha20 and Poly1305 for IETF Protocols" +*/ + +#ifdef LTC_XCHACHA20 + +#define QUARTERROUND(a,b,c,d) \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 7); + +/* ChaCha20 double-round without the final addition */ +static void s_hchacha20(ulong32 *x, int rounds) +{ + int i; + + for (i = rounds; i > 0; i -= 2) { + /* columnround */ + QUARTERROUND( 0, 4, 8,12) + QUARTERROUND( 1, 5, 9,13) + QUARTERROUND( 2, 6,10,14) + QUARTERROUND( 3, 7,11,15) + /* diagonalround */ + QUARTERROUND( 0, 5,10,15) + QUARTERROUND( 1, 6,11,12) + QUARTERROUND( 2, 7, 8,13) + QUARTERROUND( 3, 4, 9,14) + } +} + +#undef QUARTERROUND + +/** + HChaCha20: derive a 256-bit subkey from a 256-bit key and 128-bit input. + This is the ChaCha20 core (double-rounds) without the final addition step, + extracting output from state positions {0,1,2,3,12,13,14,15}. + @param out [out] The derived 32-byte subkey + @param outlen The length of the output buffer, must be 32 (octets) + @param key The secret key + @param keylen The length of the secret key, must be 32 (octets) + @param in The 16-byte input (nonce or constant) + @param inlen The length of the input, must be 16 (octets) + @param rounds Number of rounds (must be evenly divisible by 2, default is 20) + @return CRYPT_OK if successful +*/ +int xchacha20_hchacha20(unsigned char *out, unsigned long outlen, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + int rounds) +{ + const char * const constants = "expand 32-byte k"; + ulong32 x[16]; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen == 32); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(keylen == 32); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(inlen == 16); + if (rounds == 0) rounds = 20; + LTC_ARGCHK(rounds % 2 == 0); + + LOAD32L(x[ 0], constants + 0); + LOAD32L(x[ 1], constants + 4); + LOAD32L(x[ 2], constants + 8); + LOAD32L(x[ 3], constants + 12); + LOAD32L(x[ 4], key + 0); + LOAD32L(x[ 5], key + 4); + LOAD32L(x[ 6], key + 8); + LOAD32L(x[ 7], key + 12); + LOAD32L(x[ 8], key + 16); + LOAD32L(x[ 9], key + 20); + LOAD32L(x[10], key + 24); + LOAD32L(x[11], key + 28); + LOAD32L(x[12], in + 0); + LOAD32L(x[13], in + 4); + LOAD32L(x[14], in + 8); + LOAD32L(x[15], in + 12); + + s_hchacha20(x, rounds); + + STORE32L(x[ 0], out + 0); + STORE32L(x[ 1], out + 4); + STORE32L(x[ 2], out + 8); + STORE32L(x[ 3], out + 12); + STORE32L(x[12], out + 16); + STORE32L(x[13], out + 20); + STORE32L(x[14], out + 24); + STORE32L(x[15], out + 28); + + zeromem(x, sizeof(x)); + return CRYPT_OK; +} + +/** + Initialize an XChaCha20 context (HChaCha20 subkey derivation + ChaCha20 IETF setup) + @param st [out] The destination of the ChaCha20 state + @param key The secret key + @param keylen The length of the secret key, must be 32 (octets) + @param nonce The nonce + @param noncelen The length of the nonce, must be 24 (octets) + @param rounds Number of rounds (must be evenly divisible by 2, default is 20) + @return CRYPT_OK if successful +*/ +int xchacha20_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + int rounds) +{ + unsigned char subkey[32]; + unsigned char iv[12]; + int err; + + LTC_ARGCHK(st != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(noncelen == 24); + + /* HChaCha20: derive subkey from key and first 16 bytes of nonce */ + if ((err = xchacha20_hchacha20(subkey, 32, key, keylen, nonce, 16, rounds)) != CRYPT_OK) goto cleanup; + + /* set up ChaCha20 with the derived subkey */ + if ((err = chacha_setup(st, subkey, 32, rounds)) != CRYPT_OK) goto cleanup; + + /* build 12-byte IETF IV: 4 zero bytes + last 8 bytes of original nonce */ + XMEMSET(iv, 0, 4); + XMEMCPY(iv + 4, nonce + 16, 8); + if ((err = chacha_ivctr32(st, iv, 12, 0)) != CRYPT_OK) goto cleanup; + + /* mark as XChaCha20 */ + st->ivlen = 24; + +cleanup: + zeromem(subkey, sizeof(subkey)); + zeromem(iv, sizeof(iv)); + + return err; +} + +#endif /* LTC_XCHACHA20 */ diff --git a/src/stream/chacha/xchacha20_test.c b/src/stream/chacha/xchacha20_test.c new file mode 100644 index 000000000..4a280afdd --- /dev/null +++ b/src/stream/chacha/xchacha20_test.c @@ -0,0 +1,119 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_private.h" + +#ifdef LTC_XCHACHA20 + +int xchacha20_test(void) +{ +#ifndef LTC_TEST + return CRYPT_NOP; +#else + /* TV1: HChaCha20 known-answer test (draft-irtf-cfrg-xchacha, Section 2.2.1) */ + { + const unsigned char key[] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f + }; + const unsigned char in[] = { + 0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x31,0x41,0x59,0x27 + }; + const unsigned char expected_subkey[] = { + 0x82,0x41,0x3b,0x42,0x27,0xb2,0x7b,0xfe,0xd3,0x0e,0x42,0x50,0x8a,0x87,0x7d,0x73, + 0xa0,0xf9,0xe4,0xd5,0x8a,0x74,0xa8,0x53,0xc1,0x2e,0xc4,0x13,0x26,0xd3,0xec,0xdc + }; + unsigned char subkey[32]; + int err; + + if ((err = xchacha20_hchacha20(subkey, 32, key, 32, in, 16, 20)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(subkey, 32, expected_subkey, 32, "XCHACHA20-TV1 (HChaCha20)", 1)) return CRYPT_FAIL_TESTVECTOR; + } + + /* TV2: XChaCha20 encryption test (draft-irtf-cfrg-xchacha, Appendix A.3.2) */ + { + const unsigned char key[] = { + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f + }; + const unsigned char nonce[] = { + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x58 + }; + /* "The dhole (pronounced "dole") is also known as the Asiatic wild dog, ..." */ + const unsigned char plaintext[] = { + 0x54,0x68,0x65,0x20,0x64,0x68,0x6f,0x6c,0x65,0x20,0x28,0x70,0x72,0x6f,0x6e,0x6f, + 0x75,0x6e,0x63,0x65,0x64,0x20,0x22,0x64,0x6f,0x6c,0x65,0x22,0x29,0x20,0x69,0x73, + 0x20,0x61,0x6c,0x73,0x6f,0x20,0x6b,0x6e,0x6f,0x77,0x6e,0x20,0x61,0x73,0x20,0x74, + 0x68,0x65,0x20,0x41,0x73,0x69,0x61,0x74,0x69,0x63,0x20,0x77,0x69,0x6c,0x64,0x20, + 0x64,0x6f,0x67,0x2c,0x20,0x72,0x65,0x64,0x20,0x64,0x6f,0x67,0x2c,0x20,0x61,0x6e, + 0x64,0x20,0x77,0x68,0x69,0x73,0x74,0x6c,0x69,0x6e,0x67,0x20,0x64,0x6f,0x67,0x2e, + 0x20,0x49,0x74,0x20,0x69,0x73,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x74,0x68,0x65, + 0x20,0x73,0x69,0x7a,0x65,0x20,0x6f,0x66,0x20,0x61,0x20,0x47,0x65,0x72,0x6d,0x61, + 0x6e,0x20,0x73,0x68,0x65,0x70,0x68,0x65,0x72,0x64,0x20,0x62,0x75,0x74,0x20,0x6c, + 0x6f,0x6f,0x6b,0x73,0x20,0x6d,0x6f,0x72,0x65,0x20,0x6c,0x69,0x6b,0x65,0x20,0x61, + 0x20,0x6c,0x6f,0x6e,0x67,0x2d,0x6c,0x65,0x67,0x67,0x65,0x64,0x20,0x66,0x6f,0x78, + 0x2e,0x20,0x54,0x68,0x69,0x73,0x20,0x68,0x69,0x67,0x68,0x6c,0x79,0x20,0x65,0x6c, + 0x75,0x73,0x69,0x76,0x65,0x20,0x61,0x6e,0x64,0x20,0x73,0x6b,0x69,0x6c,0x6c,0x65, + 0x64,0x20,0x6a,0x75,0x6d,0x70,0x65,0x72,0x20,0x69,0x73,0x20,0x63,0x6c,0x61,0x73, + 0x73,0x69,0x66,0x69,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x77,0x6f,0x6c,0x76, + 0x65,0x73,0x2c,0x20,0x63,0x6f,0x79,0x6f,0x74,0x65,0x73,0x2c,0x20,0x6a,0x61,0x63, + 0x6b,0x61,0x6c,0x73,0x2c,0x20,0x61,0x6e,0x64,0x20,0x66,0x6f,0x78,0x65,0x73,0x20, + 0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x74,0x61,0x78,0x6f,0x6e,0x6f,0x6d,0x69,0x63, + 0x20,0x66,0x61,0x6d,0x69,0x6c,0x79,0x20,0x43,0x61,0x6e,0x69,0x64,0x61,0x65,0x2e + }; + const unsigned char expected_ct[] = { + 0x45,0x59,0xab,0xba,0x4e,0x48,0xc1,0x61,0x02,0xe8,0xbb,0x2c,0x05,0xe6,0x94,0x7f, + 0x50,0xa7,0x86,0xde,0x16,0x2f,0x9b,0x0b,0x7e,0x59,0x2a,0x9b,0x53,0xd0,0xd4,0xe9, + 0x8d,0x8d,0x64,0x10,0xd5,0x40,0xa1,0xa6,0x37,0x5b,0x26,0xd8,0x0d,0xac,0xe4,0xfa, + 0xb5,0x23,0x84,0xc7,0x31,0xac,0xbf,0x16,0xa5,0x92,0x3c,0x0c,0x48,0xd3,0x57,0x5d, + 0x4d,0x0d,0x2c,0x67,0x3b,0x66,0x6f,0xaa,0x73,0x10,0x61,0x27,0x77,0x01,0x09,0x3a, + 0x6b,0xf7,0xa1,0x58,0xa8,0x86,0x42,0x92,0xa4,0x1c,0x48,0xe3,0xa9,0xb4,0xc0,0xda, + 0xec,0xe0,0xf8,0xd9,0x8d,0x0d,0x7e,0x05,0xb3,0x7a,0x30,0x7b,0xbb,0x66,0x33,0x31, + 0x64,0xec,0x9e,0x1b,0x24,0xea,0x0d,0x6c,0x3f,0xfd,0xdc,0xec,0x4f,0x68,0xe7,0x44, + 0x30,0x56,0x19,0x3a,0x03,0xc8,0x10,0xe1,0x13,0x44,0xca,0x06,0xd8,0xed,0x8a,0x2b, + 0xfb,0x1e,0x8d,0x48,0xcf,0xa6,0xbc,0x0e,0xb4,0xe2,0x46,0x4b,0x74,0x81,0x42,0x40, + 0x7c,0x9f,0x43,0x1a,0xee,0x76,0x99,0x60,0xe1,0x5b,0xa8,0xb9,0x68,0x90,0x46,0x6e, + 0xf2,0x45,0x75,0x99,0x85,0x23,0x85,0xc6,0x61,0xf7,0x52,0xce,0x20,0xf9,0xda,0x0c, + 0x09,0xab,0x6b,0x19,0xdf,0x74,0xe7,0x6a,0x95,0x96,0x74,0x46,0xf8,0xd0,0xfd,0x41, + 0x5e,0x7b,0xee,0x2a,0x12,0xa1,0x14,0xc2,0x0e,0xb5,0x29,0x2a,0xe7,0xa3,0x49,0xae, + 0x57,0x78,0x20,0xd5,0x52,0x0a,0x1f,0x3f,0xb6,0x2a,0x17,0xce,0x6a,0x7e,0x68,0xfa, + 0x7c,0x79,0x11,0x1d,0x88,0x60,0x92,0x0b,0xc0,0x48,0xef,0x43,0xfe,0x84,0x48,0x6c, + 0xcb,0x87,0xc2,0x5f,0x0a,0xe0,0x45,0xf0,0xcc,0xe1,0xe7,0x98,0x9a,0x9a,0xa2,0x20, + 0xa2,0x8b,0xdd,0x48,0x27,0xe7,0x51,0xa2,0x4a,0x6d,0x5c,0x62,0xd7,0x90,0xa6,0x63, + 0x93,0xb9,0x31,0x11,0xc1,0xa5,0x5d,0xd7,0x42,0x1a,0x10,0x18,0x49,0x74,0xc7,0xc5 + }; + unsigned long ptlen = sizeof(plaintext); + unsigned char ciphertext[304]; + unsigned char msg2[304]; + chacha_state st; + int err; + + /* encrypt with incremental API */ + if ((err = xchacha20_setup(&st, key, 32, nonce, 24, 20)) != CRYPT_OK) return err; + if ((err = chacha_crypt(&st, plaintext, ptlen, ciphertext)) != CRYPT_OK) return err; + if ((err = chacha_done(&st)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(ciphertext, ptlen, expected_ct, ptlen, "XCHACHA20-TV2", 1)) return CRYPT_FAIL_TESTVECTOR; + + /* decrypt and verify round-trip */ + if ((err = xchacha20_setup(&st, key, 32, nonce, 24, 20)) != CRYPT_OK) return err; + if ((err = chacha_crypt(&st, ciphertext, ptlen, msg2)) != CRYPT_OK) return err; + if ((err = chacha_done(&st)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(msg2, ptlen, plaintext, ptlen, "XCHACHA20-TV3 (roundtrip)", 1)) + return CRYPT_FAIL_TESTVECTOR; + + /* round-trip with xchacha20_memory */ + if ((err = xchacha20_memory(key, 32, 20, nonce, 24, plaintext, ptlen, ciphertext)) != CRYPT_OK) return err; + if ((err = xchacha20_memory(key, 32, 20, nonce, 24, ciphertext, ptlen, msg2)) != CRYPT_OK) return err; + + if (ltc_compare_testvector(msg2, ptlen, plaintext, ptlen, "XCHACHA20-TV4 (memory roundtrip)", 1)) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + +#endif +} + +#endif /* LTC_XCHACHA20 */ diff --git a/tests/argon2_test.c b/tests/argon2_test.c new file mode 100644 index 000000000..5274f2722 --- /dev/null +++ b/tests/argon2_test.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include + +#ifdef LTC_ARGON2 + +/* RFC 9106 test vectors */ + +int argon2_test(void) +{ + static const unsigned char password[32] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 + }; + static const unsigned char salt[16] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 + }; + static const unsigned char secret[8] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 + }; + static const unsigned char ad[12] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04 + }; + + static const unsigned char expected_argon2d[32] = { + 0x51, 0x2b, 0x39, 0x1b, 0x6f, 0x11, 0x62, 0x97, + 0x53, 0x71, 0xd3, 0x09, 0x19, 0x73, 0x42, 0x94, + 0xf8, 0x68, 0xe3, 0xbe, 0x39, 0x84, 0xf3, 0xc1, + 0xa1, 0x3a, 0x4d, 0xb9, 0xfa, 0xbe, 0x4a, 0xcb + }; + static const unsigned char expected_argon2i[32] = { + 0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa, + 0x13, 0xf0, 0xd7, 0x7f, 0x24, 0x94, 0xbd, 0xa1, + 0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2, + 0x99, 0x52, 0xa4, 0xc4, 0x67, 0x2b, 0x6c, 0xe8 + }; + static const unsigned char expected_argon2id[32] = { + 0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c, + 0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b, 0x53, 0xc9, + 0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e, + 0xb5, 0x25, 0x20, 0xe9, 0x6b, 0x01, 0xe6, 0x59 + }; + + unsigned char tag[32]; + + const struct { + const char *name; + argon2_type type; + const unsigned char *expected; + unsigned long elen; + } argon_testcase[] = { + { "Argon2d", ARGON2_D, expected_argon2d, sizeof(expected_argon2d) }, + { "Argon2i", ARGON2_I, expected_argon2i, sizeof(expected_argon2i) }, + { "Argon2id", ARGON2_ID, expected_argon2id, sizeof(expected_argon2id) }, + }; + + size_t n; + + for (n = 0; n < LTC_ARRAY_SIZE(argon_testcase); ++n) { + DO(argon2_hash(password, sizeof(password), + salt, sizeof(salt), + secret, sizeof(secret), + ad, sizeof(ad), + 3, 32, 4, + argon_testcase[n].type, + tag, sizeof(tag))); + COMPARE_TESTVECTOR(tag, sizeof(tag), argon_testcase[n].expected, argon_testcase[n].elen, argon_testcase[n].name, n); + } + + return CRYPT_OK; +} + +#else + +int argon2_test(void) +{ + return CRYPT_NOP; +} + +#endif diff --git a/tests/cipher_hash_test.c b/tests/cipher_hash_test.c index 92e082307..ac1701874 100644 --- a/tests/cipher_hash_test.c +++ b/tests/cipher_hash_test.c @@ -32,6 +32,9 @@ int cipher_hash_test(void) #ifdef LTC_CHACHA DO(chacha_test()); #endif +#ifdef LTC_XCHACHA20 + DO(xchacha20_test()); +#endif #ifdef LTC_SALSA20 DO(salsa20_test()); #endif @@ -56,6 +59,27 @@ int cipher_hash_test(void) DOX(hash_descriptor[x].test(), hash_descriptor[x].name); } + /* explicit SHA-NI + portable implementations tests */ + if (shani_is_supported()) { +#if defined(LTC_SHA256) && defined(LTC_SHA256_X86) + DO(sha256_x86_test()); +#endif +#if defined(LTC_SHA224) && defined(LTC_SHA224_X86) + DO(sha224_x86_test()); +#endif +#if defined(LTC_SHA1) && defined(LTC_SHA1_X86) + DO(sha1_x86_test()); +#endif + } +#if defined(LTC_SHA256) + DO(sha256_c_test()); +#endif +#if defined(LTC_SHA224) + DO(sha224_c_test()); +#endif +#if defined(LTC_SHA1) + DO(sha1_c_test()); +#endif #ifdef LTC_SHA3 /* SHAKE128 + SHAKE256 tests are a bit special */ DOX(sha3_shake_test(), "sha3_shake"); diff --git a/tests/deprecated_test.c b/tests/deprecated_test.c index f2ed3638b..57215d4e3 100644 --- a/tests/deprecated_test.c +++ b/tests/deprecated_test.c @@ -1,5 +1,6 @@ /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ +#ifndef LTC_NO_DEPRECATED_APIS #define LTC_DEPRECATED(x) #include @@ -39,10 +40,53 @@ static void s_ecc_test(void) } #endif +#ifdef LTC_MRSA +extern const unsigned char ltc_rsa_private_test_key[]; +extern const unsigned long ltc_rsa_private_test_key_sz; +extern const unsigned char ltc_openssl_public_rsa[]; +extern const unsigned long ltc_openssl_public_rsa_sz; +static void s_rsa_test(void) +{ + rsa_key key, pubkey; + int stat; + const unsigned char tv[] = "test"; + unsigned char buf0[1024], buf1[1024]; + unsigned long buf0len, buf1len; + + /* We need an MPI provider for RSA */ + if (ltc_mp.name == NULL) return; + + DO(rsa_import(ltc_rsa_private_test_key, ltc_rsa_private_test_key_sz, &key)); + DO(rsa_import(ltc_openssl_public_rsa, ltc_openssl_public_rsa_sz, &pubkey)); + + buf0len = sizeof(buf0); + DO(rsa_sign_hash_ex(tv, 4, buf0, &buf0len, LTC_PKCS_1_PSS, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), 8, &key)); + buf1len = sizeof(buf1); + DO(rsa_verify_hash_ex(buf0, buf0len, tv, 4, LTC_PKCS_1_PSS, find_hash("sha1"), 8, &stat, &pubkey)); + ENSURE(stat == 1); + + buf0len = sizeof(buf0); + DO(rsa_encrypt_key_ex(tv, 4, buf0, &buf0len, NULL, 0, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), LTC_PKCS_1_OAEP, &pubkey)); + buf1len = sizeof(buf1); + DO(rsa_decrypt_key_ex(buf0, buf0len, buf1, &buf1len, NULL, 0, find_hash("sha1"), LTC_PKCS_1_OAEP, &stat, &key)); + ENSURE(stat == 1); + COMPARE_TESTVECTOR(buf1, buf1len, tv, 4, "s_rsa_test", 0); + + rsa_free(&pubkey); + rsa_free(&key); +} +#endif +#endif /* LTC_NO_DEPRECATED_APIS */ + int deprecated_test(void) { +#ifndef LTC_NO_DEPRECATED_APIS #ifdef LTC_MECC s_ecc_test(); #endif +#ifdef LTC_MRSA + s_rsa_test(); +#endif +#endif /* LTC_NO_DEPRECATED_APIS */ return 0; } diff --git a/tests/ecc_test.c b/tests/ecc_test.c index f2c5ee1bf..90293ed35 100644 --- a/tests/ecc_test.c +++ b/tests/ecc_test.c @@ -643,21 +643,21 @@ static int s_ecc_new_api(void) #ifdef LTC_ECC_SHAMIR if (strcmp(ltc_mp.name, "TomsFastMath") != 0) { /* XXX-FIXME: TFM does not support sqrtmod_prime */ - int found = 0, recid; + int found = 0; ecc_key reckey; /* test recovery */ - sig_opts.recid = &recid; + sig_opts.enable_recovery_id = 1; len = sizeof(buf); DO(ecc_sign_hash_v2(data16, privkey.dp.size, buf, &len, &sig_opts, &privkey)); DO(ecc_set_curve(dp, &reckey)); for (k = 0; k < 2*(1+privkey.dp.cofactor); k++) { - recid = k; + sig_opts.recovery_id = k; stat = ecc_recover_key(buf, len, data16, privkey.dp.size, &sig_opts, &reckey); if (stat != CRYPT_OK) continue; /* last two will almost always fail, only possible if x<(prime mod order) */ stat = ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey); if (stat == CRYPT_OK) found++; } - sig_opts.recid = NULL; + sig_opts.enable_recovery_id = 0; if (found != 1) return CRYPT_FAIL_TESTVECTOR; /* unique match */ ecc_free(&reckey); } @@ -995,7 +995,7 @@ static int s_ecc_rfc6979(void) } }, { - NULL + 0 } }; @@ -1971,7 +1971,7 @@ static int s_ecc_test_ethereum(void) static int s_ecc_test_recovery(void) { - int i, recid, stat; + int i, stat; const ltc_ecc_curve* dp; ecc_key key, privkey, pubkey, reckey; unsigned char buf[1000]; @@ -1998,7 +1998,7 @@ static int s_ecc_test_recovery(void) ltc_ecc_sig_opts sig_opts = { .prng = &yarrow_prng, .wprng = find_prng ("yarrow"), - .recid = &recid + .enable_recovery_id = 1, }; /* XXX-FIXME: TFM does not support sqrtmod_prime */ @@ -2011,14 +2011,14 @@ static int s_ecc_test_recovery(void) DO(ecc_set_key(eth_pubkey, sizeof(eth_pubkey), PK_PUBLIC, &pubkey)); DO(ecc_set_curve(dp, &reckey)); - recid = 0; + sig_opts.recovery_id = 0; sig_opts.type = LTC_ECCSIG_RFC7518; DO(ecc_recover_key(eth_sig, sizeof(eth_sig)-1, eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); ecc_free(&reckey); DO(ecc_set_curve(dp, &reckey)); - recid = -1; + sig_opts.recovery_id = -1; sig_opts.type = LTC_ECCSIG_ETH27; DO(ecc_recover_key(eth_sig, sizeof(eth_sig), eth_hash, sizeof(eth_hash), &sig_opts, &reckey)); DO(ecc_key_cmp(PK_PUBLIC, &pubkey, &reckey)); @@ -2055,7 +2055,7 @@ static int s_ecc_test_recovery(void) /* test signature */ len = sizeof(buf); - recid = 0; + sig_opts.recovery_id = 0; DO(ecc_sign_hash_v2(data16, 16, buf, &len, &sig_opts, &privkey)); /* test verification */ @@ -2098,5 +2098,9 @@ int ecc_test(void) #endif return CRYPT_OK; } - +#else +int ecc_test(void) +{ + return CRYPT_NOP; +} #endif diff --git a/tests/ed25519_test.c b/tests/ed25519_test.c index 45f871db9..ca1ebecd1 100644 --- a/tests/ed25519_test.c +++ b/tests/ed25519_test.c @@ -396,6 +396,43 @@ static int s_rfc_8032_7_3_test(void) return CRYPT_OK; } +static int s_signature_malleability_test(void) +{ + /* Wycheproof Ed25519 signature malleability test vectors. */ + static const struct { + int tc_id; + const char *sig; + } test_cases[] = { + { 63, "7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab067654bce3832c2d76f8f6f5dafc08d9339d4eef676573336a5c51eb6f946b31d" }, + { 64, "7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab05439412b5395d42f462c67008eba6ca839d4eef676573336a5c51eb6f946b32d" }, + { 65, "7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab02ee12ce5875bf9dff26556464bae2ad239d4eef676573336a5c51eb6f946b34d" }, + { 66, "7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0e2300459f1e742404cd934d2c595a6253ad4eef676573336a5c51eb6f946b38d" }, + }; + const char *public_key = "7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa"; + const char *message = "54657374"; + unsigned long n, mlen, plen, siglen; + unsigned char msg[32], pub[32], sig[64]; + curve25519_key key; + int ret; + const int should = 0; + + plen = sizeof(pub); + DO(base16_decode(public_key, XSTRLEN(public_key), pub, &plen)); + mlen = sizeof(msg); + DO(base16_decode(message, XSTRLEN(message), msg, &mlen)); + DO(ed25519_import_raw(pub, plen, PK_PUBLIC, &key)); + + for (n = 0; n < LTC_ARRAY_SIZE(test_cases); ++n) { + siglen = sizeof(sig); + DO(base16_decode(test_cases[n].sig, XSTRLEN(test_cases[n].sig), sig, &siglen)); + DO(ed25519_verify(msg, mlen, sig, siglen, &ret, &key)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed25519 malleability rejection", test_cases[n].tc_id); + } + + zeromem(&key, sizeof(key)); + return CRYPT_OK; +} + /** Test the ed25519 system @return CRYPT_OK if successful @@ -423,6 +460,9 @@ int ed25519_test(void) if ((ret = s_rfc_8032_7_3_test()) != CRYPT_OK) { return ret; } + if ((ret = s_signature_malleability_test()) != CRYPT_OK) { + return ret; + } return ret; } diff --git a/tests/ed448_test.c b/tests/ed448_test.c new file mode 100644 index 000000000..68ca17ad1 --- /dev/null +++ b/tests/ed448_test.c @@ -0,0 +1,439 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_test.h" + +#ifdef LTC_CURVE448 + +typedef struct { + const char *secret_key; + const char *public_key; + const char *message; + const char *signature; + const char *context; +} rfc_8032_t; + +static int s_ed448_keygen_sign_verify(void) +{ + curve448_key key, pubkey; + const unsigned char msg[] = "test message"; + unsigned char sig[114], pk_buf[57]; + unsigned long siglen, pklen; + int stat, prng_idx; + + prng_idx = find_prng("yarrow"); + + /* keygen */ + DO(ed448_make_key(&yarrow_prng, prng_idx, &key)); + ENSURE(key.type == PK_PRIVATE); + ENSURE(key.pka == LTC_PKA_ED448); + + /* sign */ + siglen = sizeof(sig); + DO(ed448_sign(msg, sizeof(msg), sig, &siglen, &key)); + ENSURE(siglen == 114); + + /* export/import public key */ + pklen = sizeof(pk_buf); + DO(ed448_export(pk_buf, &pklen, PK_PUBLIC, &key)); + DO(ed448_import_raw(pk_buf, pklen, PK_PUBLIC, &pubkey)); + + /* verify */ + stat = 0; + DO(ed448_verify(msg, sizeof(msg), sig, siglen, &stat, &pubkey)); + ENSURE(stat == 1); + + /* corrupted sig must fail */ + sig[0] ^= 1; + stat = 1; + DO(ed448_verify(msg, sizeof(msg), sig, siglen, &stat, &pubkey)); + ENSURE(stat == 0); + + /* sign with context */ + siglen = sizeof(sig); + DO(ed448ctx_sign(msg, sizeof(msg), sig, &siglen, + (const unsigned char *)"ctx", 3, &key)); + stat = 0; + DO(ed448ctx_verify(msg, sizeof(msg), sig, siglen, + (const unsigned char *)"ctx", 3, &stat, &pubkey)); + ENSURE(stat == 1); + + /* wrong context must fail */ + stat = 1; + DO(ed448ctx_verify(msg, sizeof(msg), sig, siglen, + (const unsigned char *)"bad", 3, &stat, &pubkey)); + ENSURE(stat == 0); + + return CRYPT_OK; +} + +/* RFC 8032 Section 5.2.6 - Ed448 (pure, no context) */ +static int s_rfc_8032_5_2_6_pure_test(void) +{ + const rfc_8032_t vectors[] = { + { + /* 1: empty message */ + "6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3" + "528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b", + "5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778" + "edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180", + "", + "533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f" + "2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a" + "9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4db" + "b61149f05a7363268c71d95808ff2e652600", + NULL + }, + { + /* 2: 1 byte message */ + "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463a" + "fbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e", + "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c086" + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480", + "03", + "26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f435" + "2541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cb" + "cee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0f" + "f3348ab21aa4adafd1d234441cf807c03a00", + NULL + }, + { + /* 4: 11 byte message */ + "cd23d24f714274e744343237b93290f511f6425f98e64459ff203e8985083ffd" + "f60500553abc0e05cd02184bdb89c4ccd67e187951267eb328", + "dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e3" + "65fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400", + "0c3e544074ec63b0265e0c", + "1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d3" + "89dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b05" + "1068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5" + "028961c9bf8ffd973fe5d5c206492b140e00", + NULL + }, + { + /* 5: 12 byte message */ + "258cdd4ada32ed9c9ff54e63756ae582fb8fab2ac721f2c8e676a72768513d93" + "9f63dddb55609133f29adf86ec9929dccb52c1c5fd2ff7e21b", + "3ba16da0c6f2cc1f30187740756f5e798d6bc5fc015d7c63cc9510ee3fd44adc" + "24d8e968b6e46e6f94d19b945361726bd75e149ef09817f580", + "64a65f3cdedcdd66811e2915", + "7eeeab7c4e50fb799b418ee5e3197ff6bf15d43a14c34389b59dd1a7b1b85b4a" + "e90438aca634bea45e3a2695f1270f07fdcdf7c62b8efeaf00b45c2c96ba457e" + "b1a8bf075a3db28e5c24f6b923ed4ad747c3c9e03c7079efb87cb110d3a99861" + "e72003cbae6d6b8b827e4e6c143064ff3c00", + NULL + }, + { + /* 6: 13 byte message */ + "7ef4e84544236752fbb56b8f31a23a10e42814f5f55ca037cdcc11c64c9a3b29" + "49c1bb60700314611732a6c2fea98eebc0266a11a93970100e", + "b3da079b0aa493a5772029f0467baebee5a8112d9d3a22532361da294f7bb381" + "5c5dc59e176b4d9f381ca0938e13c6c07b174be65dfa578e80", + "64a65f3cdedcdd66811e2915e7", + "6a12066f55331b6c22acd5d5bfc5d71228fbda80ae8dec26bdd306743c5027cb" + "4890810c162c027468675ecf645a83176c0d7323a2ccde2d80efe5a1268e8aca" + "1d6fbc194d3f77c44986eb4ab4177919ad8bec33eb47bbb5fc6e28196fd1caf5" + "6b4e7e0ba5519234d047155ac727a1053100", + NULL + }, + { + /* 7: 64 byte message */ + "d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bf" + "f21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01", + "df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a" + "39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00", + "bd0f6a3747cd561bdddf4640a332461a4a30a12a434cd0bf40d766d9c6d458e5" + "512204a30c17d1f50b5079631f64eb3112182da3005835461113718d1a5ef944", + "554bc2480860b49eab8532d2a533b7d578ef473eeb58c98bb2d0e1ce488a98b1" + "8dfde9b9b90775e67f47d4a1c3482058efc9f40d2ca033a0801b63d45b3b722e" + "f552bad3b4ccb667da350192b61c508cf7b6b5adadc2c8d9a446ef003fb05cba" + "5f30e88e36ec2703b349ca229c2670833900", + NULL + }, + { + /* 8: 256 byte message */ + "2ec5fe3c17045abdb136a5e6a913e32ab75ae68b53d2fc149b77e504132d3756" + "9b7e766ba74a19bd6162343a21c8590aa9cebca9014c636df5", + "79756f014dcfe2079f5dd9e718be4171e2ef2486a08f25186f6bff43a9936b9b" + "fe12402b08ae65798a3d81e22e9ec80e7690862ef3d4ed3a00", + "15777532b0bdd0d1389f636c5f6b9ba734c90af572877e2d272dd078aa1e567c" + "fa80e12928bb542330e8409f3174504107ecd5efac61ae7504dabe2a602ede89" + "e5cca6257a7c77e27a702b3ae39fc769fc54f2395ae6a1178cab4738e543072f" + "c1c177fe71e92e25bf03e4ecb72f47b64d0465aaea4c7fad372536c8ba516a60" + "39c3c2a39f0e4d832be432dfa9a706a6e5c7e19f397964ca4258002f7c0541b5" + "90316dbc5622b6b2a6fe7a4abffd96105eca76ea7b98816af0748c10df048ce0" + "12d901015a51f189f3888145c03650aa23ce894c3bd889e030d565071c59f409" + "a9981b51878fd6fc110624dcbcde0bf7a69ccce38fabdf86f3bef6044819de11", + "c650ddbb0601c19ca11439e1640dd931f43c518ea5bea70d3dcde5f4191fe53f" + "00cf966546b72bcc7d58be2b9badef28743954e3a44a23f880e8d4f1cfce2d7a" + "61452d26da05896f0a50da66a239a8a188b6d825b3305ad77b73fbac0836ecc6" + "0987fd08527c1a8e80d5823e65cafe2a3d00", + NULL + }, + { + /* 9: 1023 byte message */ + "872d093780f5d3730df7c212664b37b8a0f24f56810daa8382cd4fa3f77634ec" + "44dc54f1c2ed9bea86fafb7632d8be199ea165f5ad55dd9ce8", + "a81b2e8a70a5ac94ffdbcc9badfc3feb0801f258578bb114ad44ece1ec0e799d" + "a08effb81c5d685c0c56f64eecaef8cdf11cc38737838cf400", + "6ddf802e1aae4986935f7f981ba3f0351d6273c0a0c22c9c0e8339168e675412" + "a3debfaf435ed651558007db4384b650fcc07e3b586a27a4f7a00ac8a6fec2cd" + "86ae4bf1570c41e6a40c931db27b2faa15a8cedd52cff7362c4e6e23daec0fbc" + "3a79b6806e316efcc7b68119bf46bc76a26067a53f296dafdbdc11c77f7777e9" + "72660cf4b6a9b369a6665f02e0cc9b6edfad136b4fabe723d2813db3136cfde9" + "b6d044322fee2947952e031b73ab5c603349b307bdc27bc6cb8b8bbd7bd32321" + "9b8033a581b59eadebb09b3c4f3d2277d4f0343624acc817804728b25ab79717" + "2b4c5c21a22f9c7839d64300232eb66e53f31c723fa37fe387c7d3e50bdf9813" + "a30e5bb12cf4cd930c40cfb4e1fc622592a49588794494d56d24ea4b40c89fc0" + "596cc9ebb961c8cb10adde976a5d602b1c3f85b9b9a001ed3c6a4d3b1437f520" + "96cd1956d042a597d561a596ecd3d1735a8d570ea0ec27225a2c4aaff26306d1" + "526c1af3ca6d9cf5a2c98f47e1c46db9a33234cfd4d81f2c98538a09ebe76998" + "d0d8fd25997c7d255c6d66ece6fa56f11144950f027795e653008f4bd7ca2dee" + "85d8e90f3dc315130ce2a00375a318c7c3d97be2c8ce5b6db41a6254ff264fa6" + "155baee3b0773c0f497c573f19bb4f4240281f0b1f4f7be857a4e59d416c06b4" + "c50fa09e1810ddc6b1467baeac5a3668d11b6ecaa901440016f389f80acc4db9" + "77025e7f5924388c7e340a732e554440e76570f8dd71b7d640b3450d1fd5f041" + "0a18f9a3494f707c717b79b4bf75c98400b096b21653b5d217cf3565c9597456" + "f70703497a078763829bc01bb1cbc8fa04eadc9a6e3f6699587a9e75c94e5bab" + "0036e0b2e711392cff0047d0d6b05bd2a588bc109718954259f1d86678a579a3" + "120f19cfb2963f177aeb70f2d4844826262e51b80271272068ef5b3856fa8535" + "aa2a88b2d41f2a0e2fda7624c2850272ac4a2f561f8f2f7a318bfd5caf969614" + "9e4ac824ad3460538fdc25421beec2cc6818162d06bbed0c40a387192349db67" + "a118bada6cd5ab0140ee273204f628aad1c135f770279a651e24d8c14d75a605" + "9d76b96a6fd857def5e0b354b27ab937a5815d16b5fae407ff18222c6d1ed263" + "be68c95f32d908bd895cd76207ae726487567f9a67dad79abec316f683b17f2d" + "02bf07e0ac8b5bc6162cf94697b3c27cd1fea49b27f23ba2901871962506520c" + "392da8b6ad0d99f7013fbc06c2c17a569500c8a7696481c1cd33e9b14e40b82e" + "79a5f5db82571ba97bae3ad3e0479515bb0e2b0f3bfcd1fd33034efc6245eddd" + "7ee2086ddae2600d8ca73e214e8c2b0bdb2b047c6a464a562ed77b73d2d841c4" + "b34973551257713b753632efba348169abc90a68f42611a40126d7cb21b58695" + "568186f7e569d2ff0f9e745d0487dd2eb997cafc5abf9dd102e62ff66cba87", + "e301345a41a39a4d72fff8df69c98075a0cc082b802fc9b2b6bc503f926b65bd" + "df7f4c8f1cb49f6396afc8a70abe6d8aef0db478d4c6b2970076c6a0484fe76d" + "76b3a97625d79f1ce240e7c576750d295528286f719b413de9ada3e8eb78ed57" + "3603ce30d8bb761785dc30dbc320869e1a00", + NULL + } + }; + unsigned int n; + unsigned long mlen, slen, plen, siglen, buflen; + unsigned char msg[1024], sec[57], pub[57], sig[114], buf[114]; + curve448_key key, key2; + int ret; + const int should = 1; + + for (n = 0; n < sizeof(vectors)/sizeof(vectors[0]); ++n) { + slen = sizeof(sec); + DO(base16_decode(vectors[n].secret_key, XSTRLEN(vectors[n].secret_key), sec, &slen)); + plen = sizeof(pub); + DO(base16_decode(vectors[n].public_key, XSTRLEN(vectors[n].public_key), pub, &plen)); + if (XSTRLEN(vectors[n].message) > 0) { + mlen = sizeof(msg); + DO(base16_decode(vectors[n].message, XSTRLEN(vectors[n].message), msg, &mlen)); + } else { + mlen = 0; + } + siglen = sizeof(sig); + DO(base16_decode(vectors[n].signature, XSTRLEN(vectors[n].signature), sig, &siglen)); + + /* sign with private key and compare */ + DO(ed448_import_raw(sec, slen, PK_PRIVATE, &key)); + buflen = sizeof(buf); + DO(ed448_sign(msg, mlen, buf, &buflen, &key)); + COMPARE_TESTVECTOR(buf, buflen, sig, siglen, "Ed448 RFC8032 5.2.6 - sign", n); + + /* verify with private key */ + DO(ed448_verify(msg, mlen, sig, siglen, &ret, &key)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed448 RFC8032 5.2.6 - verify w/ privkey", n); + + /* verify with public key only */ + DO(ed448_import_raw(pub, plen, PK_PUBLIC, &key2)); + DO(ed448_verify(msg, mlen, sig, siglen, &ret, &key2)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed448 RFC8032 5.2.6 - verify w/ pubkey", n); + + zeromem(&key, sizeof(key)); + zeromem(&key2, sizeof(key2)); + } + return CRYPT_OK; +} + +/* RFC 8032 Section 5.2.6 - Ed448 with context (vector 3) */ +static int s_rfc_8032_5_2_6_ctx_test(void) +{ + const rfc_8032_t vectors[] = { + { + /* 3: 1 byte message, context "foo" */ + "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463a" + "fbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e", + "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c086" + "6aea01eb00742802b8438ea4cb82169c235160627b4c3a9480", + "03", + "d4f8f6131770dd46f40867d6fd5d5055de43541f8c5e35abbcd001b32a89f7d2" + "151f7647f11d8ca2ae279fb842d607217fce6e042f6815ea000c85741de5c8da" + "1144a6a1aba7f96de42505d7a7298524fda538fccbbb754f578c1cad10d54d0d" + "5428407e85dcbc98a49155c13764e66c3c00", + "666f6f" + } + }; + unsigned int n; + unsigned long mlen, slen, plen, siglen, buflen, ctxlen; + unsigned char msg[1024], sec[57], pub[57], sig[114], buf[114], ctx[64]; + curve448_key key, key2; + int ret; + const int should = 1; + + for (n = 0; n < sizeof(vectors)/sizeof(vectors[0]); ++n) { + slen = sizeof(sec); + DO(base16_decode(vectors[n].secret_key, XSTRLEN(vectors[n].secret_key), sec, &slen)); + plen = sizeof(pub); + DO(base16_decode(vectors[n].public_key, XSTRLEN(vectors[n].public_key), pub, &plen)); + mlen = sizeof(msg); + DO(base16_decode(vectors[n].message, XSTRLEN(vectors[n].message), msg, &mlen)); + siglen = sizeof(sig); + DO(base16_decode(vectors[n].signature, XSTRLEN(vectors[n].signature), sig, &siglen)); + ctxlen = sizeof(ctx); + DO(base16_decode(vectors[n].context, XSTRLEN(vectors[n].context), ctx, &ctxlen)); + + /* sign with context and compare */ + DO(ed448_import_raw(sec, slen, PK_PRIVATE, &key)); + buflen = sizeof(buf); + DO(ed448ctx_sign(msg, mlen, buf, &buflen, ctx, ctxlen, &key)); + COMPARE_TESTVECTOR(buf, buflen, sig, siglen, "Ed448ctx RFC8032 5.2.6 - sign", n); + + /* verify with private key */ + DO(ed448ctx_verify(msg, mlen, sig, siglen, ctx, ctxlen, &ret, &key)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed448ctx RFC8032 5.2.6 - verify w/ privkey", n); + + /* verify with public key only */ + DO(ed448_import_raw(pub, plen, PK_PUBLIC, &key2)); + DO(ed448ctx_verify(msg, mlen, sig, siglen, ctx, ctxlen, &ret, &key2)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed448ctx RFC8032 5.2.6 - verify w/ pubkey", n); + + zeromem(&key, sizeof(key)); + zeromem(&key2, sizeof(key2)); + } + return CRYPT_OK; +} + +/* RFC 8032 Section 5.2.6 - Ed448ph (prehash) */ +static int s_rfc_8032_5_2_6_ph_test(void) +{ + const rfc_8032_t vectors[] = { + { + /* Ed448ph without context */ + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42" + "ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49", + "259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9c52beb743" + "c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880", + "616263", + "822f6901f7480f3d5f562c592994d9693602875614483256505600bbc281ae38" + "1f54d6bce2ea911574932f52a4e6cadd78769375ec3ffd1b801a0d9b3f4030cd" + "433964b6457ea39476511214f97469b57dd32dbc560a9a94d00bff07620464a3" + "ad203df7dc7ce360c3cd3696d9d9fab90f00", + NULL + }, + { + /* Ed448ph with context "foo" */ + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42" + "ef7822e0d5104127dc05d6dbefde69e3ab2cec7c867c6e2c49", + "259b71c19f83ef77a7abd26524cbdb3161b590a48f7d17de3ee0ba9c52beb743" + "c09428a131d6b1b57303d90d8132c276d5ed3d5d01c0f53880", + "616263", + "c32299d46ec8ff02b54540982814dce9a05812f81962b649d528095916a2aa48" + "1065b1580423ef927ecf0af5888f90da0f6a9a85ad5dc3f280d91224ba9911a3" + "653d00e484e2ce232521481c8658df304bb7745a73514cdb9bf3e15784ab7128" + "4f8d0704a608c54a6b62d97beb511d132100", + "666f6f" + } + }; + unsigned int n; + unsigned long mlen, slen, plen, siglen, buflen, ctxlen; + unsigned char msg[1024], sec[57], pub[57], sig[114], buf[114], ctx[64]; + curve448_key key; + int ret; + const int should = 1; + + for (n = 0; n < sizeof(vectors)/sizeof(vectors[0]); ++n) { + slen = sizeof(sec); + DO(base16_decode(vectors[n].secret_key, XSTRLEN(vectors[n].secret_key), sec, &slen)); + plen = sizeof(pub); + DO(base16_decode(vectors[n].public_key, XSTRLEN(vectors[n].public_key), pub, &plen)); + mlen = sizeof(msg); + DO(base16_decode(vectors[n].message, XSTRLEN(vectors[n].message), msg, &mlen)); + siglen = sizeof(sig); + DO(base16_decode(vectors[n].signature, XSTRLEN(vectors[n].signature), sig, &siglen)); + + if (vectors[n].context != NULL) { + ctxlen = sizeof(ctx); + DO(base16_decode(vectors[n].context, XSTRLEN(vectors[n].context), ctx, &ctxlen)); + } else { + ctxlen = 0; + } + + DO(ed448_import_raw(sec, slen, PK_PRIVATE, &key)); + buflen = sizeof(buf); + DO(ed448ph_sign(msg, mlen, buf, &buflen, ctx, ctxlen, &key)); + COMPARE_TESTVECTOR(buf, buflen, sig, siglen, "Ed448ph RFC8032 5.2.6 - sign", n); + + DO(ed448ph_verify(msg, mlen, sig, siglen, ctx, ctxlen, &ret, &key)); + COMPARE_TESTVECTOR(&ret, sizeof(ret), &should, sizeof(should), "Ed448ph RFC8032 5.2.6 - verify", n); + + zeromem(&key, sizeof(key)); + } + return CRYPT_OK; +} + +/* Export/import round-trip for Ed448 (requires MPI for DER/PKCS8) */ +static int s_ed448_compat_test(void) +{ + curve448_key priv, pub, imported; + unsigned char buf[1024]; + unsigned long buflen; + int prng_idx = find_prng("yarrow"); + + XMEMSET(&priv, 0, sizeof(priv)); + XMEMSET(&pub, 0, sizeof(pub)); + XMEMSET(&imported, 0, sizeof(imported)); + + DO(ed448_make_key(&yarrow_prng, prng_idx, &priv)); + + /* private PKCS#8 export -> import */ + buflen = sizeof(buf); + DO(ed448_export(buf, &buflen, PK_PRIVATE | PK_STD, &priv)); + DO(ed448_import_pkcs8(buf, buflen, NULL, &imported)); + COMPARE_TESTVECTOR(&priv, sizeof(priv), &imported, sizeof(imported), "Ed448 priv pkcs8 round-trip", __LINE__); + XMEMSET(&imported, 0, sizeof(imported)); + + /* public raw export -> import */ + buflen = sizeof(buf); + DO(ed448_export(buf, &buflen, PK_PUBLIC, &priv)); + DO(ed448_import_raw(buf, buflen, PK_PUBLIC, &pub)); + + /* public DER export -> import */ + buflen = sizeof(buf); + DO(ed448_export(buf, &buflen, PK_PUBLIC | PK_STD, &priv)); + DO(ed448_import(buf, buflen, &imported)); + COMPARE_TESTVECTOR(&pub, sizeof(pub), &imported, sizeof(imported), "Ed448 pub DER round-trip", __LINE__); + + return CRYPT_OK; +} + +int ed448_test(void) +{ + DO(s_ed448_keygen_sign_verify()); + DO(s_rfc_8032_5_2_6_pure_test()); + DO(s_rfc_8032_5_2_6_ctx_test()); + DO(s_rfc_8032_5_2_6_ph_test()); + if (ltc_mp.name != NULL) { + DO(s_ed448_compat_test()); + } + return CRYPT_OK; +} + +#else + +int ed448_test(void) +{ + return CRYPT_NOP; +} + +#endif diff --git a/tests/file_test.c b/tests/file_test.c index c410d8963..294e95500 100644 --- a/tests/file_test.c +++ b/tests/file_test.c @@ -28,6 +28,10 @@ int file_test(void) isha256 = find_hash("sha256"); iaes = find_cipher("aes"); + /* Suppress warnings when building with -DLTC_MINIMAL */ + LTC_UNUSED_PARAM(iaes); + LTC_UNUSED_PARAM(key); + len = sizeof(buf); if ((in = fopen(fname, "rb")) == NULL) return CRYPT_FILE_NOTFOUND; err = hash_filehandle(isha256, in, buf, &len); diff --git a/tests/mac_test.c b/tests/mac_test.c index da1d95372..d1c0307c6 100644 --- a/tests/mac_test.c +++ b/tests/mac_test.c @@ -23,9 +23,6 @@ int mac_test(void) #ifdef LTC_EAX_MODE DO(eax_test()); #endif -#ifdef LTC_OCB_MODE - DO(ocb_test()); -#endif #ifdef LTC_OCB3_MODE DO(ocb3_test()); #endif @@ -52,6 +49,7 @@ int mac_test(void) #endif #ifdef LTC_SIV_MODE DO(siv_test()); + DO(siv_wycheproof_test()); #endif return 0; } diff --git a/tests/misc_test.c b/tests/misc_test.c index 5a60ff236..d3d2945dc 100644 --- a/tests/misc_test.c +++ b/tests/misc_test.c @@ -4,9 +4,15 @@ int misc_test(void) { +#ifdef LTC_ARGON2 + DO(argon2_test()); +#endif #ifdef LTC_BCRYPT DO(bcrypt_test()); #endif +#ifdef LTC_SCRYPT + DO(scrypt_test()); +#endif #ifdef LTC_HKDF DO(hkdf_test()); #endif diff --git a/tests/multi_test.c b/tests/multi_test.c index e02940554..94236c1b1 100644 --- a/tests/multi_test.c +++ b/tests/multi_test.c @@ -9,10 +9,16 @@ int multi_test(void) unsigned char buf[2][MAXBLOCKSIZE]; unsigned long len, len2; + /* Suppress warnings when building with -DLTC_MINIMAL */ + LTC_UNUSED_PARAM(key); + LTC_UNUSED_PARAM(buf); + LTC_UNUSED_PARAM(len); + LTC_UNUSED_PARAM(len2); /* register algos */ register_hash(&sha256_desc); register_cipher(&aes_desc); +#ifdef LTC_HASH_HELPERS /* HASH testing */ len = sizeof(buf[0]); #if defined(ENDIAN_32BITWORD) || defined(_WIN32) || defined(ENDIAN_64BITWORD_ILP32) @@ -43,6 +49,7 @@ int multi_test(void) printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return CRYPT_FAIL_TESTVECTOR; } +#endif #ifdef LTC_HMAC len = sizeof(buf[0]); diff --git a/tests/padding_test.c b/tests/padding_test.c index 9cc9add4a..434db007b 100644 --- a/tests/padding_test.c +++ b/tests/padding_test.c @@ -5,11 +5,11 @@ #ifdef LTC_PADDING -typedef struct padding_testcase_ padding_testcase; +typedef struct padding_testcase padding_testcase; typedef int (*cmp_padding_testcase)(const padding_testcase*, const unsigned char*, unsigned long); -struct padding_testcase_ { +struct padding_testcase { unsigned long is, should, max, mode; const char* name; cmp_padding_testcase cmp; diff --git a/tests/pem/openssl_ed448_pk.pem b/tests/pem/openssl_ed448_pk.pem new file mode 100644 index 000000000..c31b24012 --- /dev/null +++ b/tests/pem/openssl_ed448_pk.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MEMwBQYDK2VxAzoAZkavwN2Jb7JwbSR79T0JZUDV1VOCgm1AlFdsW9dV+O57w7E2 ++y9O4Ejkhya86byArbdRsOk7ovqA +-----END PUBLIC KEY----- diff --git a/tests/pem/openssl_ed448_sk.pem b/tests/pem/openssl_ed448_sk.pem new file mode 100644 index 000000000..7d6ee84c5 --- /dev/null +++ b/tests/pem/openssl_ed448_sk.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEcCAQAwBQYDK2VxBDsEOe/w/F8aSpwuG9cBnsAkhloXWhPJEVhCxzWdXebe27Tu +f1R24A1BP7pjIihNdlXTsxv+sFuKWMR5ng== +-----END PRIVATE KEY----- diff --git a/tests/pem/openssl_ed448_x509.pem b/tests/pem/openssl_ed448_x509.pem new file mode 100644 index 000000000..33de3f859 --- /dev/null +++ b/tests/pem/openssl_ed448_x509.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhDCCAQSgAwIBAgIUA30c9xlNmn6aa6MeW/sattDShU8wBQYDK2VxMBExDzAN +BgNVBAMMBkNyeXB0WDAgFw0yNjA0MTQxMjAwMDNaGA8yMzAwMDEyNzEyMDAwM1ow +ETEPMA0GA1UEAwwGQ3J5cHRYMEMwBQYDK2VxAzoAZkavwN2Jb7JwbSR79T0JZUDV +1VOCgm1AlFdsW9dV+O57w7E2+y9O4Ejkhya86byArbdRsOk7ovqAo1MwUTAdBgNV +HQ4EFgQUrowTD38+WWdAZuwA1WLZu/7xsGIwHwYDVR0jBBgwFoAUrowTD38+WWdA +ZuwA1WLZu/7xsGIwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDD6A7cE22i0417 +jNIVCCMPxY09OkC5yFLXV3MilpvyWyUQFz/J4XWxpnRyWYaap6EeZLzowTtPFgCH +uPj4rCSVFQkBRaMkBv1zsFUXz7mAg01aNZFu7aDO+n+ctpl/8+BLw1+lQm4BiOGw +47xwywstBgA= +-----END CERTIFICATE----- diff --git a/tests/pem/openssl_x448_pk.pem b/tests/pem/openssl_x448_pk.pem new file mode 100644 index 000000000..3df5c9529 --- /dev/null +++ b/tests/pem/openssl_x448_pk.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MEIwBQYDK2VvAzkApScinIzW1CGVm4zV1j6fw7GsbeHGFy8QY7JLd8tXGiaXzr+/ +OwJqRZ9X1QhfEYso6no4d1fP9N0= +-----END PUBLIC KEY----- diff --git a/tests/pem/openssl_x448_sk.pem b/tests/pem/openssl_x448_sk.pem new file mode 100644 index 000000000..f6c4fe672 --- /dev/null +++ b/tests/pem/openssl_x448_sk.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEYCAQAwBQYDK2VvBDoEOPBQlJ/c83DaT71qCGj25lKh7rr3q6pRBIqHCjExTXD0 +vM82EulDzmjR9WU9zaS00j2LU4XXKpvV +-----END PRIVATE KEY----- diff --git a/tests/pem/pkcs/extra/zerolength.pem b/tests/pem/pkcs/extra/zerolength.pem new file mode 100644 index 000000000..e6d78fdea --- /dev/null +++ b/tests/pem/pkcs/extra/zerolength.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQowAAOCAQ8AMIIBCgKCAQEAvTHHoCaR0tlYfvapRv94 +hUTMrdSymIrWIIZ5Kmv5bIYWtK0TMX0icLkB0PzR2IDLj1L7hzBKUljBGzjf6ujf +Zwru5+odDZ344A6AhH5B5Zie1ALUTnizD+8XtWcdOtv4aF5NwgRJns0YY+HVr/KK +fPZurfMf7JI2wSCt0TRRUixkfJgypnLNZNMowcMiGD9GYdCb2mC43V8DKNpUIIIU +JK/auxqAxdEnY6GwI4zYnQdCv8ULai/LcB2CQhj5gm9PeKI6K1qkKs5/F1N2+2y9 +srrSk7pYPU0xxrj5Ap5GsTaJJJhV9QV1bgDiJaakWhh2m9jSs6SsufHCPT5RiCVh +5QIDAQAB +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/tests/pem/pkcs/openssl_ed448_sk.pk8 b/tests/pem/pkcs/openssl_ed448_sk.pk8 new file mode 100644 index 000000000..7d6ee84c5 --- /dev/null +++ b/tests/pem/pkcs/openssl_ed448_sk.pk8 @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEcCAQAwBQYDK2VxBDsEOe/w/F8aSpwuG9cBnsAkhloXWhPJEVhCxzWdXebe27Tu +f1R24A1BP7pjIihNdlXTsxv+sFuKWMR5ng== +-----END PRIVATE KEY----- diff --git a/tests/pem/pkcs/openssl_ed448_sk_pbes1.pk8 b/tests/pem/pkcs/openssl_ed448_sk_pbes1.pk8 new file mode 100644 index 000000000..c7574555e --- /dev/null +++ b/tests/pem/pkcs/openssl_ed448_sk_pbes1.pk8 @@ -0,0 +1,5 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MHAwHAYKKoZIhvcNAQwBAzAOBAjJ1wdj8L5FKgICCAAEUFrnEEVG1fA7XOx15h9T +H0TLtbCm/UYnFLh8GDGVjM+q/OYrfnTv5a6P5G/Ze7tMVsSCpgZBlSL9/Q6NJ37P +2X/Jd5vwyJSRzm+qeugIci5d +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/pem/pkcs/openssl_ed448_sk_pbes2.pk8 b/tests/pem/pkcs/openssl_ed448_sk_pbes2.pk8 new file mode 100644 index 000000000..27f9ef3a2 --- /dev/null +++ b/tests/pem/pkcs/openssl_ed448_sk_pbes2.pk8 @@ -0,0 +1,6 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAhhZGWQAxrkOAICCAAw +DAYIKoZIhvcNAgsFADAdBglghkgBZQMEASoEEBWa/IgJqnE1O2ibVuIkqVwEUIEG +2Wj76gtauZF1wEIts6PN/of37CQjdI8qBT95f0NemnXA9KWhqdT7zCVoZykdwTtr +QveA4USScJ1NjGRCgLcoh+RW0/7pQLI1s06UIptb +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/pem/pkcs/openssl_x448_sk.pk8 b/tests/pem/pkcs/openssl_x448_sk.pk8 new file mode 100644 index 000000000..f6c4fe672 --- /dev/null +++ b/tests/pem/pkcs/openssl_x448_sk.pk8 @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEYCAQAwBQYDK2VvBDoEOPBQlJ/c83DaT71qCGj25lKh7rr3q6pRBIqHCjExTXD0 +vM82EulDzmjR9WU9zaS00j2LU4XXKpvV +-----END PRIVATE KEY----- diff --git a/tests/pem/pkcs/openssl_x448_sk_pbes1.pk8 b/tests/pem/pkcs/openssl_x448_sk_pbes1.pk8 new file mode 100644 index 000000000..b0c6a9289 --- /dev/null +++ b/tests/pem/pkcs/openssl_x448_sk_pbes1.pk8 @@ -0,0 +1,5 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MHAwHAYKKoZIhvcNAQwBAzAOBAgZ7uqzZ0UIPAICCAAEUIoyzd9lPvjne3Bg7lk9 +PIHPqflbG9jCtk9192bVNj8+QHA1+XMEB9Ay3/Ljr+hQwiTS1tVELbzqyOoNYxpF +H91YfGjRZDrh2+k/K5MtLFUh +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/pem/pkcs/openssl_x448_sk_pbes2.pk8 b/tests/pem/pkcs/openssl_x448_sk_pbes2.pk8 new file mode 100644 index 000000000..14c70e5c5 --- /dev/null +++ b/tests/pem/pkcs/openssl_x448_sk_pbes2.pk8 @@ -0,0 +1,6 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAhzD7h+saEo1gICCAAw +DAYIKoZIhvcNAgsFADAdBglghkgBZQMEASoEEFcOyy6Y7TG3Z8wklZO14U8EUKKD +vdlVxsVBpoMpRTbYKen6rbSnAhysBG24K5AVyMAcsTXL1uzGHTIrV3xSjW4W8NV2 +N1MjPECNVcxH5HvsCOZ0lqYrj4IdSk4hL1+9Jrzz +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/pem_test.c b/tests/pem_test.c index 4dc14cbd7..652a341b8 100644 --- a/tests/pem_test.c +++ b/tests/pem_test.c @@ -86,6 +86,8 @@ static int s_key_cmp(ltc_pka_key *key) case LTC_PKA_ED25519: case LTC_PKA_X25519: case LTC_PKA_DH: + case LTC_PKA_X448: + case LTC_PKA_ED448: return CRYPT_OK; default: return CRYPT_INVALID_ARG; diff --git a/tests/pkcs_1_eme_test.c b/tests/pkcs_1_eme_test.c index 9e818ace6..61bf9d91c 100644 --- a/tests/pkcs_1_eme_test.c +++ b/tests/pkcs_1_eme_test.c @@ -11,16 +11,17 @@ int pkcs_1_eme_test(void) { struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get(); - int prng_idx = register_prng(no_prng_desc); - int hash_idx = find_hash("sha1"); - unsigned int i; - unsigned int j; + ltc_rsa_op_parameters rsa_params = { + .wprng = register_prng(no_prng_desc), + .prng = (void*)no_prng_desc, + .params.hash_idx = -1, + .padding = LTC_PKCS_1_V1_5 + }; + unsigned int i, j; + rsa_params.params.hash_idx = find_hash("sha1"); if (ltc_mp.name == NULL) return CRYPT_NOP; - DO(prng_is_valid(prng_idx)); - DO(hash_is_valid(hash_idx)); - for (i = 0; i < LTC_ARRAY_SIZE(testcases_eme); ++i) { testcase_t* t = &testcases_eme[i]; rsa_key k, *key = &k; @@ -41,11 +42,11 @@ int pkcs_1_eme_test(void) unsigned char buf[256], obuf[256]; unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; - prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc); - DOX(rsa_encrypt_key_ex(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, -1, -1, LTC_PKCS_1_V1_5, key), s->name); + prng_descriptor[rsa_params.wprng].add_entropy(s->o2, s->o2_l, (void*)rsa_params.prng); + DOX(rsa_encrypt_key_v2(s->o1, s->o1_l, obuf, &obuflen, &rsa_params, key), s->name); COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j); - DOX(rsa_decrypt_key_ex(obuf, obuflen, buf, &buflen, NULL, 0, -1, -1, LTC_PKCS_1_V1_5, &stat, key), s->name); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); + DOX(rsa_decrypt_key_v2(obuf, obuflen, buf, &buflen, &rsa_params, &stat, key), s->name); + ENSUREX(stat == 1, s->name); } /* for */ ltc_mp_deinit_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, LTC_NULL); diff --git a/tests/pkcs_1_emsa_test.c b/tests/pkcs_1_emsa_test.c index 43fb112ae..4691e259b 100644 --- a/tests/pkcs_1_emsa_test.c +++ b/tests/pkcs_1_emsa_test.c @@ -10,9 +10,13 @@ int pkcs_1_emsa_test(void) { + ltc_rsa_op_parameters rsa_params = { + .params.hash_idx = -1, + .padding = LTC_PKCS_1_V1_5 + }; int hash_idx = find_hash("sha1"); - unsigned int i; - unsigned int j; + unsigned int i, j; + rsa_params.params.hash_idx = hash_idx; if (ltc_mp.name == NULL) return CRYPT_NOP; @@ -39,10 +43,10 @@ int pkcs_1_emsa_test(void) unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; DOX(hash_memory(hash_idx, s->o1, s->o1_l, buf, &buflen), s->name); - DOX(rsa_sign_hash_ex(buf, buflen, obuf, &obuflen, LTC_PKCS_1_V1_5, NULL, -1, hash_idx, 0, key), s->name); + DOX(rsa_sign_hash_v2(buf, buflen, obuf, &obuflen, &rsa_params, key), s->name); COMPARE_TESTVECTOR(obuf, obuflen, s->o2, s->o2_l,s->name, j); - DOX(rsa_verify_hash_ex(obuf, obuflen, buf, buflen, LTC_PKCS_1_V1_5, hash_idx, 0, &stat, key), s->name); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); + DOX(rsa_verify_hash_v2(obuf, obuflen, buf, buflen, &rsa_params, &stat, key), s->name); + ENSUREX(stat == 1, s->name); } /* for */ ltc_mp_deinit_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, LTC_NULL); diff --git a/tests/pkcs_1_oaep_test.c b/tests/pkcs_1_oaep_test.c index 76157c2c0..ec90c13ca 100644 --- a/tests/pkcs_1_oaep_test.c +++ b/tests/pkcs_1_oaep_test.c @@ -11,15 +11,19 @@ int pkcs_1_oaep_test(void) { struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get(); - int prng_idx = register_prng(no_prng_desc); - int hash_idx = find_hash("sha1"); - unsigned int i; - unsigned int j; + ltc_rsa_op_parameters rsa_params = { + .wprng = register_prng(no_prng_desc), + .prng = (void*)no_prng_desc, + .params.hash_idx = -1, + .params.mgf1_hash_idx = -1, + .padding = LTC_PKCS_1_OAEP + }; + unsigned int i, j; + rsa_params.params.hash_idx = find_hash("sha1"); + rsa_params.params.mgf1_hash_idx = rsa_params.params.hash_idx; if (ltc_mp.name == NULL) return CRYPT_NOP; - DO(prng_is_valid(prng_idx)); - DO(hash_is_valid(hash_idx)); for (i = 0; i < LTC_ARRAY_SIZE(testcases_oaep); ++i) { testcase_t* t = &testcases_oaep[i]; @@ -41,11 +45,11 @@ int pkcs_1_oaep_test(void) unsigned char buf[256], obuf[256]; unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; - prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc); - DOX(rsa_encrypt_key(s->o1, s->o1_l, obuf, &obuflen, NULL, 0, (void*)no_prng_desc, prng_idx, hash_idx, key), s->name); + prng_descriptor[rsa_params.wprng].add_entropy(s->o2, s->o2_l, rsa_params.prng); + DOX(rsa_encrypt_key_v2(s->o1, s->o1_l, obuf, &obuflen, &rsa_params, key), s->name); COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j); - DOX(rsa_decrypt_key(obuf, obuflen, buf, &buflen, NULL, 0, hash_idx, &stat, key), s->name); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); + DOX(rsa_decrypt_key_v2(obuf, obuflen, buf, &buflen, &rsa_params, &stat, key), s->name); + ENSUREX(stat == 1, s->name); } /* for */ ltc_mp_deinit_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, LTC_NULL); diff --git a/tests/pkcs_1_pss_test.c b/tests/pkcs_1_pss_test.c index a86e473ac..12365bf91 100644 --- a/tests/pkcs_1_pss_test.c +++ b/tests/pkcs_1_pss_test.c @@ -11,14 +11,20 @@ int pkcs_1_pss_test(void) { struct ltc_prng_descriptor* no_prng_desc = no_prng_desc_get(); - int prng_idx = register_prng(no_prng_desc); + ltc_rsa_op_parameters rsa_params = { + .wprng = register_prng(no_prng_desc), + .prng = (void*)no_prng_desc, + .params.hash_idx = -1, + .params.mgf1_hash_idx = -1, + .padding = LTC_PKCS_1_PSS + }; int hash_idx = find_hash("sha1"); - unsigned int i; - unsigned int j; + unsigned int i, j; + rsa_params.params.hash_idx = hash_idx; + rsa_params.params.mgf1_hash_idx = hash_idx; if (ltc_mp.name == NULL) return CRYPT_NOP; - DO(prng_is_valid(prng_idx)); DO(hash_is_valid(hash_idx)); for (i = 0; i < LTC_ARRAY_SIZE(testcases_pss); ++i) { @@ -41,12 +47,13 @@ int pkcs_1_pss_test(void) unsigned char buf[20], obuf[256]; unsigned long buflen = sizeof(buf), obuflen = sizeof(obuf); int stat; - prng_descriptor[prng_idx].add_entropy(s->o2, s->o2_l, (void*)no_prng_desc); + prng_descriptor[rsa_params.wprng].add_entropy(s->o2, s->o2_l, rsa_params.prng); DOX(hash_memory(hash_idx, s->o1, s->o1_l, buf, &buflen), s->name); - DOX(rsa_sign_hash(buf, buflen, obuf, &obuflen, (void*)no_prng_desc, prng_idx, hash_idx, s->o2_l, key), s->name); + rsa_params.params.saltlen = s->o2_l; + DOX(rsa_sign_hash_v2(buf, buflen, obuf, &obuflen, &rsa_params, key), s->name); COMPARE_TESTVECTOR(obuf, obuflen, s->o3, s->o3_l,s->name, j); - DOX(rsa_verify_hash(obuf, obuflen, buf, buflen, hash_idx, s->o2_l, &stat, key), s->name); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, s->name); + DOX(rsa_verify_hash_v2(obuf, obuflen, buf, buflen, &rsa_params, &stat, key), s->name); + ENSUREX(stat == 1, s->name); } /* for */ ltc_mp_deinit_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, LTC_NULL); diff --git a/tests/pkcs_1_test.c b/tests/pkcs_1_test.c index de0f7d307..79ee4e079 100644 --- a/tests/pkcs_1_test.c +++ b/tests/pkcs_1_test.c @@ -13,18 +13,17 @@ int pkcs_1_test(void) { unsigned char buf[3][128]; - int res1, res2, res3, prng_idx, hash_idx; - unsigned long x, y, l1, l2, l3, i1, lparamlen, saltlen, modlen; + int res1, res2, res3; + unsigned long x, y, l1, l2, l3, i1, modlen; static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; - - /* get hash/prng */ - hash_idx = find_hash("sha1"); - prng_idx = find_prng("yarrow"); - - if (hash_idx == -1 || prng_idx == -1) { - fprintf(stderr, "pkcs_1 tests require sha1/yarrow"); - return 1; - } + ltc_rsa_op_parameters rsa_params = { + .wprng = find_prng("yarrow"), + .prng = &yarrow_prng, + .params.hash_idx = -1, + .params.mgf1_hash_idx = -1, + }; + rsa_params.params.hash_idx = find_hash("sha1"); + rsa_params.params.mgf1_hash_idx = rsa_params.params.hash_idx; srand(LTC_TEST_RAND_SEED); /* do many tests */ @@ -36,49 +35,43 @@ int pkcs_1_test(void) for (y = 0; y < l3; y++) buf[0][y] = rand() & 255; /* pick a random lparam len [0..16] */ - lparamlen = abs(rand()) % 17; + rsa_params.u.crypt.lparamlen = abs(rand()) % 17; /* pick a random saltlen 0..16 */ - saltlen = abs(rand()) % 17; + rsa_params.params.saltlen = abs(rand()) % 17; /* PKCS #1 v2.0 supports modlens not multiple of 8 */ modlen = 800 + (abs(rand()) % 224); /* encode it */ l1 = sizeof(buf[1]); - DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, -1, buf[1], &l1)); + rsa_params.padding = LTC_PKCS_1_OAEP; + rsa_params.u.crypt.lparam = lparam; + DO(ltc_pkcs_1_oaep_encode(buf[0], l3, &rsa_params, modlen, buf[1], &l1)); /* decode it */ l2 = sizeof(buf[2]); - DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, -1, buf[2], &l2, &res1)); - - if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { - fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); - fprintf(stderr, "ORIGINAL:\n"); - for (x = 0; x < l3; x++) { - fprintf(stderr, "%02x ", buf[0][x]); - } - fprintf(stderr, "\nRESULT:\n"); - for (x = 0; x < l2; x++) { - fprintf(stderr, "%02x ", buf[2][x]); - } - fprintf(stderr, "\n\n"); - return 1; - } + DO(ltc_pkcs_1_oaep_decode(buf[1], l1, &rsa_params, modlen, buf[2], &l2, &res1)); + + ENSURE(res1 == 1); + COMPARE_TESTVECTOR(buf[0], l3, buf[2], l2, "PKCS#1 OAEP", x); /* test PSS */ l1 = sizeof(buf[1]); - DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &yarrow_prng, prng_idx, hash_idx, modlen, buf[1], &l1)); - DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1)); + rsa_params.padding = LTC_PKCS_1_PSS; + rsa_params.u.crypt.lparam = NULL; + rsa_params.u.crypt.lparamlen = 0; + DO(ltc_pkcs_1_pss_encode_mgf1(buf[0], l3, &rsa_params, modlen, buf[1], &l1)); + DO(ltc_pkcs_1_pss_decode_mgf1(buf[0], l3, buf[1], l1, &rsa_params, modlen, &res1)); buf[0][i1 = abs(rand()) % l3] ^= 1; - DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2)); + DO(ltc_pkcs_1_pss_decode_mgf1(buf[0], l3, buf[1], l1, &rsa_params, modlen, &res2)); buf[0][i1] ^= 1; buf[1][abs(rand()) % (l1 - 1)] ^= 1; - pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3); + ltc_pkcs_1_pss_decode_mgf1(buf[0], l3, buf[1], l1, &rsa_params, modlen, &res3); if (!(res1 == 1 && res2 == 0 && res3 == 0)) { - fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); + fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, rsa_params.params.saltlen); return 1; } } diff --git a/tests/rsa_test.c b/tests/rsa_test.c index c1cfbb2b0..e4d16ac10 100644 --- a/tests/rsa_test.c +++ b/tests/rsa_test.c @@ -134,7 +134,7 @@ static const char *hex_key[] = { "DCCC27C8E4DC6248D59BAFF5AB60F621FD53E2B75D09C91AA104A9FC612C5D04583A5A39F14A215667FDCC20A38F78185A793D2E8E7E860AE6A833C104174A9F" }; /*** openssl public RSA key in DER format */ -static const unsigned char openssl_public_rsa[] = { +const unsigned char ltc_openssl_public_rsa[] = { 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, @@ -146,6 +146,7 @@ static const unsigned char openssl_public_rsa[] = { 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, }; +const unsigned long ltc_openssl_public_rsa_sz = sizeof(ltc_openssl_public_rsa); /* same key but with extra headers stripped */ static const unsigned char openssl_public_rsa_stripped[] = { @@ -184,22 +185,24 @@ static int rsa_compat_test(void) int stat, i; unsigned char buf[1024], key_parts[8][128]; unsigned long len, key_lens[8]; + ltc_rsa_op_parameters rsa_params = {0}; /* try reading the key */ DO(rsa_import(ltc_rsa_private_test_key, sizeof(ltc_rsa_private_test_key), &key)); - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &pubkey)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &pubkey)); /* sign-verify a message with PKCS #1 v1.5 no ASN.1 */ len = sizeof(buf); - DO(rsa_sign_hash_ex((unsigned char*)"test", 4, buf, &len, LTC_PKCS_1_V1_5_NA1, NULL, 0, 0, 0, &key)); + rsa_params.padding = LTC_PKCS_1_V1_5_NA1; + DO(rsa_sign_hash_v2((unsigned char*)"test", 4, buf, &len, &rsa_params, &key)); if (len != sizeof(openssl_rsautl_pkcs) || memcmp(buf, openssl_rsautl_pkcs, len)) { - fprintf(stderr, "RSA rsa_sign_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n"); + fprintf(stderr, "RSA rsa_sign_hash_v2 + LTC_PKCS_1_V1_5_NA1 failed\n"); return 1; } stat = 0; - DO(rsa_verify_hash_ex(openssl_rsautl_pkcs, sizeof(openssl_rsautl_pkcs), (unsigned char*)"test", 4, LTC_PKCS_1_V1_5_NA1, 0, 0, &stat, &pubkey)); + DO(rsa_verify_hash_v2(openssl_rsautl_pkcs, sizeof(openssl_rsautl_pkcs), (unsigned char*)"test", 4, &rsa_params, &stat, &pubkey)); if (stat != 1) { - fprintf(stderr, "RSA rsa_verify_hash_ex + LTC_PKCS_1_V1_5_NA1 failed\n"); + fprintf(stderr, "RSA rsa_verify_hash_v2 + LTC_PKCS_1_V1_5_NA1 failed\n"); return 1; } rsa_free(&pubkey); @@ -222,7 +225,7 @@ static int rsa_compat_test(void) rsa_free(&key); /* try reading the public key */ - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC, &key)); COMPARE_TESTVECTOR(buf, len, openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), "RSA public export (from OpenSSL)", 0); @@ -257,10 +260,10 @@ static int rsa_compat_test(void) rsa_free(&key); /* try export in SubjectPublicKeyInfo format of the public key */ - DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key)); - COMPARE_TESTVECTOR(buf, len, openssl_public_rsa, sizeof(openssl_public_rsa), "RSA public export (X.509)", 0); + COMPARE_TESTVECTOR(buf, len, ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), "RSA public export (X.509)", 0); rsa_free(&key); return 0; @@ -319,6 +322,10 @@ static int s_rsa_cryptx_issue_69(void) unsigned char buf0[512], buf1[512]; unsigned long l0, l1; int stat; + ltc_rsa_op_parameters rsa_params = { + .params.hash_idx = -1, + .params.mgf1_hash_idx = -1, + }; l0 = sizeof(buf0); l1 = sizeof(buf1); @@ -331,9 +338,10 @@ static int s_rsa_cryptx_issue_69(void) l1 = sizeof(buf1); DO(radix_to_bin(sig1, 16, buf0, &l0)); DO(radix_to_bin(hash, 16, buf1, &l1)); - SHOULD_FAIL(rsa_verify_hash_ex(buf0, l0, buf1, l1, LTC_PKCS_1_V1_5, 0, 0, &stat, &key)); + rsa_params.padding = LTC_PKCS_1_V1_5; + SHOULD_FAIL(rsa_verify_hash_v2(buf0, l0, buf1, l1, &rsa_params, &stat, &key)); DO(radix_to_bin(sig2, 16, buf0, &l0)); - SHOULD_FAIL(rsa_verify_hash_ex(buf0, l0, buf1, l1, LTC_PKCS_1_V1_5, 0, 0, &stat, &key)); + SHOULD_FAIL(rsa_verify_hash_v2(buf0, l0, buf1, l1, &rsa_params, &stat, &key)); rsa_free(&key); return CRYPT_OK; } @@ -448,17 +456,83 @@ static int s_rsa_import_pkcs8(const void *in, unsigned long inlen, void *key) #endif #endif +static int s_rsa_macros_test(void) +{ + rsa_key key, pubkey; + int stat; + const unsigned char tv[] = "test"; + unsigned char buf0[1024], buf1[1024]; + unsigned long buf0len, buf1len; + + DO(rsa_import(ltc_rsa_private_test_key, sizeof(ltc_rsa_private_test_key), &key)); + DO(rsa_import(ltc_openssl_public_rsa, sizeof(ltc_openssl_public_rsa), &pubkey)); + + buf0len = sizeof(buf0); + DO(ltc_rsa_sign_hash(tv, 4, buf0, &buf0len, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), 8, &key)); + buf1len = sizeof(buf1); + DO(ltc_rsa_verify_hash(buf0, buf0len, tv, 4, find_hash("sha1"), 8, &stat, &key)); + ENSURE(stat == 1); + + buf0len = sizeof(buf0); + DO(ltc_rsa_encrypt_key(tv, 4, buf0, &buf0len, NULL, 0, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &pubkey)); + buf1len = sizeof(buf1); + DO(ltc_rsa_decrypt_key(buf0, buf0len, buf1, &buf1len, NULL, 0, find_hash("sha1"), &stat, &key)); + ENSURE(stat == 1); + COMPARE_TESTVECTOR(buf1, buf1len, tv, 4, "s_rsa_macros_test", 0); + + rsa_free(&pubkey); + rsa_free(&key); + + return CRYPT_OK; +} + +static int s_rsa_pss_test(void) +{ + rsa_key key; + const unsigned char tv[] = "test"; + unsigned char buf0[1024]; + unsigned long buf0len; + ltc_rsa_op_parameters rsa_oparams = { + .prng = &yarrow_prng, + .wprng = find_prng("yarrow"), + .padding = LTC_PKCS_1_OAEP, + .u.crypt.lparam = tv, + .u.crypt.lparamlen = (unsigned long)4, + .params.saltlen = 7, + }; + + rsa_oparams.params.hash_idx = find_hash("sha1"); + rsa_oparams.params.mgf1_hash_idx = find_hash("sha256"); + + DO(rsa_import(ltc_rsa_private_test_key, sizeof(ltc_rsa_private_test_key), &key)); + + buf0len = sizeof(buf0); + DO(rsa_encrypt_key_v2(tv, 4, buf0, &buf0len, &rsa_oparams, &key)); + DO(rsa_encrypt_key_v2(tv, 4, buf0, &buf0len, &rsa_oparams, &key)); + key.params = rsa_oparams.params; + key.pss_oaep = 1; + DO(rsa_encrypt_key_v2(tv, 4, buf0, &buf0len, &rsa_oparams, &key)); + /* If the key is a PSS key, we must do a PSS operation */ + rsa_oparams.padding = LTC_PKCS_1_V1_5; + SHOULD_FAIL(rsa_encrypt_key_v2(tv, 4, buf0, &buf0len, &rsa_oparams, &key)); + + rsa_free(&key); + + return CRYPT_OK; +} + int rsa_test(void) { unsigned char in[1024], out[1024], tmp[3072]; rsa_key key, privKey, pubKey; - int hash_idx, prng_idx, stat, stat2, i, mgf_hash, label_hash; - unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize; + int prng_idx, stat, stat2, i, mgf_hash; + unsigned long rsa_msgsize, len, len2, len3, cnt, cnt2, max_msgsize, label_hash; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; void* dP; unsigned char* p; unsigned char* p2; unsigned char* p3; + ltc_rsa_op_parameters rsa_params = {0}; if (ltc_mp.name == NULL) return CRYPT_NOP; @@ -466,12 +540,16 @@ int rsa_test(void) return 1; } - hash_idx = find_hash("sha1"); - prng_idx = find_prng("yarrow"); - if (hash_idx == -1 || prng_idx == -1) { + rsa_params.params.hash_idx = find_hash("sha1"); + rsa_params.params.mgf1_hash_idx = rsa_params.params.hash_idx; + rsa_params.wprng = find_prng("yarrow"); + mgf_hash = rsa_params.params.hash_idx; + if (mgf_hash == -1 || rsa_params.wprng == -1) { fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow"); return 1; } + rsa_params.prng = &yarrow_prng; + prng_idx = rsa_params.wprng; #ifdef LTC_TEST_READDIR DO(test_process_dir("tests/rsa", &key, s_rsa_import_x509, NULL, (dir_cleanup_cb)rsa_free, "rsa_test")); @@ -481,6 +559,8 @@ int rsa_test(void) DO(test_process_dir("tests/rsa-pkcs8", &key, s_rsa_import_pkcs8, NULL, (dir_cleanup_cb)rsa_free, "rsa_pkcs8_test")); #endif + DO(s_rsa_pss_test()); + DO(s_rsa_macros_test()); DO(s_rsa_cryptx_issue_69()); DO(s_rsa_issue_301(prng_idx)); DO(s_rsa_public_ubin_e(prng_idx)); @@ -512,13 +592,13 @@ print_hex("q", tmp, len); /* make a random key/msg */ ENSURE(yarrow_read(in, 117, &yarrow_prng) == 117); + rsa_params.padding = LTC_PKCS_1_OAEP; #ifdef LTC_TEST_EXT for (mgf_hash = 0; mgf_hash < TAB_SIZE; ++mgf_hash) { if (hash_is_valid(mgf_hash) != CRYPT_OK) continue; #else { - mgf_hash = hash_idx; #endif for (label_hash = 0; label_hash < TAB_SIZE; ++label_hash) { if (hash_is_valid(label_hash) != CRYPT_OK) @@ -526,6 +606,8 @@ print_hex("q", tmp, len); if (2 * hash_descriptor[label_hash].hashsize > 126) continue; max_msgsize = 128 - (2 * hash_descriptor[label_hash].hashsize) - 2; + rsa_params.params.hash_idx = label_hash; + rsa_params.params.mgf1_hash_idx = mgf_hash; #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 fprintf(stderr, "Test MGF(%s), Labelhash(%s) with max_msgsize %lu\n", hash_descriptor[mgf_hash].name, hash_descriptor[label_hash].name, max_msgsize); @@ -536,59 +618,66 @@ print_hex("q", tmp, len); len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key)); + DO(rsa_encrypt_key_v2(in, rsa_msgsize, out, &len, &rsa_params, &key)); /* change a byte */ out[8] ^= 1; - SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key)); + SHOULD_FAIL(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat2, &key)); /* change a byte back */ out[8] ^= 1; ENSURE(len2 == rsa_msgsize); len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSUREX(stat == 1 && stat2 == 0, "rsa_decrypt_key (without lparam)"); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (without lparam)", cnt << 8 | rsa_msgsize); } /* encrypt the key (with lparam) */ + rsa_params.u.crypt.lparam = lparam; + rsa_params.u.crypt.lparamlen = sizeof(lparam); for (rsa_msgsize = 0; rsa_msgsize <= max_msgsize; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, mgf_hash, label_hash, LTC_PKCS_1_OAEP, &key)); + DO(rsa_encrypt_key_v2(rsa_msgsize ? in : NULL, rsa_msgsize, out, &len, &rsa_params, &key)); /* change a byte */ out[8] ^= 1; - SHOULD_FAIL(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat2, &key)); + SHOULD_FAIL(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat2, &key)); ENSURE(len2 == rsa_msgsize); /* change a byte back */ out[8] ^= 1; len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, lparam, sizeof(lparam), mgf_hash, label_hash, LTC_PKCS_1_OAEP, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSURE(stat == 1 && stat2 == 0); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key (with lparam)", rsa_msgsize); } + rsa_params.u.crypt.lparam = NULL; + rsa_params.u.crypt.lparamlen = 0; } } - + rsa_params.params.hash_idx = find_hash("sha1"); + rsa_params.params.mgf1_hash_idx = rsa_params.params.hash_idx; /* encrypt the key PKCS #1 v1.5 (payload from 1 to 117 bytes) */ + rsa_params.padding = LTC_PKCS_1_V1_5; for (rsa_msgsize = 0; rsa_msgsize <= 117; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; - DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, -1, LTC_PKCS_1_V1_5, &key)); + DO(rsa_encrypt_key_v2(in, rsa_msgsize, out, &len, &rsa_params, &key)); len2 = rsa_msgsize; - DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, -1, LTC_PKCS_1_V1_5, &stat, &key)); + DO(rsa_decrypt_key_v2(out, len, tmp, &len2, &rsa_params, &stat, &key)); ENSURE(stat == 1); COMPARE_TESTVECTOR(tmp, len2, in, rsa_msgsize, "rsa_decrypt_key_ex", rsa_msgsize); } /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); - DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); + rsa_params.padding = LTC_PKCS_1_PSS; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); @@ -607,20 +696,20 @@ print_hex("q", tmp, len); dbg_malloc_stats(); /* verify with original */ - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &key)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &key)); ENSUREX(stat == 1 && stat2 == 0, "rsa_verify_hash (unsalted, origKey) failed"); /* verify with privKey */ /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &privKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); @@ -636,10 +725,10 @@ print_hex("q", tmp, len); privKey.dP = NULL; /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &privKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); @@ -653,10 +742,10 @@ print_hex("q", tmp, len); /* verify with pubKey */ /* change byte back to original */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); @@ -668,11 +757,12 @@ print_hex("q", tmp, len); /* sign a message (salted) now (use privKey to make, pubKey to verify) */ len = sizeof(out); - DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); + rsa_params.params.saltlen = 8; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); @@ -681,17 +771,19 @@ print_hex("q", tmp, len); rsa_free(&privKey); return 1; } + rsa_params.params.saltlen = 0; /* sign a message with PKCS #1 v1.5 */ len = sizeof(out); - DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); - DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey)); + rsa_params.padding = LTC_PKCS_1_V1_5; + DO(rsa_sign_hash_v2(in, 20, out, &len, &rsa_params, &privKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; - DO(rsa_verify_hash_ex(out, len, in, 20, LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey)); + DO(rsa_verify_hash_v2(out, len, in, 20, &rsa_params, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { - fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash_v2 failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -717,14 +809,14 @@ print_hex("q", tmp, len); p = in; p2 = out; p3 = tmp; - for (i = 0; i < 9; ++i) { + for (i = 0; i < 10; ++i) { len = sizeof(in); len2 = sizeof(out); /* (1) */ - DO(rsa_sign_hash_ex(p, 20, p2, &len2, LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); + DO(rsa_sign_hash_v2(p, 20, p2, &len2, &rsa_params, &privKey)); /* (2) */ - DOX(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey), "should succeed"); - DOX(stat == 1?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should succeed"); + DOX(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey), "should succeed"); + ENSURE(stat == 1); len3 = sizeof(tmp); /* (3) */ DO(ltc_mp.rsa_me(p2, len2, p3, &len3, PK_PUBLIC, &key)); @@ -757,8 +849,11 @@ print_hex("q", tmp, len); len3 = sizeof(tmp); /* (6) */ - SHOULD_FAIL(rsa_verify_hash_ex(p2, len2, p, 20, LTC_PKCS_1_V1_5, hash_idx, -1, &stat, &pubKey)); - DOX(stat == 0?CRYPT_OK:CRYPT_FAIL_TESTVECTOR, "should fail"); + if (i < 8) + SHOULD_FAIL(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey)); + else + DO(rsa_verify_hash_v2(p2, len2, p, 20, &rsa_params, &stat, &pubKey)); + ENSURE(stat == 0); } rsa_free(&key); diff --git a/tests/scrypt_test.c b/tests/scrypt_test.c new file mode 100644 index 000000000..b3f579208 --- /dev/null +++ b/tests/scrypt_test.c @@ -0,0 +1,106 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include + +#ifdef LTC_SCRYPT + +/* RFC 7914 test vectors */ + +typedef struct { + const char *password; + unsigned long password_len; + const char *salt; + unsigned long salt_len; + unsigned long N, r, p; + const unsigned char expected[64]; + const char *name; +} scrypt_testcase; + +static const scrypt_testcase cases[] = { + { + "", 0, "", 0, 16, 1, 1, + { + 0x77, 0xd6, 0x57, 0x62, 0x38, 0x65, 0x7b, 0x20, + 0x3b, 0x19, 0xca, 0x42, 0xc1, 0x8a, 0x04, 0x97, + 0xf1, 0x6b, 0x48, 0x44, 0xe3, 0x07, 0x4a, 0xe8, + 0xdf, 0xdf, 0xfa, 0x3f, 0xed, 0xe2, 0x14, 0x42, + 0xfc, 0xd0, 0x06, 0x9d, 0xed, 0x09, 0x48, 0xf8, + 0x32, 0x6a, 0x75, 0x3a, 0x0f, 0xc8, 0x1f, 0x17, + 0xe8, 0xd3, 0xe0, 0xfb, 0x2e, 0x0d, 0x36, 0x28, + 0xcf, 0x35, 0xe2, 0x0c, 0x38, 0xd1, 0x89, 0x06 + }, + "scrypt(\"\", \"\", 16, 1, 1)" + }, + { + "password", 8, "NaCl", 4, 1024, 8, 16, + { + 0xfd, 0xba, 0xbe, 0x1c, 0x9d, 0x34, 0x72, 0x00, + 0x78, 0x56, 0xe7, 0x19, 0x0d, 0x01, 0xe9, 0xfe, + 0x7c, 0x6a, 0xd7, 0xcb, 0xc8, 0x23, 0x78, 0x30, + 0xe7, 0x73, 0x76, 0x63, 0x4b, 0x37, 0x31, 0x62, + 0x2e, 0xaf, 0x30, 0xd9, 0x2e, 0x22, 0xa3, 0x88, + 0x6f, 0xf1, 0x09, 0x27, 0x9d, 0x98, 0x30, 0xda, + 0xc7, 0x27, 0xaf, 0xb9, 0x4a, 0x83, 0xee, 0x6d, + 0x83, 0x60, 0xcb, 0xdf, 0xa2, 0xcc, 0x06, 0x40 + }, + "scrypt(\"password\", \"NaCl\", 1024, 8, 16)" + }, + { + "pleaseletmein", 13, "SodiumChloride", 14, 16384, 8, 1, + { + 0x70, 0x23, 0xbd, 0xcb, 0x3a, 0xfd, 0x73, 0x48, + 0x46, 0x1c, 0x06, 0xcd, 0x81, 0xfd, 0x38, 0xeb, + 0xfd, 0xa8, 0xfb, 0xba, 0x90, 0x4f, 0x8e, 0x3e, + 0xa9, 0xb5, 0x43, 0xf6, 0x54, 0x5d, 0xa1, 0xf2, + 0xd5, 0x43, 0x29, 0x55, 0x61, 0x3f, 0x0f, 0xcf, + 0x62, 0xd4, 0x97, 0x05, 0x24, 0x2a, 0x9a, 0xf9, + 0xe6, 0x1e, 0x85, 0xdc, 0x0d, 0x65, 0x1e, 0x40, + 0xdf, 0xcf, 0x01, 0x7b, 0x45, 0x57, 0x58, 0x87 + }, + "scrypt(\"pleaseletmein\", \"SodiumChloride\", 16384, 8, 1)" + }, +#ifdef LTC_SCRYPT_TEST_1GB + /* Define LTC_SCRYPT_TEST_1GB via CFLAGS to enable this test vector + * which allocates ~1 GiB of memory and takes a long time to run. */ + { + "pleaseletmein", 13, "SodiumChloride", 14, 1048576, 8, 1, + { + 0x21, 0x01, 0xcb, 0x9b, 0x6a, 0x51, 0x1a, 0xae, + 0xad, 0xdb, 0xbe, 0x09, 0xcf, 0x70, 0xf8, 0x81, + 0xec, 0x56, 0x8d, 0x57, 0x4a, 0x2f, 0xfd, 0x4d, + 0xab, 0xe5, 0xee, 0x98, 0x20, 0xad, 0xaa, 0x47, + 0x8e, 0x56, 0xfd, 0x8f, 0x4b, 0xa5, 0xd0, 0x9f, + 0xfa, 0x1c, 0x6d, 0x92, 0x7c, 0x40, 0xf4, 0xc3, + 0x37, 0x30, 0x40, 0x49, 0xe8, 0xa9, 0x52, 0xfb, + 0xcb, 0xf4, 0x5c, 0x6f, 0xa7, 0x7a, 0x41, 0xa4 + }, + "scrypt(\"pleaseletmein\", \"SodiumChloride\", 1048576, 8, 1)" + }, +#endif +}; + +int scrypt_test(void) +{ + unsigned char dk[64]; + unsigned int n; + + for (n = 0; n < LTC_ARRAY_SIZE(cases); ++n) { + DO(scrypt_pbkdf((const unsigned char *)cases[n].password, cases[n].password_len, + (const unsigned char *)cases[n].salt, cases[n].salt_len, + cases[n].N, cases[n].r, cases[n].p, + dk, sizeof(dk))); + COMPARE_TESTVECTOR(dk, sizeof(dk), cases[n].expected, sizeof(cases[n].expected), cases[n].name, n); + } + + return CRYPT_OK; +} + +#else + +int scrypt_test(void) +{ + return CRYPT_NOP; +} + +#endif diff --git a/tests/siv_wycheproof.h b/tests/siv_wycheproof.h new file mode 100644 index 000000000..e194ca026 --- /dev/null +++ b/tests/siv_wycheproof.h @@ -0,0 +1,1345 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include + +#if defined(LTC_TEST) && defined(LTC_SIV_MODE) +#include +typedef enum ltc_aes_siv_test_case_result +{ + LTC_TEST_CASE_SHOULD_SUCCEED, + LTC_TEST_CASE_SHOULD_FAIL, +} ltc_aes_siv_test_case_result; + +typedef struct { int tcId; const char* comment; uint8_t key[64]; unsigned long keyLen; const uint8_t* aad; unsigned long aadLen; const uint8_t* msg; unsigned long msgLen; const uint8_t* ct; unsigned long ctLen; ltc_aes_siv_test_case_result result; } aes_siv_test_case; + +static const uint8_t aad_1[] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27}; +static const uint8_t msg_1[] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee}; +static const uint8_t ct_1[] = {0x85,0x63,0x2d,0x07,0xc6,0xe8,0xf3,0x7f,0x95,0x0a,0xcd,0x32,0x0a,0x2e,0xcc,0x93,0x40,0xc0,0x2b,0x96,0x90,0xc4,0xdc,0x04,0xda,0xef,0x7f,0x6a,0xfe,0x5c}; +static const uint8_t ct_2[] = {0xb2,0xb2,0x35,0x4e,0x37,0x24,0xdc,0xda,0xa8,0x5e,0xcf,0x02,0x9b,0x49,0xa9,0x0c}; +static const uint8_t aad_3[] = {0x82,0x68,0xc5,0x19,0x4a,0x71,0xae,0xd0,0xfc,0x1d,0xaf,0xe3}; +static const uint8_t ct_3[] = {0x92,0xbc,0x07,0xee,0x20,0x0f,0xbd,0x48,0x8b,0x7f,0x70,0xa1,0x0d,0xa2,0x6a,0x21}; +static const uint8_t aad_4[] = {0x24,0xab,0x40,0xe7,0x96,0x6c,0x5b,0xfe,0x8a,0x5d,0x2b,0x0a,0x6a,0x97,0x65}; +static const uint8_t ct_4[] = {0xf4,0x49,0x34,0xd6,0xf5,0xba,0x77,0x12,0x2f,0x19,0x85,0x99,0xcd,0x0e,0x5e,0x52}; +static const uint8_t aad_5[] = {0x9f,0xff,0xf1,0x96,0xbe,0xfb,0x5f,0xfb,0xa0,0x1a,0xfa,0x92,0x35,0x41,0x8d,0x57}; +static const uint8_t ct_5[] = {0xc1,0x1a,0xb0,0xae,0x19,0x30,0x18,0xd2,0xc9,0xc7,0x98,0x5a,0xec,0x3f,0x8a,0x5b}; +static const uint8_t aad_6[] = {0xa9,0xef,0xd1,0x55,0x15,0x9b,0x53,0x3f,0x2b,0x64,0x9b,0x2e,0x5f,0xbf,0x87,0xe6,0xa2,0xc1,0x1e,0xe8}; +static const uint8_t ct_6[] = {0xcf,0x52,0xa3,0xc9,0xe2,0xd3,0xd9,0x9a,0x66,0xf7,0x41,0x35,0xf3,0x9e,0x28,0xbb}; +static const uint8_t aad_7[] = {0x89,0x6d,0xcd,0xb3,0x67,0xf3,0xc7,0x6d,0x60,0x09,0x3d,0xc5,0xae,0x09,0xbc,0x4f,0x30,0xe5,0xcb,0x88,0xe3,0x43,0x4e,0x6e,0xb0,0xf0,0x70,0x0a,0xc7,0x52,0xcd,0x97}; +static const uint8_t ct_7[] = {0x8f,0x60,0x3b,0x65,0xe7,0x67,0xef,0x17,0x8b,0x4d,0xd1,0x1d,0xb6,0xc1,0x14,0xc1}; +static const uint8_t aad_8[] = {0x86,0x5d,0x39,0xae,0x9b,0x5e,0x9f,0xf8,0xd6,0x30,0x8e,0x00,0x20,0x87,0x45,0xbc}; +static const uint8_t msg_8[] = {0xcc,0x37,0xfa,0xe1,0x5f,0x74,0x5a,0x2f,0x40,0xe2,0xc8,0xb1,0x92,0xf2,0xb3,0x8d}; +static const uint8_t ct_8[] = {0xc7,0x9c,0x86,0xcd,0x75,0x09,0xe6,0x0a,0x16,0xca,0x8c,0xec,0x6b,0xca,0xa1,0xc5,0x8f,0xbd,0x60,0x99,0x71,0x89,0x91,0xfe,0x77,0x5b,0xf5,0xa6,0x59,0xd3,0x0a,0x24}; +static const uint8_t aad_9[] = {0x8e,0xe2,0x1f,0x1a,0x5e,0x2b,0x3f,0x8b,0x8f,0x20,0x64,0xe5,0xce,0xca,0xc8,0x1d}; +static const uint8_t msg_9[] = {0x91,0xa1,0x7e,0x4d,0xfc,0xc3,0x16,0x6a,0x1a,0xdd,0x26,0xff,0x0e,0x7c,0x12,0x05,0x6e,0x8a,0x65,0x4f,0x28,0xa6,0xde,0x24,0xf4,0xba,0x73,0x9c,0xeb,0x5b,0x5b,0x18}; +static const uint8_t ct_9[] = {0x84,0x91,0x95,0x03,0x1e,0x89,0x27,0xa1,0xaf,0x4f,0x64,0xcb,0xdd,0x80,0x48,0x46,0x1c,0x03,0x59,0x8b,0xfb,0xa4,0x41,0x31,0x27,0x76,0xa4,0xe8,0xac,0x95,0x9b,0xee,0x44,0xc5,0x21,0x80,0x12,0x87,0xa2,0xfd,0x95,0xe2,0x32,0x9b,0x1c,0x69,0x44,0x41}; +static const uint8_t aad_10[] = {0x3a,0x83,0x63,0xf5,0x1b,0xce,0x89,0x1e,0xba,0x7b,0xcc,0x0a,0xa4,0x31,0x1e,0x10}; +static const uint8_t msg_10[] = {0x39,0xb4,0x47,0xbd,0x3a,0x01,0x98,0x3c,0x1c,0xb7,0x61,0xb4,0x56,0xd6,0x90,0x00,0x94,0x8c,0xeb,0x87,0x05,0x62,0xa5,0x36,0x12,0x6a,0x0d,0x18,0xa8,0xe7,0xe4,0x9b,0x16,0xde,0x8f,0xe6,0x72,0xf1,0x3d,0x08,0x08,0xd8,0xb7,0xd9,0x57,0x89,0x99,0x17}; +static const uint8_t ct_10[] = {0x9f,0x66,0x76,0x5a,0x01,0x92,0x77,0xa7,0xa7,0xac,0xb9,0x2e,0x80,0xf8,0x30,0x0b,0xaa,0x72,0x4c,0x92,0x56,0x09,0x51,0xeb,0x09,0xd8,0x55,0xf4,0x71,0xfe,0x1b,0x58,0x99,0x28,0xe5,0x1f,0x7a,0x8a,0x4b,0xbc,0x6c,0xc9,0xf5,0x5f,0xab,0xb2,0xec,0xa2,0xeb,0xb4,0xfa,0xca,0x14,0xd1,0xae,0x20,0xcf,0xdc,0x31,0xb9,0x60,0x2e,0x98,0x91}; +static const uint8_t aad_11[] = {0x4c,0x37,0x5f,0xd3,0xc4,0xd4,0x5c,0x5c,0xff,0xf1,0x6d,0x55}; +static const uint8_t msg_11[] = {0x49}; +static const uint8_t ct_11[] = {0xf5,0xc8,0x15,0x5c,0x7d,0xd7,0xf4,0x7c,0x61,0xd9,0x80,0xcc,0xd2,0x17,0x5b,0xeb,0x9b}; +static const uint8_t aad_12[] = {0x59,0x9f,0x61,0xc6,0x49,0xe7,0xcc,0x5c,0xbb,0xd7,0xa7,0x8f}; +static const uint8_t msg_12[] = {0x7c,0x0c}; +static const uint8_t ct_12[] = {0x13,0x0e,0x8d,0xe1,0x10,0x80,0xa3,0xb2,0x7c,0xc1,0xef,0x12,0x72,0x58,0x6c,0x24,0x71,0x7c}; +static const uint8_t aad_13[] = {0x9a,0x58,0x22,0x45,0xb4,0x6c,0x61,0x70,0xe3,0xf5,0xca,0x53}; +static const uint8_t msg_13[] = {0x2f,0x5c,0x53}; +static const uint8_t ct_13[] = {0xb9,0x89,0x02,0xdc,0x89,0xe6,0x81,0x1d,0xfb,0xa5,0xea,0xfb,0x15,0x61,0x18,0x6d,0xc1,0x84,0x9e}; +static const uint8_t aad_14[] = {0xea,0xb4,0x1f,0x34,0x17,0xc7,0x9b,0xc7,0x26,0x2c,0x7b,0x64}; +static const uint8_t msg_14[] = {0x41,0xec,0x71,0x78}; +static const uint8_t ct_14[] = {0xcd,0x82,0x47,0x17,0x88,0x6f,0x33,0x63,0x62,0x29,0x37,0xbc,0xd1,0x18,0x96,0x0a,0x0e,0x26,0x05,0xfe}; +static const uint8_t aad_15[] = {0xe9,0xa4,0xb0,0x8a,0x8e,0x2e,0xbb,0xb1,0x3f,0x82,0xf8,0x70}; +static const uint8_t msg_15[] = {0xeb,0xe6,0x56,0xa9,0x7b}; +static const uint8_t ct_15[] = {0x85,0x28,0x88,0x34,0xb2,0x5f,0x27,0xe9,0x60,0x83,0xe2,0xf3,0x60,0xd3,0xc7,0xe7,0x48,0x65,0x19,0xb4,0xf5}; +static const uint8_t aad_16[] = {0xfc,0xa5,0x37,0xf5,0x0d,0x5f,0xce,0x3c,0xdc,0x99,0x4b,0x70}; +static const uint8_t msg_16[] = {0x82,0xf0,0xd4,0x9b,0x77,0xa5}; +static const uint8_t ct_16[] = {0x9a,0xcd,0x6e,0xe8,0xa8,0x27,0xc2,0xc5,0xd0,0xda,0x7b,0xf7,0x81,0x5d,0xbd,0x85,0x11,0xbd,0x8c,0x5a,0x79,0xc1}; +static const uint8_t aad_17[] = {0x95,0xdc,0xea,0xfc,0xd4,0x26,0xa9,0xbc,0xbe,0x99,0xb8,0x42}; +static const uint8_t msg_17[] = {0x1d,0x63,0x52,0x48,0x01,0x4c,0x3b}; +static const uint8_t ct_17[] = {0xf7,0xc7,0x39,0xf6,0xa0,0xe2,0x0e,0x94,0x26,0x5e,0xcb,0xbd,0xae,0xc3,0x6c,0xd5,0x97,0x08,0x89,0x67,0x91,0x7d,0x47}; +static const uint8_t aad_18[] = {0x0c,0x78,0x41,0x25,0x71,0x5b,0x7f,0x9b,0x10,0x67,0xb0,0x77}; +static const uint8_t msg_18[] = {0xb9,0x78,0x58,0x7b,0xf0,0x28,0x55,0x8d}; +static const uint8_t ct_18[] = {0x16,0x38,0x33,0xac,0x90,0x4d,0x30,0x58,0x9c,0xad,0x9a,0x00,0x2b,0xd7,0x02,0xf5,0xc7,0x80,0x9b,0x04,0x69,0x3f,0xd8,0xfb}; +static const uint8_t aad_19[] = {0x53,0x35,0x39,0x76,0xf1,0x8a,0xe8,0xc8,0xcb,0xc7,0xe0,0x66}; +static const uint8_t msg_19[] = {0x07,0x8a,0x6a,0x3d,0x7d,0x1d,0x31,0x20,0x04}; +static const uint8_t ct_19[] = {0x87,0xa3,0x7e,0x3d,0xe3,0x69,0x0b,0x11,0xfb,0xa0,0x89,0xc0,0x68,0xe1,0xc1,0xea,0x17,0xa4,0xd0,0x5e,0xcf,0xb0,0xa9,0x76,0x31}; +static const uint8_t aad_20[] = {0x0b,0xae,0xd8,0xc0,0x67,0x18,0x69,0x7b,0x4e,0x84,0x5a,0xcb}; +static const uint8_t msg_20[] = {0x43,0x5e,0x10,0x1a,0x1a,0x44,0x16,0xab,0xe5,0xce}; +static const uint8_t ct_20[] = {0x1e,0xe7,0x89,0x1a,0xfb,0xc9,0x2d,0x52,0x28,0x2e,0xb3,0xfd,0xad,0xa6,0xf8,0x86,0xae,0x61,0x3f,0x6d,0x60,0xe5,0xd8,0xc1,0xa3,0xa6}; +static const uint8_t aad_21[] = {0x30,0x69,0x9d,0xc6,0xf4,0x97,0x21,0x5a,0xcd,0xa1,0x54,0x41}; +static const uint8_t msg_21[] = {0xcc,0xb3,0xe3,0xe1,0xbb,0xf6,0xc3,0xb0,0x3c,0x25,0x7b}; +static const uint8_t ct_21[] = {0xa7,0x8a,0x01,0x33,0x1b,0xb6,0xda,0x90,0x96,0x73,0x19,0x85,0x94,0x34,0xdb,0xfd,0xd2,0xf9,0xb9,0xc6,0x82,0x65,0xc1,0x90,0xe2,0x8b,0xa3}; +static const uint8_t aad_22[] = {0x16,0x44,0x00,0x93,0x60,0x32,0xde,0x67,0xa4,0x66,0x0b,0x87}; +static const uint8_t msg_22[] = {0x6c,0x9a,0x00,0x29,0xbf,0xc9,0x89,0x73,0x67,0x6d,0x42,0x08}; +static const uint8_t ct_22[] = {0x1a,0x10,0x4a,0x2d,0xe4,0x59,0xa3,0xaa,0x9f,0x7b,0x50,0x14,0x38,0xb1,0x20,0x60,0x2d,0xe2,0x7a,0x8d,0x25,0x9a,0xe4,0xf5,0x8e,0xf5,0x02,0x94}; +static const uint8_t aad_23[] = {0x00,0x90,0x02,0xfc,0xf1,0x32,0x82,0x0a,0xd3,0x83,0x89,0x38}; +static const uint8_t msg_23[] = {0x9e,0x98,0x13,0xcd,0x49,0x81,0x66,0x22,0x0b,0xd0,0xd4,0x9d,0xa9}; +static const uint8_t ct_23[] = {0x3d,0x81,0x75,0xb8,0x43,0x30,0x16,0x90,0x08,0x9b,0x8a,0xa5,0x41,0x36,0xd6,0x98,0xcc,0xd3,0xd8,0x8a,0x5d,0x02,0xa3,0xa6,0x5f,0x2b,0x11,0x5b,0x00}; +static const uint8_t aad_24[] = {0x52,0xdf,0xc3,0x2b,0xab,0x8b,0xc1,0x50,0x2d,0x18,0xa3,0x34}; +static const uint8_t msg_24[] = {0x2e,0x7a,0x1b,0x4c,0x80,0x8c,0x1c,0xf4,0xe6,0x4e,0x8c,0x5c,0xe5,0x4f}; +static const uint8_t ct_24[] = {0x9f,0xc0,0x42,0xa0,0x89,0x18,0x74,0x1e,0x2b,0x7b,0xea,0xb9,0xcd,0x79,0xd7,0x62,0x62,0x14,0xd8,0x96,0x00,0x91,0xcf,0x30,0x52,0x56,0xe5,0x49,0xee,0x36}; +static const uint8_t aad_25[] = {0x4d,0xbf,0x5c,0x20,0xce,0x4c,0xae,0xed,0xfe,0xfc,0xae,0x1d}; +static const uint8_t msg_25[] = {0xc9,0x65,0x96,0xeb,0xba,0x6f,0x89,0x76,0x1b,0x9d,0x14,0xdf,0xcc,0x8f,0xb4}; +static const uint8_t ct_25[] = {0x91,0xa7,0xf5,0xc4,0x58,0x53,0x51,0xb8,0xb7,0x6d,0x4a,0x48,0x36,0xa3,0x19,0x9a,0xa7,0x61,0xe5,0xf9,0xee,0x1c,0xdd,0x84,0x25,0x8a,0x6a,0x36,0x96,0xf7,0xe9}; +static const uint8_t aad_26[] = {0xa5,0xc2,0xf6,0xcf,0x30,0x9f,0x29,0xc2,0x5f,0x5c,0xe3,0x5d}; +static const uint8_t msg_26[] = {0xdb,0xcf,0x98,0x25,0x41,0x57,0x72,0x7c,0x35,0xf3,0x67,0xfe,0x6e,0x15,0xa2,0xd0,0x89}; +static const uint8_t ct_26[] = {0x96,0xbf,0x5d,0xd0,0xc2,0x8d,0xbd,0x60,0x72,0xb7,0x0e,0x2b,0x5b,0x72,0xd3,0xeb,0x9f,0x41,0xad,0xc6,0xd5,0xd8,0x77,0xe8,0x08,0xfb,0xf1,0x5e,0xd4,0x11,0x7b,0x50,0x07}; +static const uint8_t aad_27[] = {0xe4,0x0e,0x09,0xfe,0xa8,0x64,0x42,0xdc,0xf2,0xcd,0x17,0x6d}; +static const uint8_t msg_27[] = {0x3d,0xe2,0x18,0x65,0x21,0x7c,0x94,0xc4,0xf8,0x22,0x08,0xcc,0xd6,0x2a,0xd5,0x7f,0x13,0xba,0x1f,0x5e}; +static const uint8_t ct_27[] = {0xbe,0x36,0x6c,0xa7,0x6d,0x9a,0xfe,0x36,0xc7,0xd0,0x17,0xc1,0x22,0x1e,0x1b,0xe4,0x1a,0x59,0x4e,0x1d,0x85,0x35,0x74,0xc0,0x6d,0x23,0x57,0x75,0xb7,0x1c,0xc0,0xb5,0x6a,0x7d,0xa6,0x31}; +static const uint8_t aad_28[] = {0x34,0xea,0xfb,0x78,0x18,0x63,0xd8,0x56,0x49,0xf8,0xc9,0xb0}; +static const uint8_t msg_28[] = {0x8a,0x69,0xfb,0x2a,0xb5,0x3b,0x99,0x5d,0xaf,0x2c,0xd4,0x3f,0xc3,0x16,0x69,0x0f,0x71,0xe1,0x71,0xff,0xc5,0xab,0x84,0xf6,0x8b,0xae,0x3c,0x03,0x8a,0x9f,0xd7}; +static const uint8_t ct_28[] = {0x73,0xfb,0x50,0x1f,0x90,0x3d,0x90,0xc3,0x50,0x39,0xc0,0x65,0x56,0x3a,0x0b,0x8f,0x27,0x46,0x10,0xf0,0x5b,0x8d,0x98,0x8a,0x19,0x34,0x60,0x65,0x8d,0x32,0x5a,0x25,0x5e,0x80,0x88,0x47,0xf3,0xfa,0xf9,0x37,0xe0,0x35,0x4a,0x93,0x20,0x1a,0xb0}; +static const uint8_t aad_29[] = {0x46,0xa6,0x56,0x72,0xd2,0x69,0x92,0x67,0xab,0x27,0xda,0x82}; +static const uint8_t msg_29[] = {0x22,0x7e,0x71,0x4e,0x3e,0xfa,0x84,0xe4,0x80,0x49,0x14,0x2e,0xda,0xa3,0x11,0xda,0xb2,0x85,0x40,0x7f,0x9b,0x62,0x8b,0x14,0x6f,0x1d,0x61,0x32,0xc2,0x50,0x0c,0xa2,0x84,0x97,0xfb,0xd6,0xe3,0x86,0x67,0x9c}; +static const uint8_t ct_29[] = {0xb3,0x0e,0xc3,0xb9,0xc8,0x54,0x02,0xc3,0x56,0x72,0x83,0x91,0xac,0xf0,0x4f,0xcc,0x0d,0x02,0xba,0x85,0xb6,0xa9,0xe9,0x0c,0xf8,0x46,0x15,0x5d,0x4a,0xb3,0x15,0x89,0x52,0xbd,0x17,0x91,0x88,0x53,0x70,0xbf,0x23,0xba,0x26,0xd8,0xd2,0x33,0x59,0x63,0x7b,0x6e,0x24,0xe8,0x76,0x3e,0xd1,0x07}; +static const uint8_t aad_30[] = {0xed,0x9e,0xc5,0x61,0xec,0xf5,0xe2,0x89,0xa1,0x51,0x6c,0x9f}; +static const uint8_t msg_30[] = {0xf7,0x0e,0xf1,0x59,0x8f,0x40,0x39,0x02,0xdc,0xab,0x4c,0xc2,0x3b,0xb1,0x26,0x5f,0x34,0xe8,0x25,0xb9,0x9a,0xbc,0x61,0xb2,0x6a,0x22,0xb9,0xbb,0xf4,0x78,0xc3,0xc1,0xe6,0x1e,0x67,0xe9,0x82,0x01,0xbc,0x56,0x4d,0x02,0x2b,0x87,0xb4,0x10,0x6a,0xad,0x0c,0x4c,0xa2,0xd3,0x0e,0x89,0x27,0xfb,0xa5,0xb5,0x2a,0x76,0x97,0x1e,0xf7,0x9a,0x92,0xa1,0xeb,0x6c,0xf4,0xef,0x87,0xae,0xa6,0xb5,0x51,0x56,0x7a,0x2c,0x4c,0x41}; +static const uint8_t ct_30[] = {0xfa,0xfe,0xa5,0x5b,0xba,0x06,0x80,0xa5,0x10,0xce,0x09,0x5d,0x5c,0x8a,0x40,0xa8,0x4a,0x76,0x07,0x1b,0x89,0x38,0xdc,0xfe,0x99,0xc8,0xc7,0x3b,0x04,0x92,0x30,0xac,0x52,0xdf,0x7e,0x09,0x76,0x98,0x52,0xa6,0x05,0x73,0x53,0xa7,0xdf,0x7b,0x8d,0x18,0x88,0x2c,0xe5,0x36,0x9c,0x6b,0xb8,0x55,0xf2,0x71,0xd8,0x81,0x08,0x71,0x9a,0x1b,0x5e,0xa5,0x76,0x5f,0x54,0x9c,0x28,0x26,0x39,0xc8,0xbf,0xac,0xc3,0x4b,0x5b,0x10,0x99,0x1b,0x8f,0xbd,0xae,0x2e,0x42,0x42,0x9f,0xb7,0xf0,0x55,0x4e,0x0e,0x56,0x11}; +static const uint8_t msg_31[] = {0x1d,0x7f,0x9c,0xc8,0x1b,0x31,0x6c,0x51,0x8e,0xfc,0xd7,0x92,0x7e,0x8f,0x7b,0x88}; +static const uint8_t ct_31[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xdc,0xac,0x31,0x15,0xdd,0xbd,0x3d,0x8e,0xc2,0x88,0x22,0xe5,0x40,0x88,0xd0}; +static const uint8_t aad_32[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_32[] = {0xf1,0x6d,0x49,0x58,0xe9,0x33,0x77,0x8c,0x54,0xaa,0xbc,0xd6,0xfd,0xa1,0xca,0xbc}; +static const uint8_t ct_32[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0xce,0x79,0xa1,0xe7,0xdf,0xa6,0xe0,0x54,0x94,0xe3,0x66,0x66,0x6e,0x39,0xe4}; +static const uint8_t msg_33[] = {0x11,0x0d,0x3a,0xa6,0xf5,0x58,0xc3,0x09,0x77,0x87,0x06,0x72,0x80,0x40,0x64,0xe0}; +static const uint8_t ct_33[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0xf7,0x4b,0x8e,0x43,0xa2,0x62,0x00,0x1d,0x83,0x57,0xf9,0x54,0x89,0x43,0x2e}; +static const uint8_t aad_34[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_34[] = {0xfd,0x1f,0xef,0x36,0x07,0x5a,0xd8,0xd4,0xad,0xd1,0x6d,0x36,0x03,0x6e,0xd5,0xd4}; +static const uint8_t ct_34[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xed,0xe5,0x9e,0x1e,0xb1,0xa0,0x79,0xdd,0xc7,0xd5,0x3c,0xbd,0xd7,0xa7,0xf2,0x1a}; +static const uint8_t msg_35[] = {0xc8,0x3e,0x25,0x6b,0xa8,0xba,0xec,0x09,0x38,0xe5,0x1a,0x60,0xbd,0x81,0x9c,0xc1}; +static const uint8_t ct_35[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xd8,0xc4,0x54,0x43,0x1e,0x40,0x4d,0x00,0x52,0xe1,0x4b,0xeb,0x69,0x48,0xbb,0x0f}; +static const uint8_t aad_36[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_36[] = {0x24,0x2c,0xf0,0xfb,0x5a,0xb8,0xf7,0xd4,0xe2,0xb3,0x71,0x24,0x3e,0xaf,0x2d,0xf5}; +static const uint8_t ct_36[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0x34,0xd6,0x81,0xd3,0xec,0x42,0x56,0xdd,0x88,0xb7,0x20,0xaf,0xea,0x66,0x0a,0x3b}; +static const uint8_t msg_37[] = {0xd8,0xc8,0x9e,0x8e,0xce,0x83,0xde,0x43,0x7e,0xac,0x13,0xca,0x7b,0x1e,0xbb,0x2c}; +static const uint8_t ct_37[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc8,0x32,0xef,0xa6,0x78,0x79,0x7f,0x4a,0x14,0xa8,0x42,0x41,0xaf,0xd7,0x9c,0xe2}; +static const uint8_t aad_38[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_38[] = {0x34,0xda,0x4b,0x1e,0x3c,0x81,0xc5,0x9e,0xa4,0xfa,0x78,0x8e,0xf8,0x30,0x0a,0x18}; +static const uint8_t ct_38[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x24,0x20,0x3a,0x36,0x8a,0x7b,0x64,0x97,0xce,0xfe,0x29,0x05,0x2c,0xf9,0x2d,0xd6}; +static const uint8_t msg_39[] = {0xb0,0x76,0x68,0x7f,0x33,0x46,0x0a,0xf3,0x2b,0x7f,0x0e,0xdc,0x33,0x04,0xbf,0xff}; +static const uint8_t ct_39[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xe2,0x14,0x95,0x31,0x22,0x3f,0x57,0x03,0xd3,0xcc,0xe8,0x87,0xd0,0xdf,0xe5,0x44}; +static const uint8_t aad_40[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_40[] = {0x5c,0x64,0xbd,0xef,0xc1,0x44,0x11,0x2e,0xf1,0x29,0x65,0x98,0xb0,0x2a,0x0e,0xcb}; +static const uint8_t ct_40[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0e,0x06,0x40,0xa1,0xd0,0x3d,0x4c,0xde,0x09,0x9a,0x83,0xc3,0x53,0xf1,0x54,0x70}; +static const uint8_t ct_41[] = {0x65,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_42[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_42[] = {0x45,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_43[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_43[] = {0x61,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_44[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_44[] = {0x10,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_45[] = {0x66,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_46[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_46[] = {0x46,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_47[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_47[] = {0x62,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_48[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_48[] = {0x13,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_49[] = {0xe4,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_50[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_50[] = {0xc4,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_51[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_51[] = {0xe0,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_52[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_52[] = {0x91,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_53[] = {0x64,0x6b,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_54[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_54[] = {0x44,0xc1,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_55[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_55[] = {0x60,0xe9,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_56[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_56[] = {0x11,0xed,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_57[] = {0x64,0x6a,0x1c,0xbe,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_58[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_58[] = {0x44,0xc0,0xcc,0x89,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_59[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_59[] = {0x60,0xe8,0x02,0x17,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_60[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_60[] = {0x11,0xec,0xf9,0xf2,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_61[] = {0x64,0x6a,0x1c,0x3e,0xff,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_62[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_62[] = {0x44,0xc0,0xcc,0x09,0xb9,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_63[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_63[] = {0x60,0xe8,0x02,0x97,0xb1,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_64[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_64[] = {0x11,0xec,0xf9,0x72,0xc1,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_65[] = {0x64,0x6a,0x1c,0x3e,0xfc,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_66[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_66[] = {0x44,0xc0,0xcc,0x09,0xba,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_67[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_67[] = {0x60,0xe8,0x02,0x97,0xb2,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_68[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_68[] = {0x11,0xec,0xf9,0x72,0xc2,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_69[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0xd8,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_70[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_70[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0xb7,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_71[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_71[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0x45,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_72[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_72[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0xe5,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_73[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9a,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_74[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_74[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf9,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_75[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_75[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4f,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_76[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_76[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2f,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_77[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x1b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_78[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_78[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0x78,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_79[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_79[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0xce,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_80[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_80[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0xae,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_81[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xdd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_82[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_82[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x42,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_83[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_83[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xfa,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_84[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_84[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0x86,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_85[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd1,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_86[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_86[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6a,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_87[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_87[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x59,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_88[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_88[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xee,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_89[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2d,0xc8,0x69,0x23}; +static const uint8_t msg_90[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_90[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xdb,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_91[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_91[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x69,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_92[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_92[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3a,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_93[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2e,0xc8,0x69,0x23}; +static const uint8_t msg_94[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_94[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xd8,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_95[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_95[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x6a,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_96[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_96[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x39,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_97[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0xac,0xc8,0x69,0x23}; +static const uint8_t msg_98[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_98[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0x5a,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_99[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_99[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0xe8,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_100[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_100[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0xbb,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_101[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x22}; +static const uint8_t msg_102[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_102[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf2,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_103[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_103[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x33,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_104[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_104[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x22,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_105[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x21}; +static const uint8_t msg_106[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_106[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf1,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_107[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_107[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x30,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_108[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_108[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x21,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_109[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x63}; +static const uint8_t msg_110[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_110[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xb3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_111[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_111[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x72,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_112[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_112[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x63,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_113[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0xa3}; +static const uint8_t msg_114[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_114[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0x73,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_115[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_115[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0xb2,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_116[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_116[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0xa3,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_117[] = {0x65,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0x58,0x9a,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_118[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_118[] = {0x45,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0x37,0xf9,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_119[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_119[] = {0x61,0xe8,0x02,0x97,0xb0,0xba,0x41,0xc5,0x4f,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_120[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_120[] = {0x10,0xec,0xf9,0x72,0xc0,0x02,0x09,0x65,0x2f,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_121[] = {0x64,0x6a,0x1c,0xbe,0xfe,0xb7,0xd2,0xd8,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0x23}; +static const uint8_t msg_122[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_122[] = {0x44,0xc0,0xcc,0x89,0xb8,0xcc,0x0c,0xb7,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0xf3,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_123[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_123[] = {0x60,0xe8,0x02,0x17,0xb0,0xba,0x41,0x45,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0x32,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_124[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_124[] = {0x11,0xec,0xf9,0xf2,0xc0,0x02,0x09,0xe5,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0x23,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_125[] = {0x64,0x6a,0x1c,0x3e,0xfe,0xb7,0xd2,0xd8,0x9b,0xfd,0xd0,0x89,0x2c,0xc8,0x69,0xa3}; +static const uint8_t msg_126[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_126[] = {0x44,0xc0,0xcc,0x09,0xb8,0xcc,0x0c,0xb7,0xf8,0x62,0x6b,0x36,0xda,0xb9,0x5d,0x73,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_127[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_127[] = {0x60,0xe8,0x02,0x97,0xb0,0xba,0x41,0x45,0x4e,0xda,0x58,0xc4,0x68,0x50,0x2b,0xb2,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_128[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_128[] = {0x11,0xec,0xf9,0x72,0xc0,0x02,0x09,0xe5,0x2e,0xa6,0xef,0x4a,0x3b,0x46,0xea,0xa3,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_129[] = {0x9b,0x95,0xe3,0xc1,0x01,0x48,0x2d,0xa7,0x64,0x02,0x2f,0x76,0xd3,0x37,0x96,0xdc}; +static const uint8_t msg_130[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_130[] = {0xbb,0x3f,0x33,0xf6,0x47,0x33,0xf3,0xc8,0x07,0x9d,0x94,0xc9,0x25,0x46,0xa2,0x0c,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_131[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_131[] = {0x9f,0x17,0xfd,0x68,0x4f,0x45,0xbe,0x3a,0xb1,0x25,0xa7,0x3b,0x97,0xaf,0xd4,0xcd,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_132[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_132[] = {0xee,0x13,0x06,0x8d,0x3f,0xfd,0xf6,0x9a,0xd1,0x59,0x10,0xb5,0xc4,0xb9,0x15,0xdc,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_133[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static const uint8_t msg_134[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_134[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_135[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_135[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_136[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_136[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_137[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +static const uint8_t msg_138[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_138[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_139[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_139[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_140[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_140[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_141[] = {0xe4,0xea,0x9c,0xbe,0x7e,0x37,0x52,0xd8,0x1b,0x7d,0x50,0x09,0xac,0x48,0xe9,0xa3}; +static const uint8_t msg_142[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_142[] = {0xc4,0x40,0x4c,0x89,0x38,0x4c,0x8c,0xb7,0x78,0xe2,0xeb,0xb6,0x5a,0x39,0xdd,0x73,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_143[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_143[] = {0xe0,0x68,0x82,0x17,0x30,0x3a,0xc1,0x45,0xce,0x5a,0xd8,0x44,0xe8,0xd0,0xab,0xb2,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_144[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_144[] = {0x91,0x6c,0x79,0xf2,0x40,0x82,0x89,0xe5,0xae,0x26,0x6f,0xca,0xbb,0xc6,0x6a,0xa3,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_145[] = {0x65,0x6b,0x1d,0x3f,0xff,0xb6,0xd3,0x59,0x9a,0xfc,0xd1,0x88,0x2d,0xc9,0x68,0x22}; +static const uint8_t msg_146[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_146[] = {0x45,0xc1,0xcd,0x08,0xb9,0xcd,0x0d,0x36,0xf9,0x63,0x6a,0x37,0xdb,0xb8,0x5c,0xf2,0x2a,0xa0,0x3c,0xea,0xfa,0x0e,0x45,0xe6}; +static const uint8_t msg_147[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_147[] = {0x61,0xe9,0x03,0x96,0xb1,0xbb,0x40,0xc4,0x4f,0xdb,0x59,0xc5,0x69,0x51,0x2a,0x33,0xda,0x4e,0x0e,0xfa,0x57,0x35,0x2f,0x1a,0x11,0x4e,0x4b,0x3f,0x0c,0xb2,0x34,0xc6}; +static const uint8_t msg_148[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_148[] = {0x10,0xed,0xf8,0x73,0xc1,0x03,0x08,0x64,0x2f,0xa7,0xee,0x4b,0x3a,0x47,0xeb,0x22,0x59,0xe6,0xfa,0xeb,0xd6,0xaf,0x70,0x63,0xc8,0x66,0x03,0x62,0x86,0x6f,0x1b,0x2a,0xf5,0x3a,0x98,0x9e}; +static const uint8_t ct_149[] = {0x59,0xe0,0xa9,0xa0,0x4c,0xdb,0x1d,0x9d,0x7b,0xee,0x6b,0xe8,0xbb,0x06,0xfd,0x61}; +static const uint8_t aad_150[] = {0xb4,0x02,0xae,0x88,0x04,0x87,0xcf,0xaa,0x93,0x14,0x54,0x9b}; +static const uint8_t ct_150[] = {0xb5,0x0b,0xe5,0xe4,0x6a,0x39,0x12,0xdc,0xac,0xff,0x27,0x11,0x5e,0x20,0x9e,0x24}; +static const uint8_t aad_151[] = {0x3f,0x33,0xc7,0x81,0xea,0x57,0xec,0x1c,0x29,0x8f,0x40,0x2c,0xbb,0xd2,0x7e}; +static const uint8_t ct_151[] = {0x2a,0xec,0x07,0xdb,0x61,0xe8,0xe4,0x03,0xfa,0x04,0x65,0x99,0x21,0xcc,0xaf,0x65}; +static const uint8_t aad_152[] = {0xbd,0x2a,0xa0,0x7a,0x70,0xac,0xa6,0x9c,0x46,0x21,0xd9,0x1a,0x66,0x86,0xf4,0x2a}; +static const uint8_t ct_152[] = {0x86,0x31,0x61,0xc6,0x7e,0x86,0x64,0x83,0x40,0xfc,0x5e,0xab,0x9f,0xb7,0x28,0xa7}; +static const uint8_t aad_153[] = {0x9c,0xe5,0x88,0xda,0xa7,0x9d,0x68,0x25,0x30,0x5a,0x97,0x57,0x2d,0x27,0x67,0x4a,0x96,0x02,0xbf,0xeb}; +static const uint8_t ct_153[] = {0x4c,0x9c,0xb5,0x2e,0x91,0xee,0x8f,0xd7,0x84,0xe9,0x90,0x1b,0x2b,0xbf,0xd0,0x7e}; +static const uint8_t aad_154[] = {0x96,0x0d,0xba,0xaf,0xf3,0x75,0x10,0x15,0x29,0xf1,0x93,0xa5,0xb7,0xad,0xc2,0xcd,0x95,0xa3,0x6b,0x72,0x22,0xdf,0x7e,0x9f,0x6f,0xbf,0x31,0x10,0xe1,0x64,0x62,0xa1}; +static const uint8_t ct_154[] = {0xff,0xfc,0x48,0x6f,0x02,0x99,0x70,0x39,0x02,0x92,0x61,0x86,0xe4,0x39,0x32,0xd0}; +static const uint8_t aad_155[] = {0xd4,0xdb,0xfd,0xce,0x11,0xf1,0x14,0x7e,0x29,0xdd,0x06,0x2e,0xa3,0xbb,0xbd,0x17}; +static const uint8_t msg_155[] = {0xde,0xd5,0xa1,0x3d,0x75,0x99,0x03,0xec,0xd3,0x6c,0xb2,0x38,0x52,0x77,0x76,0xc6}; +static const uint8_t ct_155[] = {0xa4,0xe0,0x8b,0xdd,0x8a,0xb8,0xcb,0xef,0x46,0xe0,0xfd,0xb8,0xa7,0xca,0x10,0x97,0xa8,0xf9,0x63,0xe4,0x5e,0x55,0x4a,0x58,0x82,0x49,0x62,0x70,0xf9,0xfd,0x6d,0xe8}; +static const uint8_t aad_156[] = {0x2e,0x4b,0x50,0x22,0x12,0x84,0xbc,0x07,0xd7,0xe3,0x0b,0x1a,0x66,0x21,0x67,0x6d}; +static const uint8_t msg_156[] = {0xd0,0x53,0x54,0x03,0xfe,0xd2,0xc1,0xde,0xc9,0xf8,0x58,0xee,0xbd,0x68,0x8a,0xfe,0x4d,0x00,0x10,0xb2,0x82,0x32,0x75,0xd1,0xba,0xcf,0xd5,0x64,0xc0,0x74,0x41,0x5f}; +static const uint8_t ct_156[] = {0x01,0x31,0x70,0x5a,0x9a,0x6c,0x64,0x5f,0x13,0xfe,0x46,0x79,0xbd,0x03,0xda,0xac,0x23,0x4b,0xc1,0x1d,0xb1,0xf0,0x94,0x1b,0xe0,0x78,0x8c,0x1c,0x14,0xbb,0xf9,0x5e,0xf1,0xdb,0xfb,0xdf,0x5a,0xf7,0x86,0xa5,0xa5,0xa3,0xa7,0xd4,0xf3,0x5f,0xd1,0x69}; +static const uint8_t aad_157[] = {0x99,0x9a,0x35,0x70,0x55,0x30,0xc2,0xf6,0xa7,0xf2,0x42,0x7d,0x6b,0x25,0x88,0x36}; +static const uint8_t msg_157[] = {0xcd,0x9b,0xfe,0x98,0x21,0xb1,0xa5,0x89,0x57,0x37,0xa8,0x27,0xb4,0x1e,0x0e,0xe2,0x71,0xab,0x26,0x87,0x12,0x8b,0xb8,0x7f,0x17,0x37,0x09,0xb7,0x3b,0xf1,0x8c,0x7c,0x25,0x82,0x2f,0x32,0x28,0x28,0x95,0xca,0x89,0x35,0xdb,0x00,0xa1,0xd1,0x71,0xdb}; +static const uint8_t ct_157[] = {0xd2,0x37,0xa9,0xdd,0x9e,0xa0,0xf7,0x0e,0xbc,0x55,0x26,0xfd,0x5e,0x41,0x4f,0x31,0x8c,0x8a,0x01,0x6b,0xc6,0xec,0xbc,0xb3,0xde,0x5f,0x0a,0xff,0x93,0x30,0x25,0x9e,0x67,0xb4,0x98,0x4f,0x13,0xfb,0x7e,0x90,0x4a,0xe8,0xac,0x91,0xd8,0xe3,0x5f,0xaf,0x41,0xad,0x86,0x0b,0xc9,0x42,0x3d,0x2e,0xf5,0x96,0xc1,0x3e,0x15,0x02,0x5c,0xdf}; +static const uint8_t aad_158[] = {0x06,0xb2,0xcd,0x26,0x1a,0x35,0x08,0xa7,0xbf,0xd1,0xc0,0x49}; +static const uint8_t msg_158[] = {0x7e}; +static const uint8_t ct_158[] = {0x00,0x2a,0xbe,0xac,0x97,0x8f,0x66,0xd9,0x34,0xb9,0xed,0x06,0xf2,0x15,0xc4,0x95,0x1d}; +static const uint8_t aad_159[] = {0x90,0xf6,0x05,0xa2,0xcf,0x3f,0xf6,0xe7,0x9d,0x6a,0xd4,0xb9}; +static const uint8_t msg_159[] = {0x5b,0xff}; +static const uint8_t ct_159[] = {0xae,0x43,0xeb,0x59,0x49,0x4a,0x5f,0xe7,0xa7,0xca,0xc8,0xd5,0xd2,0x0f,0x7d,0x40,0x17,0x7f}; +static const uint8_t aad_160[] = {0x80,0x23,0x5b,0x12,0xc8,0x40,0xe3,0xfd,0x50,0xdc,0x62,0xfd}; +static const uint8_t msg_160[] = {0x8b,0x2a,0x68}; +static const uint8_t ct_160[] = {0x6b,0x8c,0x54,0xcd,0x6d,0x99,0xf5,0x47,0x0a,0x24,0x61,0xae,0xf6,0x14,0x01,0x2c,0xee,0x73,0x41}; +static const uint8_t aad_161[] = {0x43,0x63,0x4a,0x36,0x68,0xf7,0x8c,0x0b,0x00,0x59,0x71,0x66}; +static const uint8_t msg_161[] = {0x41,0xa1,0x24,0x1d}; +static const uint8_t ct_161[] = {0xad,0x0d,0x30,0x2a,0x32,0x2c,0xa7,0x3b,0x55,0x14,0xd8,0xcf,0xd6,0xd4,0x04,0x78,0xfc,0x60,0xae,0xe6}; +static const uint8_t aad_162[] = {0x26,0x30,0x6f,0x1d,0x6a,0x43,0x16,0x52,0x2a,0x92,0x87,0x15}; +static const uint8_t msg_162[] = {0x22,0xfa,0xba,0x30,0x76}; +static const uint8_t ct_162[] = {0x71,0x7e,0x9e,0x25,0x28,0x6a,0xc7,0xeb,0x4d,0x5a,0xa5,0x0e,0x61,0x30,0x46,0xc4,0x29,0x6f,0x69,0x3b,0xf4}; +static const uint8_t aad_163[] = {0x8f,0xf6,0x66,0x16,0x3c,0x2a,0xf9,0x9f,0x3e,0x65,0x3b,0x38}; +static const uint8_t msg_163[] = {0x2e,0xf9,0x0d,0x77,0xc7,0x25}; +static const uint8_t ct_163[] = {0xc1,0x11,0x78,0xfb,0x46,0xa4,0x33,0x4d,0xf8,0x04,0x4c,0xa1,0x74,0x6d,0xdd,0x12,0x9c,0xa6,0x18,0x5d,0x21,0xe1}; +static const uint8_t aad_164[] = {0xe5,0xcb,0x90,0x7e,0x8d,0xf4,0x2f,0x0e,0x56,0x8e,0x58,0x8a}; +static const uint8_t msg_164[] = {0x8f,0x1d,0xbf,0xb8,0xc9,0xdd,0x6a}; +static const uint8_t ct_164[] = {0x53,0x3f,0xa1,0x78,0x1a,0xf3,0xa3,0x67,0x9e,0x57,0x79,0xc9,0xc7,0xc7,0x27,0xfa,0x5a,0x1d,0x20,0xd7,0xa8,0x9f,0x6c}; +static const uint8_t aad_165[] = {0x82,0x5d,0x77,0x13,0x73,0xd6,0xe0,0x19,0x04,0x3d,0xd2,0xa0}; +static const uint8_t msg_165[] = {0x3d,0xa0,0x9c,0x27,0x59,0x06,0x83,0x5f}; +static const uint8_t ct_165[] = {0x05,0x28,0xc0,0x21,0x15,0x86,0x09,0xe0,0x7d,0x3c,0x71,0xfd,0x36,0x33,0x65,0xa6,0x44,0xca,0x61,0xb9,0x32,0xc1,0x61,0xba}; +static const uint8_t aad_166[] = {0x98,0x76,0x04,0xce,0xe2,0x9b,0x9e,0xe3,0x2f,0x26,0xf3,0x32}; +static const uint8_t msg_166[] = {0xcf,0x1e,0x93,0xa0,0x67,0xed,0x6b,0x4f,0x26}; +static const uint8_t ct_166[] = {0x4f,0x4d,0x35,0x33,0xc0,0xa6,0xd2,0x30,0x2c,0xc3,0xce,0x54,0x7c,0xa7,0x8f,0x1d,0x6d,0xce,0x6f,0x33,0x3c,0xca,0x0f,0xe8,0x89}; +static const uint8_t aad_167[] = {0x80,0xb9,0x53,0x4f,0x1e,0x83,0x59,0x82,0x35,0xc8,0x56,0x90}; +static const uint8_t msg_167[] = {0xb8,0x1c,0xc3,0xa3,0x82,0xa1,0xad,0x29,0xc1,0xdd}; +static const uint8_t ct_167[] = {0xc4,0xc9,0x7f,0x0c,0x35,0x30,0x98,0x1b,0xca,0xde,0x42,0xa1,0x74,0xa6,0x50,0x38,0xd8,0x92,0x5e,0xd8,0xa5,0xde,0xce,0xe8,0xa7,0xc6}; +static const uint8_t aad_168[] = {0x1b,0x7a,0x5c,0xe2,0xff,0x40,0x5b,0x01,0x91,0x25,0x91,0x0b}; +static const uint8_t msg_168[] = {0x96,0x2c,0x7c,0x7c,0xa5,0xbd,0xfc,0xbc,0xb3,0xeb,0xa4}; +static const uint8_t ct_168[] = {0x2d,0x60,0xae,0x19,0xa3,0x8f,0x40,0x0e,0x0e,0xd7,0x8b,0x65,0xdb,0x3d,0xf8,0x52,0xf4,0x1f,0x0d,0x1e,0x22,0xc9,0x17,0xb4,0x2e,0x7c,0x5a}; +static const uint8_t aad_169[] = {0xb5,0x5d,0x19,0x77,0x2f,0x27,0x76,0x77,0x2c,0x04,0x07,0x8a}; +static const uint8_t msg_169[] = {0x3c,0x32,0xca,0xfe,0xed,0xcc,0xe5,0x41,0x08,0xe3,0x95,0x88}; +static const uint8_t ct_169[] = {0xb9,0x72,0x90,0xf5,0xf2,0x25,0xd0,0x5b,0x40,0x70,0x4c,0x53,0xee,0x8f,0xdf,0xcf,0xfd,0x97,0x21,0x85,0xaa,0x96,0xd4,0xdb,0x4b,0x8d,0xdb,0x16}; +static const uint8_t aad_170[] = {0xb6,0x0c,0x69,0xa4,0xbe,0xfe,0xd3,0x9e,0xac,0x27,0x79,0x0b}; +static const uint8_t msg_170[] = {0x55,0x0d,0x0e,0x8b,0x83,0x73,0xa2,0x7e,0x40,0x72,0xa5,0xb7,0x6c}; +static const uint8_t ct_170[] = {0x0a,0xfe,0x67,0x5b,0x5b,0x92,0xfe,0xbd,0xdc,0x6b,0xd6,0xd4,0x50,0x71,0x5a,0xd4,0xda,0x97,0x71,0x1b,0xfb,0xf3,0x46,0x5d,0xa4,0x08,0x51,0x74,0x01}; +static const uint8_t aad_171[] = {0x29,0xd8,0x34,0xbc,0x7b,0xdd,0x2a,0x3e,0x95,0xae,0x83,0x08}; +static const uint8_t msg_171[] = {0xc9,0x69,0xbd,0x4b,0x5a,0xcf,0x1f,0x7b,0x50,0x0f,0x8f,0x21,0xf3,0xc9}; +static const uint8_t ct_171[] = {0x92,0xe1,0x43,0xe4,0x57,0xbe,0x47,0xa1,0x8c,0xa6,0x82,0x78,0x11,0x32,0x0c,0xe9,0xc7,0x0a,0x1b,0x4e,0x0e,0xf6,0x4c,0xf3,0x65,0x8b,0x25,0xcd,0x8f,0x51}; +static const uint8_t aad_172[] = {0xc3,0xf0,0xf5,0xc4,0x38,0xde,0x5f,0xd8,0x5b,0x7a,0x21,0xaf}; +static const uint8_t msg_172[] = {0xe8,0xd7,0xac,0x78,0xd2,0x80,0x5b,0xfd,0x65,0x66,0x34,0xd1,0x9b,0x58,0x34}; +static const uint8_t ct_172[] = {0x2e,0xea,0x01,0x15,0xc3,0x4a,0x46,0x1d,0x4d,0xe5,0xde,0x4a,0x41,0xb9,0x65,0x4b,0x8a,0xa8,0x7b,0x4c,0xc9,0x44,0xc0,0x50,0x57,0xf5,0xb3,0x06,0x94,0x2a,0x0f}; +static const uint8_t aad_173[] = {0xb4,0x9b,0x12,0xba,0x14,0x0f,0xa8,0xd7,0x94,0xa3,0x17,0x38}; +static const uint8_t msg_173[] = {0x34,0x06,0x12,0xda,0x2d,0x2d,0xbb,0xd2,0x5d,0x7f,0xa0,0x5c,0x77,0x5a,0x6e,0xcf,0xa8}; +static const uint8_t ct_173[] = {0xad,0xc7,0x24,0xb7,0xfa,0xbb,0xad,0x10,0x36,0xde,0xd1,0x52,0xb9,0x68,0xe5,0x57,0xa4,0xa1,0xb3,0xf5,0x01,0x4f,0x42,0xf8,0x4a,0x21,0xca,0x45,0x72,0x7f,0x4b,0x43,0x39}; +static const uint8_t aad_174[] = {0xb9,0x6c,0x86,0x82,0xcd,0x3c,0xe6,0x76,0xb0,0xd7,0x98,0x65}; +static const uint8_t msg_174[] = {0x14,0x85,0x12,0x6d,0x04,0x76,0xbb,0x4b,0x86,0xd0,0x87,0xd1,0x89,0x26,0x32,0xb5,0x3c,0xb4,0xf8,0xa2}; +static const uint8_t ct_174[] = {0x8f,0xd1,0x21,0x4e,0x80,0x78,0x2d,0x7c,0x14,0x00,0x7d,0x03,0x7f,0xeb,0x1a,0xb1,0x81,0xfd,0xcb,0x20,0x98,0x58,0x87,0xb5,0xee,0x8d,0x4a,0xcf,0x55,0x89,0x92,0x4b,0xe6,0x44,0x94,0x7d}; +static const uint8_t aad_175[] = {0x0f,0x1e,0xb4,0xee,0xe4,0x61,0x61,0x5b,0xc0,0xbe,0x84,0x74}; +static const uint8_t msg_175[] = {0x80,0xd9,0x77,0x96,0x5a,0x88,0x0b,0xc6,0xbb,0x5e,0x1c,0xc9,0x2f,0x23,0x47,0x71,0xad,0xb6,0x1e,0x7a,0xe7,0x19,0x88,0x44,0x62,0x3c,0x6b,0x1d,0x1b,0x54,0xec}; +static const uint8_t ct_175[] = {0x0d,0xa4,0xc7,0x88,0x5f,0xfc,0x41,0x25,0x87,0x8e,0xfe,0x1d,0x14,0xeb,0x5f,0x64,0x74,0x0b,0xca,0xed,0x91,0x50,0x88,0x80,0x6c,0x89,0xfb,0x2e,0xfd,0xde,0x2a,0x5b,0x0d,0x89,0xae,0xef,0x6a,0x23,0x24,0xba,0x26,0x26,0xb4,0x21,0x13,0xee,0x27}; +static const uint8_t aad_176[] = {0x7f,0xe4,0x97,0xba,0xcf,0x30,0xaf,0x3a,0x85,0x66,0x2a,0xa1}; +static const uint8_t msg_176[] = {0xb1,0xb1,0x97,0xcd,0x7f,0xf6,0x8b,0x62,0xe2,0x74,0xf5,0xd1,0x04,0x6f,0x42,0xf9,0x81,0x71,0x63,0xf0,0xa1,0x05,0xa0,0xfb,0x77,0x36,0xfa,0x9e,0x5e,0x8f,0x76,0x94,0x4a,0x22,0x28,0x2a,0xf4,0x80,0xee,0x79}; +static const uint8_t ct_176[] = {0xb4,0x40,0x39,0xf1,0xe5,0xba,0x80,0x8c,0xa0,0x55,0xae,0xa6,0xbc,0x2d,0x81,0x9d,0x38,0x8e,0x3c,0x27,0x1c,0xd9,0x7c,0x04,0x60,0x61,0xe5,0x72,0x23,0xbb,0xc2,0xa1,0x7a,0xa9,0xb3,0x68,0xd5,0xcf,0x28,0x1d,0xe4,0x6f,0x48,0xb3,0x4d,0x17,0x9c,0x16,0xcc,0x9e,0x9d,0x46,0x00,0xa8,0x7a,0xf4}; +static const uint8_t aad_177[] = {0x01,0x68,0x5c,0x58,0xb1,0x48,0x05,0xd6,0x36,0x54,0x11,0x79}; +static const uint8_t msg_177[] = {0x81,0xc8,0xa1,0x0f,0xcd,0x66,0x81,0x00,0xdc,0x76,0x21,0x25,0xe0,0x36,0x27,0xac,0x4e,0x68,0xd3,0x4c,0x72,0x56,0x8b,0xe4,0x38,0xa7,0xa0,0x68,0xc2,0x7e,0x2f,0x12,0xe2,0xf1,0x78,0x23,0xe4,0x1f,0xdd,0x13,0xe5,0x36,0x16,0xc6,0x22,0xd4,0xf3,0x20,0xa3,0x8f,0x97,0xc2,0xed,0xea,0xd9,0x80,0x0e,0xd1,0x09,0x1c,0x30,0x3f,0x10,0xd1,0x72,0xa2,0x84,0x28,0x4d,0x86,0x70,0x8e,0x53,0xde,0xdc,0x82,0xf6,0xa7,0x36,0x6b}; +static const uint8_t ct_177[] = {0xaa,0x3d,0x2c,0xd7,0x32,0x97,0x4b,0x73,0x35,0x97,0xa3,0x69,0xd4,0x7a,0x68,0x01,0x32,0xdd,0x5a,0x94,0x44,0x31,0x23,0x1e,0x6f,0x77,0x12,0x2d,0x40,0xae,0x70,0xc5,0xd0,0x32,0xcc,0x7d,0x62,0x20,0x8f,0x42,0x8e,0x6a,0x93,0x1c,0x7d,0xa6,0xe8,0x83,0x64,0xd5,0xce,0x1a,0x4d,0x94,0x03,0x43,0x67,0x40,0xb9,0xe7,0x14,0xa2,0xc3,0xb2,0x39,0xfe,0xbe,0x6a,0x6a,0x7b,0x42,0xf7,0x88,0x94,0x44,0x2c,0x91,0x2e,0x6a,0x9c,0x22,0xea,0x95,0x48,0xef,0x85,0x54,0x0c,0xa7,0x6d,0x7c,0x6d,0xf4,0x2b,0x65,0x34}; +static const uint8_t msg_178[] = {0x05,0xae,0x1d,0xed,0x78,0xb9,0x27,0xe7,0xbf,0x55,0x60,0x57,0x1e,0x17,0x77,0x60}; +static const uint8_t ct_178[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x46,0x0a,0xba,0x44,0xa6,0x80,0xfc,0x6c,0x77,0x6c,0x00,0xa1,0xe9,0x4b,0x6b}; +static const uint8_t aad_179[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_179[] = {0x11,0xa7,0xfa,0xe3,0xb1,0xb8,0x29,0x7b,0x31,0xbd,0xea,0x77,0xa8,0xd6,0xd6,0x7c}; +static const uint8_t ct_179[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x4f,0xed,0xb4,0x8d,0xa7,0x8e,0x60,0xe2,0x9f,0xe6,0x20,0x17,0x28,0xea,0x77}; +static const uint8_t msg_180[] = {0x3d,0xe1,0xfd,0x2f,0xf8,0xd5,0x26,0x00,0x05,0xed,0xbf,0x9b,0x59,0xb6,0xcf,0x06}; +static const uint8_t ct_180[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe8,0xa5,0x6d,0xba,0xe8,0x84,0xe9,0x90,0xcc,0x0d,0xf1,0x80,0xd5,0xe4,0x56,0xba}; +static const uint8_t aad_181[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_181[] = {0x29,0xe8,0x1a,0x21,0x31,0xd4,0x28,0x9c,0x8b,0x05,0x35,0xbb,0xef,0x77,0x6e,0x1a}; +static const uint8_t ct_181[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xac,0x8a,0xb4,0x21,0x85,0xe7,0x0c,0x42,0xe5,0x7b,0xa0,0x63,0x25,0xf7,0xa6}; +static const uint8_t msg_182[] = {0xb3,0xc7,0x5b,0x1d,0x29,0xb3,0xd5,0xd0,0x95,0x01,0xc4,0x29,0xc3,0xb8,0xfa,0xf2}; +static const uint8_t ct_182[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0x66,0x83,0xcb,0x88,0x39,0xe2,0x1a,0x40,0x5c,0xe1,0x8a,0x32,0x4f,0xea,0x63,0x4e}; +static const uint8_t aad_183[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_183[] = {0xa7,0xce,0xbc,0x13,0xe0,0xb2,0xdb,0x4c,0x1b,0xe9,0x4e,0x09,0x75,0x79,0x5b,0xee}; +static const uint8_t ct_183[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0x72,0x8a,0x2c,0x86,0xf0,0xe3,0x14,0xdc,0xd2,0x09,0x00,0x12,0xf9,0x2b,0xc2,0x52}; +static const uint8_t msg_184[] = {0x6a,0x14,0x2a,0x89,0x09,0xed,0x51,0xe7,0xb2,0xd7,0x7f,0xd0,0x71,0xf2,0x30,0xdf}; +static const uint8_t ct_184[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x50,0xba,0x1c,0x19,0xbc,0x9e,0x77,0x7b,0x37,0x31,0xcb,0xfd,0xa0,0xa9,0x63}; +static const uint8_t aad_185[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_185[] = {0x7e,0x1d,0xcd,0x87,0xc0,0xec,0x5f,0x7b,0x3c,0x3f,0xf5,0xf0,0xc7,0x33,0x91,0xc3}; +static const uint8_t ct_185[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xab,0x59,0x5d,0x12,0xd0,0xbd,0x90,0xeb,0xf5,0xdf,0xbb,0xeb,0x4b,0x61,0x08,0x7f}; +static const uint8_t msg_186[] = {0xe7,0x20,0x2a,0xbb,0xfe,0x6f,0xcf,0xfa,0x78,0x87,0xa7,0xef,0x06,0x84,0x00,0x40}; +static const uint8_t ct_186[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xa0,0xd0,0x32,0xef,0xc9,0x53,0x3b,0xf7,0xbb,0x8a,0xc7,0xaf,0x5c,0x9c,0x7c,0xdc}; +static const uint8_t aad_187[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_187[] = {0xf3,0x29,0xcd,0xb5,0x37,0x6e,0xc1,0x66,0xf6,0x6f,0x2d,0xcf,0xb0,0x45,0xa1,0x5c}; +static const uint8_t ct_187[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xb4,0xd9,0xd5,0xe1,0x00,0x52,0x35,0x6b,0x35,0x62,0x4d,0x8f,0xea,0x5d,0xdd,0xc0}; +static const uint8_t ct_188[] = {0xe9,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_189[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_189[] = {0xa3,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_190[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_190[] = {0xe9,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_191[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_191[] = {0xc2,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_192[] = {0xea,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_193[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_193[] = {0xa0,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_194[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_194[] = {0xea,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_195[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_195[] = {0xc1,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_196[] = {0x68,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_197[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_197[] = {0x22,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_198[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_198[] = {0x68,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_199[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_199[] = {0x43,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_200[] = {0xe8,0x4c,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_201[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_201[] = {0xa2,0x58,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_202[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_202[] = {0xe8,0x8f,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_203[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_203[] = {0xc3,0x58,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_204[] = {0xe8,0x4d,0xda,0x98,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_205[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_205[] = {0xa2,0x59,0x30,0xc8,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_206[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_206[] = {0xe8,0x8e,0xcb,0x80,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_207[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_207[] = {0xc3,0x59,0x76,0x80,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_208[] = {0xe8,0x4d,0xda,0x18,0xe8,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_209[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_209[] = {0xa2,0x59,0x30,0x48,0x78,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_210[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_210[] = {0xe8,0x8e,0xcb,0x00,0xad,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_211[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_211[] = {0xc3,0x59,0x76,0x00,0x02,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_212[] = {0xe8,0x4d,0xda,0x18,0xeb,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_213[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_213[] = {0xa2,0x59,0x30,0x48,0x7b,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_214[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_214[] = {0xe8,0x8e,0xcb,0x00,0xae,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_215[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_215[] = {0xc3,0x59,0x76,0x00,0x01,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_216[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x93,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_217[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_217[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x94,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_218[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_218[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0xac,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_219[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_219[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x99,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_220[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9d,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_221[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_221[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfc,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_222[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_222[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdd,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_223[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_223[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xad,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_224[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x1c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_225[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_225[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0x7d,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_226[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_226[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0x5c,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_227[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_227[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0x2c,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_228[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0x9d,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_229[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_229[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xd5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_230[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_230[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xc6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_231[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_231[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xf9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_232[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfc,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_233[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_233[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x21,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_234[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_234[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x25,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_235[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_235[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd3,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_236[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x70,0xd8,0xba,0xe0}; +static const uint8_t msg_237[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_237[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8c,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_238[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_238[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1a,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_239[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_239[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfb,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_240[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x73,0xd8,0xba,0xe0}; +static const uint8_t msg_241[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_241[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8f,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_242[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_242[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x19,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_243[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_243[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xf8,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_244[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0xf1,0xd8,0xba,0xe0}; +static const uint8_t msg_245[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_245[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x0d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_246[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_246[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x9b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_247[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_247[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0x7a,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_248[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe1}; +static const uint8_t msg_249[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_249[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf1,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_250[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_250[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe5,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_251[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_251[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x45,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_252[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe2}; +static const uint8_t msg_253[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_253[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf2,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_254[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_254[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe6,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_255[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_255[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x46,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_256[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xa0}; +static const uint8_t msg_257[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_257[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xb0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_258[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_258[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xa4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_259[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_259[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x04,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_260[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0x60}; +static const uint8_t msg_261[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_261[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0x70,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_262[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_262[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0x64,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_263[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_263[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0xc4,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_264[] = {0xe9,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x13,0x9d,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_265[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_265[] = {0xa3,0x59,0x30,0x48,0x79,0xd7,0x4e,0x14,0xfc,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_266[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_266[] = {0xe9,0x8e,0xcb,0x00,0xac,0x9a,0x46,0x2c,0xdd,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_267[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_267[] = {0xc2,0x59,0x76,0x00,0x03,0x21,0x13,0x19,0xad,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_268[] = {0xe8,0x4d,0xda,0x98,0xe9,0x8c,0xc8,0x93,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0xe0}; +static const uint8_t msg_269[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_269[] = {0xa2,0x59,0x30,0xc8,0x79,0xd7,0x4e,0x94,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0xf0,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_270[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_270[] = {0xe8,0x8e,0xcb,0x80,0xac,0x9a,0x46,0xac,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0xe4,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_271[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_271[] = {0xc3,0x59,0x76,0x80,0x03,0x21,0x13,0x99,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0x44,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_272[] = {0xe8,0x4d,0xda,0x18,0xe9,0x8c,0xc8,0x93,0x9c,0xbd,0xfd,0x22,0x71,0xd8,0xba,0x60}; +static const uint8_t msg_273[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_273[] = {0xa2,0x59,0x30,0x48,0x79,0xd7,0x4e,0x94,0xfd,0xf5,0x20,0x58,0x8d,0x38,0x88,0x70,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_274[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_274[] = {0xe8,0x8e,0xcb,0x00,0xac,0x9a,0x46,0xac,0xdc,0xe6,0x24,0x2b,0x1b,0x49,0x51,0x64,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_275[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_275[] = {0xc3,0x59,0x76,0x00,0x03,0x21,0x13,0x99,0xac,0xd9,0xd2,0xd8,0xfa,0x26,0x08,0xc4,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_276[] = {0x17,0xb2,0x25,0xe7,0x16,0x73,0x37,0xec,0x63,0x42,0x02,0xdd,0x8e,0x27,0x45,0x1f}; +static const uint8_t msg_277[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_277[] = {0x5d,0xa6,0xcf,0xb7,0x86,0x28,0xb1,0xeb,0x02,0x0a,0xdf,0xa7,0x72,0xc7,0x77,0x0f,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_278[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_278[] = {0x17,0x71,0x34,0xff,0x53,0x65,0xb9,0xd3,0x23,0x19,0xdb,0xd4,0xe4,0xb6,0xae,0x1b,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_279[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_279[] = {0x3c,0xa6,0x89,0xff,0xfc,0xde,0xec,0xe6,0x53,0x26,0x2d,0x27,0x05,0xd9,0xf7,0xbb,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_280[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static const uint8_t msg_281[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_281[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_282[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_282[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_283[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_283[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_284[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +static const uint8_t msg_285[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_285[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_286[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_286[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_287[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_287[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_288[] = {0x68,0xcd,0x5a,0x98,0x69,0x0c,0x48,0x93,0x1c,0x3d,0x7d,0xa2,0xf1,0x58,0x3a,0x60}; +static const uint8_t msg_289[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_289[] = {0x22,0xd9,0xb0,0xc8,0xf9,0x57,0xce,0x94,0x7d,0x75,0xa0,0xd8,0x0d,0xb8,0x08,0x70,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_290[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_290[] = {0x68,0x0e,0x4b,0x80,0x2c,0x1a,0xc6,0xac,0x5c,0x66,0xa4,0xab,0x9b,0xc9,0xd1,0x64,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_291[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_291[] = {0x43,0xd9,0xf6,0x80,0x83,0xa1,0x93,0x99,0x2c,0x59,0x52,0x58,0x7a,0xa6,0x88,0xc4,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_292[] = {0xe9,0x4c,0xdb,0x19,0xe8,0x8d,0xc9,0x12,0x9d,0xbc,0xfc,0x23,0x70,0xd9,0xbb,0xe1}; +static const uint8_t msg_293[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_293[] = {0xa3,0x58,0x31,0x49,0x78,0xd6,0x4f,0x15,0xfc,0xf4,0x21,0x59,0x8c,0x39,0x89,0xf1,0x7a,0xb3,0xdd,0x3c,0x6c,0x31,0xa3,0x86}; +static const uint8_t msg_294[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_294[] = {0xe9,0x8f,0xca,0x01,0xad,0x9b,0x47,0x2d,0xdd,0xe7,0x25,0x2a,0x1a,0x48,0x50,0xe5,0x73,0x8b,0x59,0x5a,0xeb,0xf6,0xee,0x3e,0x7b,0xe4,0x24,0xbf,0xb5,0x1b,0xfd,0xee}; +static const uint8_t msg_295[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_295[] = {0xc2,0x58,0x77,0x01,0x02,0x20,0x12,0x18,0xad,0xd8,0xd3,0xd9,0xfb,0x27,0x09,0x45,0x8b,0x0b,0x5d,0xf8,0x33,0x21,0x50,0xff,0x08,0x77,0xd8,0x54,0x71,0xd5,0x40,0xc4,0xcf,0xf1,0xe1,0x83}; +static const uint8_t ct_296[] = {0x44,0xb1,0xc6,0xfe,0x8a,0x8c,0x07,0xde,0xe5,0x37,0x7b,0x16,0x1f,0x28,0x3c,0x31}; +static const uint8_t aad_297[] = {0xd0,0xbb,0x29,0x49,0xa4,0x11,0xe2,0x2d,0x32,0x96,0x45,0x26}; +static const uint8_t ct_297[] = {0xe2,0x88,0xd8,0x02,0xa0,0xe5,0x6e,0xd7,0x54,0x4a,0x2e,0x57,0x75,0x45,0x93,0x89}; +static const uint8_t aad_298[] = {0x1d,0x5c,0xe9,0x28,0x86,0x27,0xa1,0x2f,0x8f,0x5d,0x80,0x91,0x67,0xa3,0xb2}; +static const uint8_t ct_298[] = {0xf8,0x08,0x3e,0x55,0x30,0x79,0x32,0xd9,0x71,0xbf,0xc2,0xa8,0x91,0x3c,0x19,0x51}; +static const uint8_t aad_299[] = {0x76,0xaa,0xde,0x95,0x96,0x4f,0x07,0x4c,0x69,0x38,0x86,0xf2,0x45,0xfa,0x57,0xf9}; +static const uint8_t ct_299[] = {0xf1,0xad,0x6e,0xa9,0x98,0xa2,0xa4,0x38,0xac,0xaf,0x90,0xba,0xd0,0xcb,0x9f,0x9f}; +static const uint8_t aad_300[] = {0x41,0x25,0x7d,0xa6,0x10,0x8b,0xed,0xbb,0x15,0x0d,0x4e,0x29,0x0b,0x6b,0x9a,0x76,0xd1,0x10,0x92,0xc6}; +static const uint8_t ct_300[] = {0xa8,0xd2,0x79,0x44,0xa8,0x43,0x17,0x09,0x8e,0xed,0x17,0x06,0x31,0xf4,0xc8,0x67}; +static const uint8_t aad_301[] = {0xe9,0x41,0xd1,0x5f,0xad,0xeb,0xaf,0x46,0x71,0xe0,0xe3,0xd6,0xd8,0x35,0xf8,0x7b,0xfb,0x1c,0xc7,0x02,0x8f,0x14,0x99,0x30,0xda,0xa6,0x9c,0x3d,0xe4,0x46,0xc4,0x23}; +static const uint8_t ct_301[] = {0xb7,0x54,0xec,0xb5,0x5c,0x1e,0x12,0x4d,0xe0,0xc8,0xa9,0x73,0xd0,0x33,0xbd,0x7f}; +static const uint8_t aad_302[] = {0xde,0xeb,0x0c,0xcf,0x3a,0xef,0x47,0xa2,0x96,0xed,0x1c,0xa8,0xf4,0xae,0x59,0x07}; +static const uint8_t msg_302[] = {0xbe,0xec,0x61,0x03,0x0f,0xa3,0xd6,0x70,0x33,0x71,0x96,0xbe,0xad,0xe6,0xae,0xaa}; +static const uint8_t ct_302[] = {0x58,0x65,0x20,0x8e,0xab,0x91,0x63,0xdb,0x85,0xca,0xb9,0xf9,0x6d,0x84,0x62,0x34,0xa2,0x62,0x6a,0xae,0x22,0xf5,0xc1,0x7c,0x9a,0xad,0x4b,0x50,0x1f,0x44,0x16,0xe4}; +static const uint8_t aad_303[] = {0xcc,0x94,0xf6,0x4e,0x14,0xdf,0x90,0x26,0x5f,0x7f,0x12,0xa8,0xa0,0x38,0x6d,0x0a}; +static const uint8_t msg_303[] = {0x6b,0x1d,0xb0,0xf5,0xa4,0x33,0x76,0x88,0x50,0x02,0xdc,0x98,0xbd,0x55,0x6f,0x1d,0xac,0x9b,0x66,0xb6,0x62,0x13,0xa9,0xfa,0x60,0x69,0xdf,0x99,0x5a,0x12,0x33,0x84}; +static const uint8_t ct_303[] = {0xd0,0x01,0x6d,0x67,0x5b,0x49,0xf1,0x1e,0xa8,0x73,0x70,0x74,0x12,0xd4,0x57,0x09,0xb7,0x70,0x3a,0x02,0x8a,0x0c,0xfc,0x31,0x2c,0xf6,0x1c,0xbe,0x22,0xb9,0x1e,0x3c,0xf2,0x0b,0x7d,0x4c,0x93,0x08,0xee,0x15,0xf1,0x8b,0x4e,0xba,0x00,0x88,0x92,0x84}; +static const uint8_t aad_304[] = {0x1c,0xda,0x34,0x2c,0x16,0x6e,0xa2,0x08,0xdf,0x5c,0x56,0xbc,0xf9,0x95,0xa5,0x9b}; +static const uint8_t msg_304[] = {0x48,0xef,0x10,0xcc,0xb1,0x97,0x8b,0x53,0xae,0x73,0x16,0x7a,0xbe,0x1c,0xc5,0x38,0xfa,0x80,0xda,0x3f,0x5d,0xf9,0x3e,0x3d,0x5c,0x4e,0x9a,0x9a,0xd1,0xf2,0x13,0x50,0x4f,0x22,0xa6,0x94,0xb9,0x8a,0x35,0xad,0x67,0x62,0x0a,0xf9,0xd8,0xa2,0x9f,0xc7}; +static const uint8_t ct_304[] = {0xd5,0x5c,0x5d,0x0a,0xf0,0x26,0x0d,0xc1,0x12,0x3a,0xdb,0x5d,0x78,0x69,0x20,0x1f,0x8c,0xce,0xe4,0x6d,0xeb,0x66,0xdd,0x69,0x5c,0x59,0x3c,0xde,0x1d,0x76,0x45,0xc7,0x27,0x96,0xe4,0x2a,0x17,0x33,0xb6,0x70,0x57,0x53,0x63,0x1b,0x9b,0x62,0x69,0x91,0xdd,0xbd,0x28,0x47,0x3c,0xe7,0x5c,0xfd,0xc4,0xc1,0x4d,0x20,0xe6,0x6f,0x21,0x2d}; +static const uint8_t aad_305[] = {0xfa,0xb9,0x12,0xde,0xc2,0x9a,0x34,0xaa,0xbf,0xae,0xf1,0x76}; +static const uint8_t msg_305[] = {0x0d}; +static const uint8_t ct_305[] = {0x1c,0x69,0x69,0xec,0xb1,0x57,0x41,0xa9,0x95,0x9b,0x7a,0x84,0x92,0x25,0x0e,0x39,0x1a}; +static const uint8_t aad_306[] = {0xe8,0x60,0x5f,0x13,0xdb,0x8c,0x48,0x2d,0x48,0xbd,0xba,0x2d}; +static const uint8_t msg_306[] = {0x5c,0x6f}; +static const uint8_t ct_306[] = {0xfd,0xde,0xa9,0xac,0x77,0x8b,0x97,0x8a,0x96,0x80,0x33,0xce,0x52,0xec,0x61,0x16,0x25,0x88}; +static const uint8_t aad_307[] = {0x7f,0x89,0xa3,0xf6,0x48,0xc1,0xc7,0xc2,0x3e,0xdb,0xd5,0xca}; +static const uint8_t msg_307[] = {0x35,0xac,0x33}; +static const uint8_t ct_307[] = {0x38,0x34,0xfb,0xed,0xc3,0x50,0x22,0x27,0xe3,0xc9,0x1a,0x86,0x1f,0x2e,0x31,0x95,0xfb,0xb3,0x44}; +static const uint8_t aad_308[] = {0xc2,0xb7,0x5c,0x99,0x8f,0x4c,0xac,0x28,0xb4,0xb6,0x9d,0xfb}; +static const uint8_t msg_308[] = {0x1d,0x25,0xf8,0x33}; +static const uint8_t ct_308[] = {0x0d,0x1e,0x19,0x81,0xda,0x44,0xa7,0xd9,0xed,0xa6,0x0e,0x48,0xe7,0xae,0x4f,0x85,0x05,0xd8,0xba,0x98}; +static const uint8_t aad_309[] = {0xf5,0x04,0x2d,0x5a,0x5b,0x68,0xb2,0x62,0x27,0x49,0x74,0xa8}; +static const uint8_t msg_309[] = {0x9e,0x99,0x91,0x2c,0x7b}; +static const uint8_t ct_309[] = {0x65,0x5e,0xf7,0xf0,0x9f,0x4c,0xff,0x47,0xb4,0x27,0xe9,0xdf,0x7f,0xcc,0x64,0x26,0x64,0x71,0x5a,0xd1,0x4c}; +static const uint8_t aad_310[] = {0x75,0x5f,0x50,0xcf,0xdf,0xc8,0x49,0x65,0x4a,0xd9,0x8c,0xc7}; +static const uint8_t msg_310[] = {0xac,0x59,0x87,0x20,0xb9,0x6e}; +static const uint8_t ct_310[] = {0xad,0xee,0x2a,0x37,0x3a,0x7f,0x6b,0xba,0xf4,0xf0,0x0e,0x5f,0x3f,0x93,0x43,0x5a,0x09,0x09,0x1b,0x52,0x21,0xae}; +static const uint8_t aad_311[] = {0xf8,0x79,0x9b,0xc7,0x32,0xcb,0xf6,0xa3,0x9a,0xe2,0x26,0x8e}; +static const uint8_t msg_311[] = {0x8f,0x6b,0x2b,0x21,0xa6,0xdc,0x73}; +static const uint8_t ct_311[] = {0xff,0x61,0x73,0xa7,0x0d,0xee,0x05,0xdd,0xbd,0xe7,0x5a,0x96,0x0f,0x84,0x52,0x3e,0x01,0xb3,0x0a,0xdc,0xac,0x52,0x75}; +static const uint8_t aad_312[] = {0x7a,0x5d,0xbd,0xbf,0x80,0x3b,0x25,0x93,0xd3,0xe1,0x70,0x97}; +static const uint8_t msg_312[] = {0xde,0xb2,0xc7,0xc6,0x20,0x44,0x96,0xe5}; +static const uint8_t ct_312[] = {0x2f,0x8b,0x75,0x83,0x77,0x3a,0xe0,0x3b,0xa7,0xb3,0x95,0x24,0x53,0xc8,0x14,0x31,0x78,0x0b,0xfc,0xc9,0xd7,0xdf,0x9a,0x43}; +static const uint8_t aad_313[] = {0xe4,0x82,0xe9,0x42,0xce,0x26,0xd2,0x44,0xd4,0x96,0x2a,0xcf}; +static const uint8_t msg_313[] = {0x12,0x2d,0x1b,0xa3,0x94,0xaf,0xad,0x1f,0xe3}; +static const uint8_t ct_313[] = {0x81,0x85,0xd1,0x4e,0xe8,0x7c,0xc8,0x91,0xbb,0x9b,0xcf,0x3f,0xaf,0xde,0x4e,0xd2,0x46,0x59,0x96,0x26,0x21,0x1f,0xe0,0x4d,0x23}; +static const uint8_t aad_314[] = {0x89,0xf9,0x52,0x50,0xfb,0x66,0xb2,0xcd,0xa7,0x0b,0x88,0x54}; +static const uint8_t msg_314[] = {0x9c,0xab,0x7b,0xde,0x92,0x63,0x07,0x38,0x65,0x05}; +static const uint8_t ct_314[] = {0xc4,0xde,0xca,0x5c,0x53,0xbc,0xfa,0x62,0x08,0xb3,0x37,0x47,0x42,0x12,0x41,0x85,0x41,0xe4,0x4d,0x0f,0xbf,0x2d,0xe7,0xb4,0x8c,0x6f}; +static const uint8_t aad_315[] = {0x5c,0x36,0x61,0xf4,0x04,0x74,0x54,0xba,0xc4,0x45,0xf1,0xac}; +static const uint8_t msg_315[] = {0x08,0xeb,0x0a,0x19,0x6e,0x8f,0x3c,0xb6,0x42,0x8b,0x0a}; +static const uint8_t ct_315[] = {0x67,0x67,0x30,0x64,0xfc,0x54,0x0a,0xe1,0x28,0x23,0x2b,0xa8,0x7b,0xa2,0xe9,0xbb,0xe7,0xd3,0x56,0x9d,0xd4,0x19,0xbc,0xc5,0x27,0x96,0xec}; +static const uint8_t aad_316[] = {0x7b,0x3f,0x95,0x91,0x07,0x6e,0x32,0xa2,0x17,0x66,0xe2,0xbb}; +static const uint8_t msg_316[] = {0x06,0x28,0xd1,0x9c,0xc9,0x4c,0x4b,0x4f,0x3d,0x70,0x3e,0x1f}; +static const uint8_t ct_316[] = {0x56,0xe6,0xfd,0x5a,0x7f,0x44,0x9a,0x8e,0x6b,0xaf,0xa3,0x8f,0x94,0x5c,0x70,0xcf,0x8a,0x53,0x41,0x79,0xb3,0xb1,0xf2,0x62,0x66,0xfb,0x6b,0x56}; +static const uint8_t aad_317[] = {0xa3,0xc4,0xe3,0x87,0xbf,0xc0,0x05,0x40,0x2a,0xcd,0x20,0xbb}; +static const uint8_t msg_317[] = {0xa1,0x71,0x37,0x6f,0x2a,0x66,0xdb,0xdf,0x17,0xf3,0x29,0x61,0xe8}; +static const uint8_t ct_317[] = {0x4e,0x7b,0x64,0x2d,0xcc,0x3c,0xbd,0x93,0x5d,0x4c,0xda,0x81,0x93,0x98,0x2e,0xf7,0x24,0x0f,0xa4,0x7f,0x95,0x1e,0xc8,0xb3,0xfd,0x37,0x20,0x4a,0x73}; +static const uint8_t aad_318[] = {0x89,0x0d,0xce,0xa8,0x71,0xda,0x1c,0xaf,0xf4,0x76,0x6d,0x32}; +static const uint8_t msg_318[] = {0x6a,0xd3,0x48,0x47,0x08,0x91,0xd1,0xba,0xbb,0x13,0xf3,0xbf,0x0e,0x8c}; +static const uint8_t ct_318[] = {0xfb,0xb6,0x83,0x24,0xb8,0xc5,0xb3,0xe5,0x5e,0xbc,0x1f,0xeb,0x4b,0x98,0x76,0x15,0x21,0xf4,0xaa,0xc7,0xeb,0x7b,0x6c,0x0f,0xb0,0x50,0x5a,0x08,0x45,0x7b}; +static const uint8_t aad_319[] = {0x6a,0xe5,0x4f,0x41,0xac,0x52,0xba,0xf2,0xf8,0x9a,0xbe,0x8e}; +static const uint8_t msg_319[] = {0x3f,0xc3,0xbf,0x53,0xbb,0x48,0x5c,0x9e,0xdc,0xb1,0xd2,0x5a,0xdb,0x4c,0xa0}; +static const uint8_t ct_319[] = {0x2d,0x34,0x4a,0x54,0x03,0x8a,0x85,0x7f,0x47,0xe0,0xc7,0x7e,0xb0,0x83,0x45,0x38,0xaa,0xf0,0x1e,0x61,0xa8,0xac,0x82,0xc0,0x01,0x2f,0x9d,0xac,0x6f,0x15,0xef}; +static const uint8_t aad_320[] = {0xd3,0x9d,0xa7,0x3f,0xfc,0x03,0xad,0x0a,0x92,0x13,0xff,0xc7}; +static const uint8_t msg_320[] = {0x48,0x60,0x49,0x44,0xa8,0x0f,0xad,0xf5,0x0d,0x55,0xb8,0x77,0x27,0x93,0x44,0x58,0xc8}; +static const uint8_t ct_320[] = {0xa9,0xcf,0x73,0x95,0x1c,0xb3,0x98,0x23,0x77,0x7f,0x35,0xc9,0x6c,0x84,0x51,0x69,0x47,0x6e,0x2e,0xc2,0x31,0x7c,0xb6,0xb8,0xdd,0x8b,0x61,0x72,0xfd,0xce,0xab,0xff,0x9d}; +static const uint8_t aad_321[] = {0x29,0xd6,0x14,0xf9,0x08,0x59,0x3f,0x6a,0x5a,0xb0,0x3c,0xea}; +static const uint8_t msg_321[] = {0x0c,0x22,0xe4,0x87,0x5d,0xcd,0x23,0xde,0x89,0xa6,0xd3,0x2f,0x20,0x82,0xdd,0x40,0xe1,0x84,0x8f,0xc2}; +static const uint8_t ct_321[] = {0xbc,0xe8,0x86,0x62,0x3d,0x11,0x32,0x0d,0x22,0xdf,0xdc,0x1d,0xef,0xb0,0x4d,0x17,0xbd,0x00,0x1d,0x93,0x70,0xa3,0xd8,0xc8,0x3a,0xab,0xe4,0x49,0x4d,0x16,0xca,0x75,0xce,0x53,0x4f,0x7c}; +static const uint8_t aad_322[] = {0xb4,0x11,0xe4,0xd2,0xfa,0xcc,0xa6,0x7e,0xa4,0xa9,0xf2,0xa1}; +static const uint8_t msg_322[] = {0x2f,0x35,0x8d,0x45,0x34,0x55,0x9a,0xc9,0x9d,0xd7,0x17,0x98,0xb7,0x92,0x57,0x05,0xd6,0xf0,0x13,0xf6,0xb8,0x48,0xff,0xe0,0x1c,0xc8,0x6c,0xef,0x09,0xd8,0x8f}; +static const uint8_t ct_322[] = {0xd2,0x7a,0xe2,0x6d,0xfe,0x02,0xe3,0xee,0xdf,0x54,0x4e,0x1b,0x45,0x2c,0xb0,0xf0,0xc9,0x30,0x3a,0x4e,0x48,0x19,0x31,0x83,0x15,0xae,0x08,0x83,0x9b,0xcc,0xe5,0x58,0xe4,0x74,0x18,0x17,0xec,0x08,0xda,0xe4,0x06,0xbb,0xfc,0x09,0xf5,0x9a,0xa9}; +static const uint8_t aad_323[] = {0xb3,0xed,0xff,0xbb,0x89,0xb3,0x73,0xfe,0x04,0xda,0x24,0x4b}; +static const uint8_t msg_323[] = {0xeb,0xcf,0xb2,0xff,0xb6,0x81,0xcc,0x5d,0xfa,0x0c,0x5c,0x52,0x4c,0x1b,0x1c,0xc8,0x7c,0xc6,0xb2,0xbf,0xa3,0x5d,0xc3,0x6d,0x15,0xe8,0x05,0x05,0x11,0x8b,0x84,0xa0,0x72,0xa7,0x8a,0x15,0x7b,0x4d,0x18,0x37}; +static const uint8_t ct_323[] = {0x1a,0xc7,0x8a,0xae,0x2e,0xde,0x04,0xeb,0x47,0x92,0x4d,0x8f,0x9f,0x99,0xfe,0x75,0xde,0xb6,0x1b,0xf6,0x93,0xda,0x7f,0x3a,0x21,0x47,0xc0,0x5f,0x6d,0x29,0xd1,0x73,0x92,0x35,0x6f,0xe0,0x0f,0x82,0xb2,0x4c,0xdb,0xce,0x77,0x4f,0xd8,0x64,0x56,0x15,0x48,0xf3,0x3d,0xd3,0x19,0x2d,0x80,0x6f}; +static const uint8_t aad_324[] = {0x6a,0x8a,0xaf,0x2c,0x84,0x00,0x3e,0x0e,0x6f,0x40,0x96,0x58}; +static const uint8_t msg_324[] = {0x92,0xd8,0xf4,0xdc,0x7d,0x41,0xe8,0xb1,0x80,0xd6,0x6e,0x89,0x94,0x02,0x2d,0xb7,0x92,0x49,0xcd,0xc7,0x6f,0xd7,0xf3,0xea,0x12,0xd9,0x92,0x5b,0x51,0x92,0x52,0x50,0xcd,0x75,0xa1,0x5f,0xcf,0xd7,0x8e,0xa8,0x5c,0x57,0xfe,0x61,0x96,0xf8,0xd7,0x54,0x50,0x86,0xf9,0x9e,0xa7,0x96,0xa0,0xea,0x69,0x17,0x0d,0xb9,0x94,0x42,0x00,0x43,0x5d,0x9d,0x3d,0x55,0x19,0x43,0x89,0x24,0x00,0xce,0x78,0x7f,0x70,0x3c,0x11,0x05}; +static const uint8_t ct_324[] = {0x69,0xf7,0x20,0xf3,0x6b,0x0d,0xa8,0x6e,0xc8,0xcc,0x0f,0x46,0xd6,0x28,0x35,0xdc,0xb3,0x5a,0xc2,0x3f,0x5b,0x89,0x11,0x52,0xd8,0x61,0xc4,0xe0,0xf0,0x01,0x8f,0x19,0xd2,0x72,0xee,0x8b,0x12,0xd8,0x33,0x00,0xbf,0xd4,0x6a,0xee,0xc0,0x12,0x4d,0x5d,0x23,0xb3,0xcb,0x84,0x9c,0x1c,0xab,0x1f,0xdf,0x64,0xb7,0x09,0x47,0xeb,0xf7,0x9f,0x54,0x42,0xe2,0x09,0x07,0x6d,0xfa,0x9a,0x3f,0x36,0xab,0x0a,0x6d,0x3c,0xf4,0xa7,0x5d,0xdf,0xcd,0xc2,0x18,0x37,0x74,0x3b,0x20,0x88,0x5d,0xb4,0xc8,0x03,0xac,0x27}; +static const uint8_t msg_325[] = {0x8d,0xbf,0xee,0x95,0x80,0xe7,0xe2,0xbc,0x66,0x10,0x0a,0x67,0x44,0x97,0xf4,0xe1}; +static const uint8_t ct_325[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0xf8,0xaa,0x7e,0x4d,0xd4,0x9d,0x9c,0xfa,0x09,0xe9,0xcb,0x57,0x4f,0xd9,0x0d}; +static const uint8_t aad_326[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_326[] = {0xbf,0xa1,0x73,0x3d,0x07,0xaf,0xa0,0x3c,0xb3,0xf2,0xee,0xb8,0x1b,0xbd,0xe0,0x37}; +static const uint8_t ct_326[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0xe6,0x37,0xd6,0xca,0x9c,0xdf,0x1c,0x2f,0xeb,0x0d,0x14,0x08,0x65,0xcd,0xdb}; +static const uint8_t msg_327[] = {0x72,0x54,0x3a,0x9a,0x07,0xa3,0xc1,0x8a,0x28,0x00,0x60,0x65,0x34,0x32,0xc0,0x5c}; +static const uint8_t ct_327[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3d,0xb0,0x9c,0xc4,0x8f,0x27,0x80,0x85,0x93,0x51,0x90,0x1d,0x10,0x14,0xae,0x06}; +static const uint8_t aad_328[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_328[] = {0x40,0x4a,0xa7,0x32,0x80,0xeb,0x83,0x0a,0xfd,0xe2,0x84,0xba,0x6b,0x18,0xd4,0x8a}; +static const uint8_t ct_328[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xae,0x01,0x6c,0x08,0x6f,0xc2,0x05,0x46,0xb3,0x74,0xc2,0x4f,0x3e,0xba,0xd0}; +static const uint8_t msg_329[] = {0xff,0x4d,0x7c,0xde,0xb8,0xf3,0xc4,0xe3,0x7a,0x05,0xa9,0x1e,0xe2,0x6e,0x2a,0x84}; +static const uint8_t ct_329[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xb0,0xa9,0xda,0x80,0x30,0x77,0x85,0xec,0xc1,0x54,0x59,0x66,0xc6,0x48,0x44,0xde}; +static const uint8_t aad_330[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_330[] = {0xcd,0x53,0xe1,0x76,0x3f,0xbb,0x86,0x63,0xaf,0xe7,0x4d,0xc1,0xbd,0x44,0x3e,0x52}; +static const uint8_t ct_330[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0x82,0xb7,0x47,0x28,0xb7,0x3f,0xc7,0x6c,0x14,0xb6,0xbd,0xb9,0x99,0x62,0x50,0x08}; +static const uint8_t msg_331[] = {0x6e,0xb5,0x2f,0xc9,0x5a,0x51,0x85,0xa3,0xbd,0x2a,0x30,0xd3,0x05,0x84,0x14,0xab}; +static const uint8_t ct_331[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x21,0x51,0x89,0x97,0xd2,0xd5,0xc4,0xac,0x06,0x7b,0xc0,0xab,0x21,0xa2,0x7a,0xf1}; +static const uint8_t aad_332[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_332[] = {0x5c,0xab,0xb2,0x61,0xdd,0x19,0xc7,0x23,0x68,0xc8,0xd4,0x0c,0x5a,0xae,0x00,0x7d}; +static const uint8_t ct_332[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x13,0x4f,0x14,0x3f,0x55,0x9d,0x86,0x2c,0xd3,0x99,0x24,0x74,0x7e,0x88,0x6e,0x27}; +static const uint8_t msg_333[] = {0x11,0x4c,0xc3,0x6e,0x58,0xfa,0xce,0xb2,0xe6,0xa2,0x34,0x4a,0x67,0x9e,0xa4,0xc3}; +static const uint8_t ct_333[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x2f,0x84,0x96,0x50,0xd6,0xe8,0x9e,0x26,0x68,0xe9,0x90,0x21,0x91,0x95,0x71,0x9c}; +static const uint8_t aad_334[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; +static const uint8_t msg_334[] = {0x23,0x52,0x5e,0xc6,0xdf,0xb2,0x8c,0x32,0x33,0x40,0xd0,0x95,0x38,0xb4,0xb0,0x15}; +static const uint8_t ct_334[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x1d,0x9a,0x0b,0xf8,0x51,0xa0,0xdc,0xa6,0xbd,0x0b,0x74,0xfe,0xce,0xbf,0x65,0x4a}; +static const uint8_t ct_335[] = {0x6e,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_336[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_336[] = {0x20,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_337[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_337[] = {0x05,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_338[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_338[] = {0x31,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_339[] = {0x6d,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_340[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_340[] = {0x23,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_341[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_341[] = {0x06,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_342[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_342[] = {0x32,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_343[] = {0xef,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_344[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_344[] = {0xa1,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_345[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_345[] = {0x84,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_346[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_346[] = {0xb0,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_347[] = {0x6f,0xf4,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_348[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_348[] = {0x21,0x2f,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_349[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_349[] = {0x04,0xb5,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_350[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_350[] = {0x30,0x5c,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_351[] = {0x6f,0xf5,0xb8,0x6f,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_352[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_352[] = {0x21,0x2e,0x4a,0x0f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_353[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_353[] = {0x04,0xb4,0xe8,0x96,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_354[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_354[] = {0x30,0x5d,0x6c,0x78,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_355[] = {0x6f,0xf5,0xb8,0xef,0x52,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_356[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_356[] = {0x21,0x2e,0x4a,0x8f,0x8a,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_357[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_357[] = {0x04,0xb4,0xe8,0x16,0x6e,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_358[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_358[] = {0x30,0x5d,0x6c,0xf8,0xef,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_359[] = {0x6f,0xf5,0xb8,0xef,0x51,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_360[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_360[] = {0x21,0x2e,0x4a,0x8f,0x89,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_361[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_361[] = {0x04,0xb4,0xe8,0x16,0x6d,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_362[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_362[] = {0x30,0x5d,0x6c,0xf8,0xec,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_363[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0xd6,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_364[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_364[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0xf8,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_365[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_365[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0xa9,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_366[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_366[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0xb7,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_367[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x07,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_368[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_368[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8e,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_369[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_369[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x86,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_370[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_370[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x85,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_371[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x86,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_372[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_372[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x0f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_373[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_373[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x07,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_374[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_374[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x04,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_375[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xed,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_376[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_376[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x1a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_377[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_377[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0x83,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_378[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_378[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0xb7,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_379[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3f,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_380[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_380[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf3,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_381[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_381[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2d,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_382[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_382[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x11,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_383[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x46,0x37,0x48,0x85}; +static const uint8_t msg_384[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_384[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfa,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_385[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_385[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf4,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_386[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_386[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd0,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_387[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x45,0x37,0x48,0x85}; +static const uint8_t msg_388[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_388[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xf9,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_389[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_389[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf7,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_390[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_390[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd3,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_391[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0xc7,0x37,0x48,0x85}; +static const uint8_t msg_392[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_392[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0x7b,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_393[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_393[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0x75,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_394[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_394[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0x51,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_395[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x84}; +static const uint8_t msg_396[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_396[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xdb,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_397[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_397[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x60,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_398[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_398[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x41,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_399[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x87}; +static const uint8_t msg_400[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_400[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xd8,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_401[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_401[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x63,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_402[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_402[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x42,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_403[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0xc5}; +static const uint8_t msg_404[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_404[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0x9a,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_405[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_405[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x21,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_406[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_406[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x00,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_407[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x05}; +static const uint8_t msg_408[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_408[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0x5a,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_409[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_409[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0xe1,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_410[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_410[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0xc0,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_411[] = {0x6e,0xf5,0xb8,0xef,0x53,0xfc,0x36,0x56,0x07,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_412[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_412[] = {0x20,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0x78,0x8e,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_413[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_413[] = {0x05,0xb4,0xe8,0x16,0x6f,0x28,0x08,0x29,0x86,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_414[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_414[] = {0x31,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0x37,0x85,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_415[] = {0x6f,0xf5,0xb8,0x6f,0x53,0xfc,0x36,0xd6,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x85}; +static const uint8_t msg_416[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_416[] = {0x21,0x2e,0x4a,0x0f,0x8b,0x4c,0x66,0xf8,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0xda,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_417[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_417[] = {0x04,0xb4,0xe8,0x96,0x6f,0x28,0x08,0xa9,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0x61,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_418[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_418[] = {0x30,0x5d,0x6c,0x78,0xee,0xb3,0x6a,0xb7,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0x40,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_419[] = {0x6f,0xf5,0xb8,0xef,0x53,0xfc,0x36,0xd6,0x06,0xcd,0x3e,0xa0,0x47,0x37,0x48,0x05}; +static const uint8_t msg_420[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_420[] = {0x21,0x2e,0x4a,0x8f,0x8b,0x4c,0x66,0xf8,0x8f,0x3a,0xf2,0x30,0xfb,0x1c,0x3a,0x5a,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_421[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_421[] = {0x04,0xb4,0xe8,0x16,0x6f,0x28,0x08,0xa9,0x87,0xa3,0x2c,0xda,0xf5,0x3d,0xeb,0xe1,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_422[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_422[] = {0x30,0x5d,0x6c,0xf8,0xee,0xb3,0x6a,0xb7,0x84,0x97,0x10,0xe7,0xd1,0xf7,0x29,0xc0,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_423[] = {0x90,0x0a,0x47,0x10,0xac,0x03,0xc9,0xa9,0xf9,0x32,0xc1,0x5f,0xb8,0xc8,0xb7,0x7a}; +static const uint8_t msg_424[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_424[] = {0xde,0xd1,0xb5,0x70,0x74,0xb3,0x99,0x87,0x70,0xc5,0x0d,0xcf,0x04,0xe3,0xc5,0x25,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_425[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_425[] = {0xfb,0x4b,0x17,0xe9,0x90,0xd7,0xf7,0xd6,0x78,0x5c,0xd3,0x25,0x0a,0xc2,0x14,0x9e,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_426[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_426[] = {0xcf,0xa2,0x93,0x07,0x11,0x4c,0x95,0xc8,0x7b,0x68,0xef,0x18,0x2e,0x08,0xd6,0xbf,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_427[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; +static const uint8_t msg_428[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_428[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_429[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_429[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_430[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_430[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_431[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; +static const uint8_t msg_432[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_432[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_433[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_433[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_434[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_434[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_435[] = {0xef,0x75,0x38,0x6f,0xd3,0x7c,0xb6,0xd6,0x86,0x4d,0xbe,0x20,0xc7,0xb7,0xc8,0x05}; +static const uint8_t msg_436[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_436[] = {0xa1,0xae,0xca,0x0f,0x0b,0xcc,0xe6,0xf8,0x0f,0xba,0x72,0xb0,0x7b,0x9c,0xba,0x5a,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_437[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_437[] = {0x84,0x34,0x68,0x96,0xef,0xa8,0x88,0xa9,0x07,0x23,0xac,0x5a,0x75,0xbd,0x6b,0xe1,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_438[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_438[] = {0xb0,0xdd,0xec,0x78,0x6e,0x33,0xea,0xb7,0x04,0x17,0x90,0x67,0x51,0x77,0xa9,0xc0,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; +static const uint8_t ct_439[] = {0x6e,0xf4,0xb9,0xee,0x52,0xfd,0x37,0x57,0x07,0xcc,0x3f,0xa1,0x46,0x36,0x49,0x84}; +static const uint8_t msg_440[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37}; +static const uint8_t ct_440[] = {0x20,0x2f,0x4b,0x8e,0x8a,0x4d,0x67,0x79,0x8e,0x3b,0xf3,0x31,0xfa,0x1d,0x3b,0xdb,0x5e,0xad,0x70,0xc7,0xf0,0x66,0xd4,0xdf}; +static const uint8_t msg_441[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}; +static const uint8_t ct_441[] = {0x05,0xb5,0xe9,0x17,0x6e,0x29,0x09,0x28,0x86,0xa2,0x2d,0xdb,0xf4,0x3c,0xea,0x60,0x21,0x1d,0xff,0xad,0x75,0x62,0xc4,0xb9,0x24,0xbb,0x79,0xfe,0xd7,0x3d,0x9c,0xe2}; +static const uint8_t msg_442[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43}; +static const uint8_t ct_442[] = {0x31,0x5c,0x6d,0xf9,0xef,0xb2,0x6b,0x36,0x85,0x96,0x11,0xe6,0xd0,0xf6,0x28,0x41,0xad,0xfd,0x10,0xa7,0x61,0x5d,0x65,0x15,0xb9,0x99,0xdb,0xfc,0x5a,0x10,0xf3,0xae,0x9d,0xf5,0xf1,0x9a}; + +static const aes_siv_test_case aes_siv_tests[] = { + { 1, "RFC 5297", {0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff}, 32, aad_1, 24, msg_1, 14, ct_1, 30, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 2, "empty message", {0x2b,0x27,0xe4,0x29,0xfb,0x6c,0x02,0x67,0x8e,0x58,0x9c,0xcc,0x44,0x37,0xc5,0xad,0xfb,0x44,0xb3,0x31,0xab,0x6d,0x21,0xea,0x32,0x17,0x27,0xe6,0xec,0x03,0xd3,0x54}, 32, NULL, 0, NULL, 0, ct_2, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 3, "empty message", {0xe4,0x09,0x92,0xeb,0x4f,0x64,0x9e,0x5d,0x49,0x13,0x46,0x52,0xae,0xcc,0x24,0xba,0xfa,0x6b,0x45,0xce,0x8d,0xd9,0xe9,0xd3,0x71,0xed,0xe7,0xd5,0xde,0x84,0xfa,0x72}, 32, aad_3, 12, NULL, 0, ct_3, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 4, "empty message", {0x99,0x03,0x79,0x35,0xe6,0x20,0xda,0x1d,0x67,0xfa,0xf1,0xe2,0x6d,0x5a,0x0e,0x2c,0x5a,0xc2,0xea,0xe5,0xee,0xc7,0xcb,0xb7,0xb7,0xa6,0x13,0x05,0x6f,0x67,0x19,0xe3}, 32, aad_4, 15, NULL, 0, ct_4, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 5, "empty message", {0x7b,0xf9,0xe5,0x36,0xb6,0x6a,0x21,0x5c,0x22,0x23,0x3f,0xe2,0xda,0xaa,0x74,0x3a,0x89,0x8b,0x9a,0xcb,0x9f,0x78,0x02,0xde,0x70,0xb4,0x0e,0x3d,0x6e,0x43,0xef,0x97}, 32, aad_5, 16, NULL, 0, ct_5, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 6, "empty message", {0xea,0x70,0x81,0xdb,0x53,0xce,0x49,0x55,0x9f,0x9f,0xd2,0xb5,0x3e,0x00,0xf9,0x1b,0x68,0xc2,0xbd,0xba,0x94,0x69,0x61,0xda,0x1a,0x5b,0xc7,0x09,0x18,0x29,0x7a,0x43}, 32, aad_6, 20, NULL, 0, ct_6, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 7, "empty message", {0x1e,0x22,0x5c,0xaf,0xb9,0x03,0x39,0xbb,0xa1,0xb2,0x40,0x76,0xd4,0x20,0x6c,0x3e,0x79,0xc3,0x55,0x80,0x5d,0x85,0x16,0x82,0xbc,0x81,0x8b,0xaa,0x4f,0x5a,0x77,0x79}, 32, aad_7, 32, NULL, 0, ct_7, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 8, "message size divisible by block size", {0x61,0x2e,0x83,0x78,0x43,0xce,0xae,0x7f,0x61,0xd4,0x96,0x25,0xfa,0xa7,0xe7,0x49,0x4f,0x92,0x53,0xe2,0x0c,0xb3,0xad,0xce,0xa6,0x86,0x51,0x2b,0x04,0x39,0x36,0xcd}, 32, aad_8, 16, msg_8, 16, ct_8, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 9, "message size divisible by block size", {0x96,0xe1,0xe4,0x89,0x6f,0xb2,0xcd,0x05,0xf1,0x33,0xa6,0xa1,0x00,0xbc,0x56,0x09,0xa7,0xac,0x3c,0xa6,0xd8,0x17,0x21,0xe9,0x22,0xda,0xdd,0x69,0xad,0x07,0xa8,0x92}, 32, aad_9, 16, msg_9, 32, ct_9, 48, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 10, "message size divisible by block size", {0x64,0x9e,0x37,0x3e,0x68,0x1e,0xf5,0x2e,0x3c,0x10,0xac,0x26,0x54,0x84,0x75,0x09,0x32,0xa9,0x91,0x8f,0x28,0xfb,0x82,0x4f,0x7c,0xb5,0x0a,0xda,0xb3,0x97,0x81,0xfe}, 32, aad_10, 16, msg_10, 48, ct_10, 64, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 11, "small plaintext size", {0x29,0x89,0x62,0x33,0x5a,0x07,0x5e,0x9e,0xac,0xb7,0xa7,0x62,0x7b,0xea,0xfa,0x4e,0xe5,0xa0,0x22,0x42,0x42,0x3c,0xdf,0xb0,0xb4,0xf1,0x06,0xeb,0x61,0xcf,0x56,0x63}, 32, aad_11, 12, msg_11, 1, ct_11, 17, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 12, "small plaintext size", {0xea,0x1a,0x78,0x31,0xe6,0xfd,0x08,0x04,0x56,0x50,0x7a,0x99,0x6b,0x6d,0x71,0x66,0x8c,0x2c,0xec,0x43,0xc7,0x57,0x53,0x9c,0x3b,0x53,0x42,0xfa,0xdb,0xe6,0x4d,0xc4}, 32, aad_12, 12, msg_12, 2, ct_12, 18, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 13, "small plaintext size", {0x00,0x9e,0x82,0x88,0xda,0x0a,0x3d,0x22,0xae,0xaa,0x23,0x1f,0xbb,0xfd,0xe9,0xed,0x90,0x1d,0x22,0xdf,0x9f,0x3a,0xb7,0x07,0xe1,0x5a,0xa2,0xfc,0x39,0x0d,0x06,0x79}, 32, aad_13, 12, msg_13, 3, ct_13, 19, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 14, "small plaintext size", {0xb6,0x20,0x2e,0xf3,0xda,0xd5,0xa4,0x26,0x67,0xf0,0x20,0xf0,0xe4,0xbd,0x89,0xd8,0x45,0x71,0x1d,0xa7,0x7f,0x98,0xc7,0x47,0xeb,0x91,0x4d,0xe8,0x69,0x63,0x8b,0xcf}, 32, aad_14, 12, msg_14, 4, ct_14, 20, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 15, "small plaintext size", {0xfa,0x82,0xae,0xf8,0xc8,0xd6,0xe3,0xcd,0x8f,0x8d,0x05,0x3e,0xa6,0xb1,0xb0,0x7c,0xa3,0xbc,0x01,0x52,0x50,0x6d,0x46,0x49,0x26,0x63,0x0d,0x6f,0xd8,0x3e,0x8a,0x72}, 32, aad_15, 12, msg_15, 5, ct_15, 21, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 16, "small plaintext size", {0x4e,0xd2,0x37,0xae,0x3d,0x06,0x6d,0xf7,0x66,0xbe,0xa9,0x23,0x11,0x6b,0xf9,0xd2,0xce,0x6f,0x63,0xd3,0x4a,0x4f,0x56,0xed,0x86,0x31,0xba,0xcc,0xab,0xd7,0x06,0x47}, 32, aad_16, 12, msg_16, 6, ct_16, 22, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 17, "small plaintext size", {0x56,0xdf,0x5d,0x41,0xa1,0x10,0xa6,0x3a,0xcc,0x7b,0x7c,0x04,0x5b,0xe9,0xf3,0x5a,0x8f,0x2f,0xaf,0x16,0xd8,0x3f,0xb5,0x59,0x26,0x8e,0xb8,0x96,0x34,0x84,0xf5,0x52}, 32, aad_17, 12, msg_17, 7, ct_17, 23, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 18, "small plaintext size", {0x2e,0x94,0xa8,0x4c,0x78,0xbe,0x80,0xcd,0x59,0x83,0x66,0x05,0x8d,0x4f,0x6c,0xdf,0x80,0x95,0x66,0x6d,0xca,0xc7,0xa0,0x0a,0xd8,0x32,0xd9,0xf3,0x3e,0x20,0xd1,0x3c}, 32, aad_18, 12, msg_18, 8, ct_18, 24, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 19, "small plaintext size", {0x60,0xbf,0x71,0x1a,0x16,0x2c,0xf6,0xa1,0xb1,0x08,0xd1,0x35,0x1f,0x9f,0xd2,0xee,0x50,0x22,0xa9,0xdf,0x3c,0x5e,0x49,0x42,0x68,0x22,0x6b,0x17,0x51,0x8a,0x93,0xb7}, 32, aad_19, 12, msg_19, 9, ct_19, 25, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 20, "small plaintext size", {0x5a,0xad,0xf8,0xdd,0x38,0x0e,0x42,0x87,0x58,0x21,0x55,0xf1,0x11,0x65,0xb3,0x1d,0xc8,0xed,0x76,0x94,0x68,0x89,0xa2,0xbb,0x86,0x33,0x99,0x0f,0xb6,0x2f,0xc4,0x6f}, 32, aad_20, 12, msg_20, 10, ct_20, 26, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 21, "small plaintext size", {0xb0,0x99,0xc4,0xa6,0x13,0xf5,0xef,0xda,0x82,0xb0,0x69,0xd9,0xa7,0x6c,0x02,0xa4,0x04,0x9c,0x12,0x31,0x0e,0x25,0xf2,0x72,0xdb,0xd9,0xd1,0x55,0xae,0xdd,0x8d,0x52}, 32, aad_21, 12, msg_21, 11, ct_21, 27, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 22, "small plaintext size", {0xdd,0x06,0x55,0xb5,0x09,0x9c,0x4a,0xcb,0x60,0xc8,0xaf,0xac,0xed,0xe1,0xb6,0xac,0x04,0x28,0x3c,0x4f,0xcd,0xd1,0xfe,0xe2,0xf5,0xaa,0xa6,0xd8,0x6b,0xf6,0xc0,0x25}, 32, aad_22, 12, msg_22, 12, ct_22, 28, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 23, "small plaintext size", {0xaa,0x62,0x85,0x69,0x3f,0xc4,0x0a,0x59,0xeb,0xc2,0xbd,0xab,0x16,0xf1,0xe9,0x11,0x1e,0xc7,0x94,0xce,0x5e,0xc6,0x3b,0x8f,0x89,0xfa,0xfe,0x1b,0x7f,0xed,0xfa,0xcf}, 32, aad_23, 12, msg_23, 13, ct_23, 29, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 24, "small plaintext size", {0x18,0xa4,0x68,0x8d,0xa2,0xad,0x1e,0x11,0x2e,0xa5,0x6e,0xf6,0xda,0x91,0x07,0xe0,0xf1,0x09,0x4e,0xee,0xd3,0xf6,0xb8,0x68,0x20,0x29,0x52,0xd5,0x6e,0x0f,0x82,0x39}, 32, aad_24, 12, msg_24, 14, ct_24, 30, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 25, "small plaintext size", {0x95,0xb3,0x30,0xaa,0x5f,0xff,0xa6,0xc0,0xe2,0x9f,0xd6,0xfa,0x0d,0xeb,0xdc,0xb9,0xcf,0x6b,0x44,0x88,0x20,0xbe,0xa2,0x48,0x75,0x08,0x9e,0xc8,0xca,0x5a,0x23,0x87}, 32, aad_25, 12, msg_25, 15, ct_25, 31, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 26, "plaintext size > 16", {0xb3,0xb7,0xc2,0xc6,0xd3,0xd8,0x09,0x18,0x21,0x8a,0xfc,0xd8,0xbf,0x2a,0x71,0xcf,0x02,0x20,0xe2,0xe8,0x08,0x4e,0xad,0x8b,0xa1,0xab,0xfb,0x89,0x3a,0xe3,0x6d,0x40}, 32, aad_26, 12, msg_26, 17, ct_26, 33, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 27, "plaintext size > 16", {0x27,0x00,0xa2,0x0e,0xf5,0xc3,0xeb,0x4d,0xf1,0x23,0x56,0x8d,0x0d,0xf0,0x42,0xc3,0x5d,0x32,0xb4,0x24,0x37,0xef,0xb1,0x03,0x2a,0x6a,0x1f,0xe5,0x35,0x97,0x67,0xcc}, 32, aad_27, 12, msg_27, 20, ct_27, 36, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 28, "plaintext size > 16", {0xcc,0x5d,0x59,0x9a,0xec,0xbe,0xd3,0x5b,0xb4,0xe1,0x3a,0x2f,0x79,0x58,0x6d,0xfe,0x42,0xe6,0x38,0x2e,0x8f,0xa8,0x32,0x6b,0x67,0x4f,0x34,0x71,0x6d,0x63,0x76,0xf2}, 32, aad_28, 12, msg_28, 31, ct_28, 47, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 29, "plaintext size > 16", {0x71,0xa7,0xad,0xc7,0x22,0x2f,0x47,0x1c,0x28,0xf6,0x82,0xc1,0x2d,0x45,0xfe,0xed,0x45,0x55,0x60,0x00,0xa9,0x86,0x03,0x59,0x22,0x92,0x4a,0xd1,0x54,0xba,0x5f,0xa5}, 32, aad_29, 12, msg_29, 40, ct_29, 56, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 30, "plaintext size > 16", {0x83,0xbc,0x39,0xbf,0x7b,0x5f,0xaa,0xf0,0xf9,0x22,0x3e,0xd2,0xaa,0x76,0x1a,0xb3,0x2c,0x04,0x99,0x3e,0x3f,0xbc,0xcd,0x34,0xee,0x61,0x6f,0xfd,0x28,0xce,0x57,0x66}, 32, aad_30, 12, msg_30, 80, ct_30, 96, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 31, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_31, 16, ct_31, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 32, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, aad_32, 16, msg_32, 16, ct_32, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 33, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_33, 16, ct_33, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 34, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, aad_34, 16, msg_34, 16, ct_34, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 35, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_35, 16, ct_35, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 36, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, aad_36, 16, msg_36, 16, ct_36, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 37, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_37, 16, ct_37, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 38, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, aad_38, 16, msg_38, 16, ct_38, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 39, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_39, 16, ct_39, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 40, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, aad_40, 16, msg_40, 16, ct_40, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 41, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_41, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 42, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_42, 8, ct_42, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 43, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_43, 16, ct_43, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 44, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_44, 20, ct_44, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 45, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_45, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 46, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_46, 8, ct_46, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 47, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_47, 16, ct_47, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 48, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_48, 20, ct_48, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 49, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_49, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 50, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_50, 8, ct_50, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 51, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_51, 16, ct_51, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 52, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_52, 20, ct_52, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 53, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_53, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 54, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_54, 8, ct_54, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 55, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_55, 16, ct_55, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 56, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_56, 20, ct_56, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 57, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_57, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 58, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_58, 8, ct_58, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 59, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_59, 16, ct_59, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 60, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_60, 20, ct_60, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 61, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_61, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 62, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_62, 8, ct_62, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 63, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_63, 16, ct_63, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 64, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_64, 20, ct_64, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 65, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_65, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 66, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_66, 8, ct_66, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 67, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_67, 16, ct_67, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 68, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_68, 20, ct_68, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 69, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_69, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 70, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_70, 8, ct_70, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 71, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_71, 16, ct_71, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 72, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_72, 20, ct_72, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 73, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_73, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 74, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_74, 8, ct_74, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 75, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_75, 16, ct_75, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 76, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_76, 20, ct_76, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 77, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_77, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 78, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_78, 8, ct_78, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 79, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_79, 16, ct_79, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 80, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_80, 20, ct_80, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 81, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_81, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 82, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_82, 8, ct_82, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 83, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_83, 16, ct_83, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 84, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_84, 20, ct_84, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 85, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_85, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 86, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_86, 8, ct_86, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 87, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_87, 16, ct_87, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 88, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_88, 20, ct_88, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 89, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_89, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 90, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_90, 8, ct_90, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 91, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_91, 16, ct_91, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 92, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_92, 20, ct_92, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 93, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_93, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 94, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_94, 8, ct_94, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 95, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_95, 16, ct_95, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 96, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_96, 20, ct_96, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 97, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_97, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 98, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_98, 8, ct_98, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 99, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_99, 16, ct_99, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 100, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_100, 20, ct_100, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 101, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_101, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 102, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_102, 8, ct_102, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 103, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_103, 16, ct_103, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 104, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_104, 20, ct_104, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 105, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_105, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 106, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_106, 8, ct_106, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 107, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_107, 16, ct_107, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 108, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_108, 20, ct_108, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 109, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_109, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 110, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_110, 8, ct_110, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 111, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_111, 16, ct_111, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 112, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_112, 20, ct_112, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 113, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_113, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 114, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_114, 8, ct_114, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 115, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_115, 16, ct_115, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 116, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_116, 20, ct_116, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 117, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_117, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 118, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_118, 8, ct_118, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 119, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_119, 16, ct_119, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 120, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_120, 20, ct_120, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 121, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_121, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 122, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_122, 8, ct_122, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 123, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_123, 16, ct_123, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 124, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_124, 20, ct_124, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 125, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_125, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 126, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_126, 8, ct_126, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 127, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_127, 16, ct_127, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 128, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_128, 20, ct_128, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 129, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_129, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 130, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_130, 8, ct_130, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 131, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_131, 16, ct_131, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 132, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_132, 20, ct_132, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 133, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_133, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 134, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_134, 8, ct_134, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 135, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_135, 16, ct_135, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 136, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_136, 20, ct_136, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 137, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_137, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 138, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_138, 8, ct_138, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 139, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_139, 16, ct_139, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 140, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_140, 20, ct_140, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 141, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_141, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 142, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_142, 8, ct_142, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 143, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_143, 16, ct_143, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 144, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_144, 20, ct_144, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 145, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, NULL, 0, ct_145, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 146, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_146, 8, ct_146, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 147, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_147, 16, ct_147, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 148, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}, 32, NULL, 0, msg_148, 20, ct_148, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 149, "empty message", {0xd3,0xd5,0x8a,0x2f,0x21,0xe6,0x2f,0x50,0x95,0x54,0x2e,0x61,0x81,0x68,0xef,0x04,0x09,0x22,0xab,0x7d,0x80,0xb3,0x84,0x00,0x55,0xeb,0x9c,0xaf,0x57,0x26,0xa8,0xd4,0xa7,0xf0,0x71,0xdc,0x40,0xdd,0xb3,0x20,0xef,0xfc,0x09,0x42,0x11,0x73,0x50,0x90}, 48, NULL, 0, NULL, 0, ct_149, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 150, "empty message", {0xad,0x0f,0x78,0x62,0x38,0x6c,0x35,0xfe,0xe1,0x28,0xae,0x7f,0xf1,0x8d,0xb0,0x84,0xa0,0xf4,0x57,0xfc,0xfc,0x7f,0xe1,0xc5,0x37,0x0b,0x14,0x5f,0x7f,0xa6,0x45,0xa9,0x7b,0xa3,0xeb,0x4f,0x90,0xe1,0x89,0x41,0xb1,0x8e,0x8d,0x89,0x49,0x4e,0xc7,0x96}, 48, aad_150, 12, NULL, 0, ct_150, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 151, "empty message", {0x27,0x8e,0x77,0x0c,0xa6,0x00,0xbb,0x23,0xf5,0xd8,0x72,0x5b,0xfd,0x0c,0xfc,0x05,0xb9,0x10,0x57,0xe7,0x9c,0x89,0x0a,0x69,0x7d,0x41,0xe9,0xff,0x68,0x7c,0x6a,0x14,0xea,0x48,0xfb,0x22,0x8d,0x7f,0x95,0xab,0x4a,0x93,0xc5,0xba,0x9d,0x96,0x62,0x62}, 48, aad_151, 15, NULL, 0, ct_151, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 152, "empty message", {0x5a,0xd9,0x85,0xb9,0xbc,0xb4,0x61,0xf9,0x11,0x59,0x37,0xb6,0xbd,0xe7,0x07,0x3f,0xbe,0xd9,0xe8,0xbf,0x32,0x24,0x5a,0xfe,0x58,0x36,0xe8,0xc2,0xf6,0x7b,0x39,0x99,0x26,0x6b,0xa0,0xd8,0xd9,0xeb,0xa6,0xfa,0x97,0x8c,0x47,0xea,0x9e,0xf4,0x69,0x0a}, 48, aad_152, 16, NULL, 0, ct_152, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 153, "empty message", {0xb6,0x5c,0x2a,0x4f,0x88,0xf7,0x33,0x14,0x2c,0xc6,0x6e,0xd9,0xaf,0xf4,0x7e,0x77,0xf3,0xa6,0x33,0x9d,0x30,0xe0,0x30,0x29,0x0d,0x34,0xbe,0x40,0xdf,0xa7,0xb3,0x3e,0x37,0xbc,0x2f,0x48,0xea,0x86,0x17,0xf4,0xe7,0xd6,0x0c,0x28,0xc0,0xc0,0x1a,0x0d}, 48, aad_153, 20, NULL, 0, ct_153, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 154, "empty message", {0x4c,0xd9,0xd4,0xd7,0x29,0x79,0x2e,0x6a,0x59,0x9b,0xd5,0x9c,0x33,0x0a,0xe8,0xa4,0xdf,0x40,0x77,0x22,0x5c,0x9c,0x63,0x3c,0xb5,0x91,0x90,0xf3,0xa5,0xd1,0x15,0x0f,0xdc,0x38,0xa7,0xfb,0xc6,0x87,0x51,0x6f,0x82,0xd6,0x35,0x4e,0x57,0x28,0x1c,0x1a}, 48, aad_154, 32, NULL, 0, ct_154, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 155, "message size divisible by block size", {0xca,0x9d,0xb6,0x22,0x14,0xc3,0xaf,0xab,0x38,0x5b,0x90,0x86,0xf1,0xcb,0x90,0xd1,0x71,0x95,0xd4,0x95,0xef,0x47,0x64,0x2d,0xba,0xd0,0x6f,0x4e,0x7d,0x0b,0xab,0x13,0x6c,0x77,0x88,0x50,0x29,0xad,0x44,0x2b,0x30,0xc3,0x4c,0x8b,0x52,0x90,0xe7,0xd0}, 48, aad_155, 16, msg_155, 16, ct_155, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 156, "message size divisible by block size", {0xc4,0xbb,0x58,0xd7,0x3a,0x61,0xee,0xef,0x0e,0xc2,0x34,0x90,0xdc,0x3c,0x3a,0x3e,0x14,0x02,0x44,0xc9,0xbe,0x88,0x20,0x96,0x58,0xcc,0x56,0x54,0xa9,0x96,0xdb,0x23,0x72,0xc2,0x21,0x2f,0xfd,0xc2,0x60,0xbb,0xdb,0x92,0xa5,0x20,0xc8,0x6f,0x96,0xd8}, 48, aad_156, 16, msg_156, 32, ct_156, 48, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 157, "message size divisible by block size", {0x9e,0xae,0x72,0xa3,0x96,0x4b,0xdf,0x14,0xad,0xef,0x86,0x16,0xaa,0x54,0x41,0x57,0x7b,0x7b,0xbc,0x32,0x46,0x52,0x51,0x6b,0x4c,0x29,0xa7,0xb0,0xf3,0xbf,0xa7,0x19,0xbe,0x49,0xe3,0xd2,0xae,0x62,0x97,0x58,0x8a,0xda,0x65,0x2e,0xb4,0x5b,0x0a,0x00}, 48, aad_157, 16, msg_157, 48, ct_157, 64, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 158, "small plaintext size", {0xba,0x78,0x3a,0x71,0x5f,0xf6,0xee,0x6d,0x71,0xe3,0xa4,0xa7,0xad,0xb6,0x35,0x66,0x87,0xdb,0x12,0xcc,0x29,0x54,0x80,0x70,0x99,0xf9,0x74,0x71,0xc9,0x51,0xc7,0xf0,0xc3,0x35,0x71,0xd3,0x33,0x4d,0x11,0x1c,0x4e,0xa3,0x3a,0x12,0x36,0x5c,0x00,0x61}, 48, aad_158, 12, msg_158, 1, ct_158, 17, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 159, "small plaintext size", {0xb5,0xba,0x35,0xa5,0x97,0xbe,0x37,0xf8,0xf8,0x16,0x8a,0x40,0xe9,0xf4,0x7b,0x96,0x07,0x7c,0xec,0xed,0x6a,0xc0,0x96,0x8a,0x4e,0x5f,0xfa,0xbc,0x40,0x21,0x99,0x26,0x7b,0xcd,0x4f,0x74,0x06,0x40,0xc6,0x87,0x74,0x41,0xc6,0x3e,0x80,0x15,0xd8,0x6c}, 48, aad_159, 12, msg_159, 2, ct_159, 18, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 160, "small plaintext size", {0x17,0xa4,0x49,0x37,0xa1,0xf8,0xb8,0x02,0x9a,0x7f,0x64,0x13,0x7e,0xaa,0x2d,0x7d,0xe9,0x50,0xb4,0x9b,0x0e,0xf2,0xd8,0x39,0x94,0x15,0x1c,0x7b,0x9d,0xde,0x2e,0x87,0xc5,0xaa,0x3d,0xeb,0xfa,0x0a,0xd9,0xf0,0x28,0x26,0x0c,0x6d,0xc2,0xfc,0x7e,0x01}, 48, aad_160, 12, msg_160, 3, ct_160, 19, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 161, "small plaintext size", {0xbf,0xf6,0x84,0xf0,0x86,0xef,0x33,0x14,0x21,0x1b,0xa7,0x82,0xa2,0xe7,0xe7,0x5a,0x60,0xa9,0xa3,0xdf,0x9f,0xc5,0x05,0x05,0x7f,0x54,0xe2,0xb2,0x64,0xfb,0xe2,0xe5,0xea,0xe2,0x99,0x87,0x9f,0xcc,0xd2,0x6c,0xa3,0x9d,0x1e,0x33,0xb8,0x83,0x96,0x6e}, 48, aad_161, 12, msg_161, 4, ct_161, 20, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 162, "small plaintext size", {0x37,0x9c,0x42,0x55,0x81,0xca,0x80,0x94,0xe4,0x7d,0x1e,0xe4,0x9f,0xe9,0xa5,0xdd,0x3d,0xd8,0xd6,0x8c,0x6c,0x85,0xf8,0xb4,0xcb,0x56,0x84,0x9e,0x99,0x69,0x8e,0xe7,0x33,0x32,0xc8,0xb0,0xcc,0x6d,0xa0,0x62,0x7c,0x95,0xf2,0xde,0x9d,0xdd,0x08,0x71}, 48, aad_162, 12, msg_162, 5, ct_162, 21, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 163, "small plaintext size", {0x0f,0x11,0xa5,0x4e,0x9f,0x03,0x07,0x18,0x28,0x94,0x4e,0x39,0xa3,0xf5,0xa5,0x53,0x8c,0x4c,0x94,0x12,0x2e,0x75,0x7a,0xa7,0x06,0x2a,0xfd,0xb9,0x0d,0x5e,0x8b,0x4a,0xeb,0x41,0xe6,0x81,0x81,0x8a,0x14,0x98,0x31,0xab,0x7b,0x25,0xe2,0xca,0x3b,0x96}, 48, aad_163, 12, msg_163, 6, ct_163, 22, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 164, "small plaintext size", {0xe9,0x59,0xe0,0xc1,0x4f,0x3e,0x0d,0x8d,0xd4,0x41,0x62,0xd2,0x7f,0x4c,0x33,0x3a,0x33,0x73,0x32,0x55,0x01,0x67,0x73,0x19,0x49,0xc6,0x73,0x2b,0x23,0xa5,0xdb,0xd9,0xaa,0x3d,0xd8,0x01,0xb6,0x65,0x43,0x75,0x54,0x74,0xf4,0x47,0x74,0xe5,0xd8,0x23}, 48, aad_164, 12, msg_164, 7, ct_164, 23, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 165, "small plaintext size", {0xfe,0x64,0x12,0xc4,0x34,0x63,0xc2,0x2b,0x98,0x99,0x2f,0x8c,0x31,0x9b,0x66,0x27,0x18,0x25,0x5d,0x12,0x27,0x7c,0xe6,0x2e,0x56,0xba,0x25,0x8c,0xcc,0x7a,0x46,0x94,0x12,0x1e,0x69,0x12,0xed,0x74,0x5b,0x4a,0x6e,0x12,0xff,0x9d,0x38,0xc8,0x6e,0xf2}, 48, aad_165, 12, msg_165, 8, ct_165, 24, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 166, "small plaintext size", {0x71,0x00,0x2b,0x32,0x1b,0x1e,0x92,0x4a,0x45,0xd9,0x73,0x02,0xa0,0x8f,0x23,0x61,0xaf,0x1d,0x20,0x93,0xfa,0xf6,0x61,0xf0,0x4a,0xb4,0x7e,0xcc,0xa9,0xf5,0xec,0x9a,0x35,0xbe,0x3c,0xcf,0xf8,0xa4,0xae,0xd1,0xff,0x65,0x8d,0x19,0x5c,0x05,0xae,0xd7}, 48, aad_166, 12, msg_166, 9, ct_166, 25, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 167, "small plaintext size", {0xdf,0xf1,0xd0,0x25,0xa8,0xb6,0x2d,0xfb,0xe8,0xfd,0x7d,0x04,0x80,0xe5,0x72,0xf1,0xc5,0xe1,0x25,0xc1,0xab,0x4c,0x14,0x8e,0x37,0xff,0x9a,0x8e,0xc5,0xd8,0xa4,0xcf,0x35,0xbc,0x30,0x44,0x45,0xbe,0x3b,0xc4,0x5e,0xd3,0x7f,0x92,0xe0,0x32,0xaf,0x14}, 48, aad_167, 12, msg_167, 10, ct_167, 26, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 168, "small plaintext size", {0xda,0xe6,0x92,0x07,0x03,0xb8,0x05,0x00,0xb4,0x19,0x72,0x69,0xfa,0xf5,0xd7,0x4d,0xe8,0xe6,0x10,0x41,0x5e,0x19,0x4b,0x42,0x30,0x80,0xeb,0xaf,0x6d,0x99,0x87,0x3d,0xc3,0x07,0xdc,0x4f,0x6d,0x9f,0x32,0xad,0x0e,0xba,0xd8,0xad,0x78,0x52,0x69,0x0c}, 48, aad_168, 12, msg_168, 11, ct_168, 27, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 169, "small plaintext size", {0xe6,0x9e,0xa3,0x66,0xfd,0x38,0x5e,0x0e,0xd8,0xb9,0xcb,0xb0,0x17,0x00,0x65,0x4f,0xa2,0x8a,0xdd,0x8e,0x56,0xb7,0xea,0x68,0x3e,0x1f,0xd7,0x18,0x51,0x1a,0xb0,0xfb,0x22,0xdc,0xd7,0x10,0xc5,0x30,0xe0,0x0f,0xb6,0x6f,0x45,0x84,0xfa,0x21,0xe9,0xe6}, 48, aad_169, 12, msg_169, 12, ct_169, 28, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 170, "small plaintext size", {0xb6,0x0b,0x83,0x85,0x6f,0x56,0xcd,0xf8,0x90,0x27,0x46,0x0a,0x76,0x99,0x3f,0xdb,0xde,0x0f,0x2a,0xb0,0x1e,0x9d,0xde,0x2f,0xa7,0xc2,0x7e,0xf4,0x71,0x55,0xec,0x7c,0xab,0xa8,0x92,0xb2,0x7f,0xd9,0xa3,0x1e,0x89,0x23,0xbf,0xc4,0x47,0x94,0xcd,0x71}, 48, aad_170, 12, msg_170, 13, ct_170, 29, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 171, "small plaintext size", {0x85,0x96,0x98,0xa8,0x52,0xa1,0x31,0xa3,0x80,0x48,0x38,0xf3,0xd0,0x12,0xd6,0x08,0x8e,0x13,0x5b,0x6d,0xb1,0x60,0xb2,0xac,0x68,0xe6,0xdf,0xa6,0xec,0x33,0x0d,0xc0,0xd6,0x82,0xe4,0x06,0xc8,0x7c,0x15,0xb9,0xa7,0x4a,0xff,0xe4,0x41,0x74,0x94,0x95}, 48, aad_171, 12, msg_171, 14, ct_171, 30, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 172, "small plaintext size", {0xeb,0xe1,0xc2,0x73,0xba,0x54,0xb8,0x77,0xb9,0x37,0xe9,0x90,0x6c,0x40,0x63,0xe1,0x88,0xef,0xd5,0x7b,0xd3,0xa3,0x2b,0xe8,0x25,0x36,0x93,0x80,0xf1,0xb9,0xf6,0xb8,0xb6,0xa0,0xc2,0xab,0x13,0x90,0xe5,0x89,0xf6,0x10,0x1c,0x5f,0xfb,0x74,0x60,0xc7}, 48, aad_172, 12, msg_172, 15, ct_172, 31, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 173, "plaintext size > 16", {0x80,0xd5,0x0f,0xaf,0xb3,0xed,0xe5,0xdd,0xbb,0x50,0x58,0x82,0x73,0x03,0xa0,0x98,0xbf,0x21,0x3e,0x47,0xdc,0xff,0x12,0xea,0x53,0x38,0xa2,0xa0,0xf9,0x14,0xd8,0x4b,0xff,0x58,0xc8,0xc6,0x9c,0x3b,0x15,0x1d,0x6d,0xc3,0x80,0xfd,0x8f,0x3e,0x41,0x78}, 48, aad_173, 12, msg_173, 17, ct_173, 33, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 174, "plaintext size > 16", {0x5f,0x6b,0xfe,0x19,0x98,0x7d,0x5b,0xf6,0x47,0x1d,0xd9,0xe4,0x36,0x09,0x4f,0x7f,0xe3,0x3f,0x8a,0xcc,0xa3,0xb8,0xa4,0x1e,0x27,0x78,0x61,0xe2,0x02,0xbd,0x72,0x62,0xfc,0x2b,0x0b,0xd3,0xdf,0x9b,0x35,0xfa,0x2f,0xc3,0xc5,0x79,0x62,0x0f,0x00,0xeb}, 48, aad_174, 12, msg_174, 20, ct_174, 36, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 175, "plaintext size > 16", {0x9e,0xa3,0x73,0x52,0xe4,0x1b,0x57,0xd6,0x1e,0xd8,0x37,0xb2,0xac,0xe4,0x81,0x87,0x0d,0x24,0x13,0xd9,0x2b,0xf0,0x0f,0x30,0xdb,0xb8,0xfe,0x8d,0x25,0x0b,0x3c,0xeb,0xd0,0xf6,0x4d,0x71,0x4c,0xf6,0x1a,0x05,0x33,0xd0,0x2d,0x37,0x22,0x84,0xc6,0xc3}, 48, aad_175, 12, msg_175, 31, ct_175, 47, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 176, "plaintext size > 16", {0x25,0xb0,0xb4,0x04,0xbb,0x1f,0x78,0x44,0x6d,0x0e,0x5c,0xde,0x01,0x2e,0xe5,0x83,0x2c,0xb4,0x03,0x39,0x8a,0x3e,0x66,0xe9,0xb5,0xa2,0x44,0xb5,0x9d,0x89,0x94,0xee,0x10,0x18,0x4a,0x57,0x76,0xf3,0x57,0x8f,0xaa,0xb8,0x30,0xe8,0x65,0xf8,0x13,0x3c}, 48, aad_176, 12, msg_176, 40, ct_176, 56, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 177, "plaintext size > 16", {0x7e,0x22,0x5c,0xf2,0x00,0x4a,0x28,0xa0,0x91,0x98,0x6f,0x13,0x1f,0xd4,0x3e,0xd1,0x11,0xc0,0x69,0x3e,0x63,0x43,0x3f,0xfc,0x9d,0xad,0x90,0x29,0xc5,0x35,0x09,0x63,0x97,0x63,0x6e,0x13,0x29,0x6e,0xb6,0x21,0x43,0x16,0x26,0x43,0xb1,0x3c,0x75,0x46}, 48, aad_177, 12, msg_177, 80, ct_177, 96, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 178, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_178, 16, ct_178, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 179, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, aad_179, 16, msg_179, 16, ct_179, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 180, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_180, 16, ct_180, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 181, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, aad_181, 16, msg_181, 16, ct_181, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 182, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_182, 16, ct_182, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 183, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, aad_183, 16, msg_183, 16, ct_183, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 184, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_184, 16, ct_184, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 185, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, aad_185, 16, msg_185, 16, ct_185, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 186, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_186, 16, ct_186, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 187, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, aad_187, 16, msg_187, 16, ct_187, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 188, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_188, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 189, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_189, 8, ct_189, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 190, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_190, 16, ct_190, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 191, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_191, 20, ct_191, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 192, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_192, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 193, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_193, 8, ct_193, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 194, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_194, 16, ct_194, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 195, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_195, 20, ct_195, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 196, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_196, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 197, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_197, 8, ct_197, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 198, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_198, 16, ct_198, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 199, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_199, 20, ct_199, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 200, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_200, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 201, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_201, 8, ct_201, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 202, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_202, 16, ct_202, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 203, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_203, 20, ct_203, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 204, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_204, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 205, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_205, 8, ct_205, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 206, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_206, 16, ct_206, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 207, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_207, 20, ct_207, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 208, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_208, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 209, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_209, 8, ct_209, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 210, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_210, 16, ct_210, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 211, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_211, 20, ct_211, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 212, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_212, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 213, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_213, 8, ct_213, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 214, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_214, 16, ct_214, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 215, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_215, 20, ct_215, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 216, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_216, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 217, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_217, 8, ct_217, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 218, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_218, 16, ct_218, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 219, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_219, 20, ct_219, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 220, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_220, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 221, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_221, 8, ct_221, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 222, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_222, 16, ct_222, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 223, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_223, 20, ct_223, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 224, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_224, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 225, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_225, 8, ct_225, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 226, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_226, 16, ct_226, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 227, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_227, 20, ct_227, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 228, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_228, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 229, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_229, 8, ct_229, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 230, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_230, 16, ct_230, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 231, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_231, 20, ct_231, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 232, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_232, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 233, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_233, 8, ct_233, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 234, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_234, 16, ct_234, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 235, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_235, 20, ct_235, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 236, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_236, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 237, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_237, 8, ct_237, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 238, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_238, 16, ct_238, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 239, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_239, 20, ct_239, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 240, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_240, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 241, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_241, 8, ct_241, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 242, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_242, 16, ct_242, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 243, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_243, 20, ct_243, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 244, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_244, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 245, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_245, 8, ct_245, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 246, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_246, 16, ct_246, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 247, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_247, 20, ct_247, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 248, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_248, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 249, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_249, 8, ct_249, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 250, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_250, 16, ct_250, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 251, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_251, 20, ct_251, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 252, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_252, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 253, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_253, 8, ct_253, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 254, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_254, 16, ct_254, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 255, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_255, 20, ct_255, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 256, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_256, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 257, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_257, 8, ct_257, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 258, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_258, 16, ct_258, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 259, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_259, 20, ct_259, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 260, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_260, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 261, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_261, 8, ct_261, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 262, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_262, 16, ct_262, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 263, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_263, 20, ct_263, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 264, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_264, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 265, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_265, 8, ct_265, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 266, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_266, 16, ct_266, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 267, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_267, 20, ct_267, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 268, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_268, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 269, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_269, 8, ct_269, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 270, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_270, 16, ct_270, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 271, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_271, 20, ct_271, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 272, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_272, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 273, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_273, 8, ct_273, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 274, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_274, 16, ct_274, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 275, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_275, 20, ct_275, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 276, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_276, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 277, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_277, 8, ct_277, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 278, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_278, 16, ct_278, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 279, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_279, 20, ct_279, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 280, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_280, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 281, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_281, 8, ct_281, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 282, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_282, 16, ct_282, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 283, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_283, 20, ct_283, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 284, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_284, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 285, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_285, 8, ct_285, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 286, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_286, 16, ct_286, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 287, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_287, 20, ct_287, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 288, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_288, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 289, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_289, 8, ct_289, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 290, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_290, 16, ct_290, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 291, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_291, 20, ct_291, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 292, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, NULL, 0, ct_292, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 293, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_293, 8, ct_293, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 294, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_294, 16, ct_294, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 295, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}, 48, NULL, 0, msg_295, 20, ct_295, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 296, "empty message", {0xbc,0x76,0x35,0xc1,0xfd,0x56,0x6a,0xa8,0x35,0x7f,0xd1,0x03,0x71,0x4b,0xfa,0xee,0x1c,0x9e,0x5b,0x3c,0x57,0x8b,0x39,0x80,0x40,0x1a,0x98,0x10,0x30,0x25,0x4a,0x54,0xb1,0x75,0x6a,0x8c,0x96,0xe6,0x00,0xb7,0x25,0x2f,0xd0,0xaa,0xb1,0x2f,0x39,0xd1,0x15,0xd2,0x56,0xb3,0xf3,0xe7,0xc2,0xc4,0x1a,0x7f,0xec,0xe7,0x2b,0xa7,0xc3,0xc4}, 64, NULL, 0, NULL, 0, ct_296, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 297, "empty message", {0xaf,0xf6,0x38,0x8f,0xdd,0x29,0x08,0xe0,0xc3,0xb6,0x10,0xe3,0xdc,0xd4,0x10,0xc8,0x14,0x6a,0x26,0x8d,0x6b,0xef,0xd5,0xc4,0x5f,0xfd,0xd2,0x35,0x08,0xb5,0xb3,0x11,0xcc,0x3a,0x9d,0x8f,0x83,0x8f,0x45,0x64,0x36,0xb2,0x89,0x01,0x86,0x82,0x15,0x1d,0xd5,0x7d,0x8d,0x65,0xd1,0xa8,0x23,0xc0,0x6e,0xca,0x8a,0xb8,0xee,0x01,0xda,0x01}, 64, aad_297, 12, NULL, 0, ct_297, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 298, "empty message", {0x48,0x42,0x61,0xeb,0xf7,0xe1,0xfb,0x66,0xe0,0xbc,0xaf,0xe8,0xf4,0xcc,0xf9,0xc5,0xac,0xcc,0x90,0x8f,0xdb,0x23,0xeb,0x7c,0x52,0x54,0xd6,0x14,0x07,0x2f,0x26,0xe1,0x06,0xb3,0x45,0x01,0xd1,0x3c,0x1d,0xad,0x1f,0x14,0x64,0x8c,0x6a,0x14,0x21,0x32,0xdd,0x7f,0x2f,0x12,0x68,0xdd,0x6b,0x70,0xfb,0xcd,0xe2,0xfe,0x98,0xf0,0x32,0x45}, 64, aad_298, 15, NULL, 0, ct_298, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 299, "empty message", {0x0b,0x6a,0xaf,0x05,0xf9,0xb5,0x22,0x1e,0x53,0x99,0x40,0xcd,0x83,0xcb,0x29,0xd2,0xbc,0xc7,0xa0,0xaa,0x47,0x2d,0x8f,0xc6,0x7b,0xed,0xd0,0x10,0x88,0x69,0x39,0x4e,0x33,0xc9,0xf2,0x33,0xd4,0xb2,0xcc,0x9c,0x6a,0x59,0xe8,0xce,0x9c,0xd2,0x68,0xa0,0xf3,0xf2,0x85,0x7e,0x08,0xfe,0x1e,0xb3,0x29,0xef,0x34,0x7d,0xac,0xe1,0x55,0x7d}, 64, aad_299, 16, NULL, 0, ct_299, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 300, "empty message", {0xd4,0x7a,0xb6,0xd5,0x1f,0x99,0xf4,0x24,0x9d,0xa5,0x6c,0x93,0xd1,0xf0,0x9e,0x85,0x62,0x31,0xf3,0xfe,0xd7,0x77,0xb3,0x03,0x11,0x1a,0xd3,0x10,0x79,0x27,0x08,0x39,0xe4,0xbc,0x4b,0x5d,0x86,0x23,0x16,0x2d,0x47,0x38,0xd7,0x08,0x03,0x93,0x4a,0x75,0xf4,0x57,0xfd,0xbf,0x4a,0x27,0x7b,0x82,0x8c,0xb6,0xe2,0x75,0x3e,0x88,0x70,0x2a}, 64, aad_300, 20, NULL, 0, ct_300, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 301, "empty message", {0xee,0xf6,0xbc,0xf1,0x6e,0xf7,0xae,0x17,0x32,0x6a,0x33,0xf2,0x2d,0x14,0x06,0xec,0x1b,0xd3,0xf8,0x66,0x50,0x5f,0x4b,0x2e,0x4f,0xe8,0xb4,0x5b,0xd6,0x2c,0xcb,0xd8,0x50,0x32,0xa9,0x89,0x9f,0xac,0xf2,0xdb,0x0c,0x93,0xa2,0x34,0x5c,0xb8,0x89,0x2a,0xfb,0x74,0xdb,0x54,0x97,0x81,0x21,0x1d,0xd8,0x88,0x1a,0x8c,0x8e,0x25,0xc1,0x71}, 64, aad_301, 32, NULL, 0, ct_301, 16, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 302, "message size divisible by block size", {0xc2,0x5c,0xaf,0xc6,0x01,0x8b,0x98,0xdf,0xbb,0x79,0xa4,0x0e,0xc8,0x9c,0x57,0x5a,0x4f,0x88,0xc4,0x11,0x64,0x89,0xbb,0xa2,0x77,0x07,0x47,0x98,0x00,0xc0,0x13,0x02,0x35,0x33,0x4a,0x45,0xdb,0xe8,0xd8,0xda,0xe3,0xda,0x8d,0xcb,0x45,0xbb,0xe5,0xdc,0xe0,0x31,0xb0,0xf6,0x8d,0xed,0x54,0x4f,0xda,0x7e,0xca,0x30,0xd6,0x74,0x94,0x42}, 64, aad_302, 16, msg_302, 16, ct_302, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 303, "message size divisible by block size", {0x27,0xfa,0xf9,0x7f,0xb3,0x03,0xaa,0x4f,0x2f,0x36,0x4e,0xdd,0x23,0x99,0x7f,0x4c,0x77,0xb8,0xe5,0x1e,0xbb,0x82,0x93,0xc5,0x9d,0xfb,0x1d,0x24,0xf0,0xfb,0x62,0x9f,0x6c,0x82,0x0f,0xc2,0xd9,0x1b,0xf4,0x8f,0x00,0x35,0xee,0xec,0x34,0x7e,0x37,0xec,0x4f,0xb0,0xcb,0x36,0x10,0x2b,0xcd,0xc5,0xa2,0x48,0xc4,0x7a,0x2f,0x97,0xea,0xb9}, 64, aad_303, 16, msg_303, 32, ct_303, 48, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 304, "message size divisible by block size", {0x97,0xbf,0xd0,0xf3,0xe9,0xbb,0x81,0x67,0xbb,0xb5,0x5f,0x4c,0xdc,0x14,0x52,0x9d,0x83,0x07,0xc0,0xec,0x2c,0x3f,0xe8,0xbc,0x88,0x52,0x2d,0x05,0xc1,0x26,0x1b,0xa4,0x60,0xc9,0xcb,0x41,0x16,0xf6,0x30,0xed,0xd7,0x4d,0x41,0x3e,0xc4,0x17,0x32,0x4c,0x6e,0x29,0xb5,0x66,0xfb,0x2d,0xd3,0xdf,0x18,0xe0,0x7b,0x53,0xb1,0xf9,0xf8,0x3b}, 64, aad_304, 16, msg_304, 48, ct_304, 64, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 305, "small plaintext size", {0xe2,0xc5,0x66,0x2b,0xb1,0x8f,0xbb,0x41,0x1d,0x03,0x04,0xe4,0x24,0x1d,0xb0,0x73,0xfe,0x60,0xa4,0x70,0x4f,0xee,0x29,0x00,0x73,0x51,0x30,0x38,0xa2,0x2b,0x4c,0xd5,0x42,0x58,0x0b,0x2b,0x4e,0xdb,0xc3,0x7e,0x3d,0xe0,0x1c,0x0c,0xb6,0x1a,0xbc,0xad,0x46,0x98,0x6c,0xdc,0x49,0x1c,0xe9,0xe5,0xae,0x5a,0xf2,0x23,0xff,0x58,0xb9,0x53}, 64, aad_305, 12, msg_305, 1, ct_305, 17, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 306, "small plaintext size", {0x3a,0xb0,0x62,0xdb,0xdd,0x38,0xb9,0x51,0xa9,0xfb,0x0d,0x8b,0xb1,0x85,0x95,0x9a,0x93,0xda,0xb3,0x49,0x6b,0x85,0x0a,0x30,0x62,0xb9,0x30,0x03,0x03,0x6c,0x8b,0xd2,0xaa,0xbb,0xf3,0x7d,0x5d,0x3f,0x6a,0x39,0x9d,0x4c,0xed,0xef,0xb7,0x0c,0x1b,0x8a,0x7b,0x45,0x63,0x9f,0xe1,0x18,0xc1,0x0e,0x39,0xf3,0x6f,0xa5,0x86,0x18,0xa8,0x4d}, 64, aad_306, 12, msg_306, 2, ct_306, 18, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 307, "small plaintext size", {0x9e,0x57,0x5c,0xd8,0x99,0x1b,0x32,0xf0,0x6f,0xba,0xf5,0x5a,0xd7,0x9e,0xb7,0x48,0x22,0x34,0x9e,0x07,0xfa,0x77,0xc4,0x09,0x84,0x8c,0x86,0x82,0x00,0x11,0x56,0x9f,0x26,0xdc,0xb4,0x9a,0xfa,0xea,0x19,0xa5,0x2a,0x96,0xb2,0x7e,0x67,0xf7,0x80,0xac,0x7a,0x00,0xda,0x9a,0x30,0x54,0xd1,0x67,0x8d,0x60,0x41,0x7c,0xf3,0x49,0x96,0xb1}, 64, aad_307, 12, msg_307, 3, ct_307, 19, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 308, "small plaintext size", {0x6d,0x43,0xcf,0xc9,0x30,0xa1,0xe0,0x05,0x1f,0x60,0x7d,0x0c,0x4a,0x76,0xad,0x5b,0xec,0x77,0xd9,0xf9,0x8b,0xbd,0x9a,0xe5,0xe5,0x6a,0x1d,0x65,0xfc,0xf1,0xbf,0x68,0xc7,0x78,0x0f,0x72,0x7b,0xfe,0x69,0x04,0x97,0xba,0xe4,0x78,0xaf,0xbc,0x4e,0xbf,0x7a,0x89,0x94,0x3e,0xe1,0x46,0xf7,0x2d,0x35,0x29,0x40,0x79,0x4f,0xf2,0x02,0xf4}, 64, aad_308, 12, msg_308, 4, ct_308, 20, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 309, "small plaintext size", {0x67,0x3c,0xea,0x58,0x2b,0xf3,0x98,0x2c,0xe3,0xfb,0xa5,0x30,0x4d,0xe8,0xfe,0x46,0xe3,0x16,0xd6,0x80,0x47,0x49,0xd6,0xdb,0x58,0xb7,0xab,0x7d,0x64,0xbd,0x4e,0x0a,0xf6,0x41,0x99,0x79,0x75,0x23,0x4f,0x8b,0x91,0x8c,0xca,0x32,0x47,0xd6,0x7c,0xfe,0xac,0x92,0x30,0xd1,0x5e,0xd2,0x8f,0x80,0x71,0xa8,0x5e,0x84,0xfa,0x9e,0xf2,0x11}, 64, aad_309, 12, msg_309, 5, ct_309, 21, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 310, "small plaintext size", {0x8f,0x13,0xf2,0xbf,0x02,0xd7,0x23,0x60,0xd9,0x95,0x8e,0xb8,0xaa,0x90,0x63,0x4a,0xe4,0x83,0x31,0xe7,0xdf,0xdb,0xf1,0x6f,0xc5,0x1c,0x72,0x38,0xae,0x9f,0x9d,0x50,0xd4,0x49,0x5d,0x19,0x66,0x76,0xef,0x52,0x59,0xb6,0x4a,0x61,0x63,0x05,0xff,0xaa,0xe5,0x17,0xc5,0x87,0xd4,0xe7,0xaf,0xba,0x40,0xe4,0xa2,0xc5,0xb0,0x98,0x91,0x82}, 64, aad_310, 12, msg_310, 6, ct_310, 22, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 311, "small plaintext size", {0x67,0xb3,0xab,0x00,0x07,0x5a,0x0e,0x3d,0x07,0xf3,0xfe,0x73,0xfa,0xbe,0xa5,0xd0,0x37,0x32,0x06,0xa0,0xaa,0xfa,0x93,0x97,0x98,0x19,0x24,0xdd,0xaf,0x2c,0xb2,0x83,0xc6,0x6a,0xf6,0x11,0x66,0x81,0x5d,0xff,0xbe,0x8f,0xaf,0xa6,0x88,0xb7,0x93,0xfd,0x25,0x9f,0xad,0x4a,0x1f,0x75,0xa2,0x59,0x34,0x2e,0x58,0x81,0x44,0x48,0xa4,0xb4}, 64, aad_311, 12, msg_311, 7, ct_311, 23, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 312, "small plaintext size", {0xa6,0x61,0xc6,0xa9,0x0f,0xd4,0x0d,0x8a,0x73,0x48,0x73,0xd6,0x6a,0xfd,0x44,0x77,0xc5,0x04,0x1c,0xdc,0x2b,0x31,0xa3,0xcd,0x0a,0xc3,0x60,0x4c,0xac,0x4f,0x74,0x41,0x12,0x19,0xe5,0x44,0x61,0x5b,0x56,0xe1,0x7f,0x57,0x74,0xb5,0x08,0x51,0x29,0xf6,0xdd,0x69,0x89,0x3b,0xb7,0x21,0x6b,0x53,0x9c,0xf4,0x2b,0x79,0xf0,0x06,0x82,0x78}, 64, aad_312, 12, msg_312, 8, ct_312, 24, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 313, "small plaintext size", {0xa4,0x0b,0x1c,0xc1,0x10,0xe1,0xaa,0x28,0xab,0x86,0xf7,0x14,0xab,0xd6,0xd3,0x13,0x01,0x69,0x89,0xa1,0xc8,0xcf,0xcb,0x62,0x06,0x3e,0x2c,0x39,0x6c,0xa1,0x2a,0x24,0x6d,0xe3,0xb9,0xbd,0x82,0x99,0x4e,0x5f,0x1c,0xb1,0x32,0x3f,0x78,0xa9,0xa0,0xed,0x02,0xfe,0x84,0x19,0x76,0xa6,0x59,0x42,0x36,0x03,0xd9,0x1c,0xcf,0x71,0xd5,0x8e}, 64, aad_313, 12, msg_313, 9, ct_313, 25, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 314, "small plaintext size", {0x8a,0xf0,0xe5,0x79,0x98,0xdd,0x68,0xb0,0xf4,0x5b,0x58,0xe7,0x08,0x40,0x5d,0x0a,0xd8,0x26,0x93,0x97,0x24,0x92,0x95,0xfd,0x33,0x60,0x96,0xe0,0x65,0xdb,0x2b,0xb1,0xe4,0x11,0x0d,0x55,0x07,0xc0,0x4d,0x73,0xc1,0x50,0xf6,0xe7,0xd8,0x7c,0xed,0x02,0x9a,0xb3,0x86,0x61,0xf2,0x01,0xec,0x77,0x87,0x4e,0x43,0x95,0x33,0x73,0xb3,0x8a}, 64, aad_314, 12, msg_314, 10, ct_314, 26, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 315, "small plaintext size", {0x6e,0x06,0x32,0x40,0xd8,0x3d,0x4a,0x90,0xe4,0x4e,0x56,0xe6,0x31,0xfe,0xfe,0x9f,0x6c,0x7c,0x7d,0x56,0x51,0x8e,0xff,0x3a,0x90,0x2d,0xdd,0x5c,0xa9,0xb8,0x37,0xa2,0x04,0x4b,0x37,0x27,0x57,0x1d,0x1c,0xa5,0x6a,0x68,0xab,0xfd,0x99,0x7d,0xa9,0x45,0xe4,0xd1,0x4f,0x71,0xdc,0x86,0xb0,0x14,0x9a,0x19,0xa9,0x3d,0x1e,0x5f,0xec,0x85}, 64, aad_315, 12, msg_315, 11, ct_315, 27, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 316, "small plaintext size", {0x95,0x93,0xf0,0xd6,0x67,0x9e,0x8e,0x18,0xb4,0x3c,0xb4,0xd2,0x6a,0x7e,0xa9,0xda,0x9d,0x60,0x37,0xfd,0x5a,0x82,0xdb,0x0b,0x09,0x1a,0x68,0x2b,0x65,0x47,0xa7,0x72,0x98,0xe4,0xfd,0x1d,0x14,0x81,0xf3,0x60,0x3d,0x0b,0x1e,0x7e,0x6d,0xcf,0x27,0x20,0x01,0x05,0xaf,0x0f,0x84,0x4f,0x2a,0xaa,0xcd,0x98,0x54,0x0a,0xb2,0xb6,0xc8,0xa8}, 64, aad_316, 12, msg_316, 12, ct_316, 28, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 317, "small plaintext size", {0x77,0xf7,0xdd,0x66,0x2a,0x8f,0x0a,0xaf,0x7f,0x19,0xc6,0x61,0x45,0x84,0xe4,0xac,0xf5,0xc7,0x74,0xd1,0x9e,0x10,0xd2,0x07,0x0e,0xaa,0x97,0x7e,0x9c,0x6b,0xa2,0x1b,0xa8,0x2f,0x0b,0xc8,0x49,0x39,0xcf,0x70,0x28,0x3d,0xca,0xc9,0xc6,0x45,0xb7,0x42,0x3c,0xa0,0xcc,0x94,0xba,0xc8,0x27,0xea,0x37,0x8f,0x1c,0xa0,0xc9,0xda,0x0e,0xee}, 64, aad_317, 12, msg_317, 13, ct_317, 29, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 318, "small plaintext size", {0x89,0x16,0xd0,0x34,0x20,0x01,0x56,0x19,0x22,0xe6,0x74,0xb0,0xcc,0x51,0xc0,0x5a,0x93,0x5e,0x5d,0xc4,0x5a,0x6d,0x62,0x84,0xf3,0x4a,0x4c,0x5c,0x79,0xe9,0x20,0x62,0xdc,0x30,0x91,0x21,0x75,0x84,0x60,0x7e,0x9c,0xf9,0x05,0x6a,0xa4,0x95,0xca,0x4c,0xd5,0x3f,0xd3,0xd4,0xc6,0xa9,0x4c,0x4b,0x38,0x40,0x07,0xe6,0x21,0x74,0x50,0x6b}, 64, aad_318, 12, msg_318, 14, ct_318, 30, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 319, "small plaintext size", {0x2a,0x93,0xa0,0xc3,0x77,0x97,0xbe,0xe0,0xc3,0x44,0xb9,0xce,0xed,0x1a,0x60,0x98,0x13,0xd8,0xc5,0xee,0x68,0x6d,0x26,0x0f,0x3a,0xa6,0xfc,0x2f,0x66,0xdc,0x59,0xf4,0x00,0x47,0x9d,0x1d,0xfe,0x04,0xe8,0x9e,0x6d,0xf6,0x08,0xa3,0xf6,0x99,0xff,0x1c,0xb4,0xe9,0xbf,0x24,0xa7,0x8f,0xb2,0xdf,0xdd,0xaa,0x00,0x11,0xa2,0xe4,0x02,0x08}, 64, aad_319, 12, msg_319, 15, ct_319, 31, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 320, "plaintext size > 16", {0x13,0x93,0x83,0xf3,0xf8,0x2d,0xc7,0x8e,0x0b,0x38,0x00,0x27,0xf9,0xe5,0xfc,0xd2,0xed,0x23,0x71,0x64,0x04,0xbe,0x5c,0x55,0x44,0x52,0xe4,0xdc,0x73,0xd2,0x37,0x02,0x65,0x94,0x49,0x18,0x20,0xc6,0xb8,0x29,0x71,0x85,0xcc,0x1f,0xa8,0x4f,0x49,0xa5,0xc7,0xd7,0xcd,0x05,0xc5,0xde,0x09,0x0f,0xf1,0xc3,0x39,0x7b,0xc2,0x74,0x04,0x37}, 64, aad_320, 12, msg_320, 17, ct_320, 33, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 321, "plaintext size > 16", {0xea,0xc9,0x6a,0x89,0xb8,0xe0,0xc9,0x28,0xa8,0x5c,0x91,0x39,0x63,0x46,0xef,0xe8,0x28,0x77,0x30,0x59,0x50,0x64,0x55,0x4c,0xd1,0x35,0x74,0xf8,0xb3,0x40,0xf5,0x41,0xc5,0xf0,0xbb,0x55,0xe6,0x54,0xe5,0x1b,0x05,0xe2,0x1b,0xa0,0x07,0x94,0x2c,0xab,0xab,0x5e,0xe1,0x02,0x09,0x22,0xf0,0xdd,0x00,0x21,0x96,0xa3,0x9d,0x7f,0xda,0x1d}, 64, aad_321, 12, msg_321, 20, ct_321, 36, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 322, "plaintext size > 16", {0xc0,0xf4,0xbe,0xde,0x68,0xc6,0xed,0x5a,0xd1,0x49,0x18,0xe2,0xdd,0xec,0xed,0x69,0x2d,0xfd,0x54,0x19,0xc0,0x42,0x04,0xd5,0xb9,0x6f,0x4c,0xa4,0x70,0x78,0xb0,0x70,0x28,0xc6,0xfb,0x87,0xb1,0xb4,0x90,0xd8,0x75,0xf0,0x70,0xbb,0xe4,0xd7,0x90,0xf6,0x5e,0x5d,0xf1,0x99,0x47,0xf0,0x2c,0x9d,0x3a,0x4e,0x49,0x3b,0x54,0x2d,0x02,0x91}, 64, aad_322, 12, msg_322, 31, ct_322, 47, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 323, "plaintext size > 16", {0xcd,0x86,0x89,0xf8,0x21,0x81,0x7f,0x59,0xbf,0xaa,0x75,0x51,0x31,0xf2,0x56,0x51,0x61,0xc7,0xf4,0x48,0x9f,0x89,0xb6,0x57,0xac,0x9f,0xa1,0x27,0xa9,0x76,0x85,0x35,0xa7,0x02,0xd0,0x01,0xb9,0xb9,0x9c,0xc1,0x1c,0x39,0x76,0x46,0x7b,0x1b,0x45,0x86,0x5f,0xf4,0x17,0xdc,0x25,0x6e,0xbb,0x50,0x79,0xb7,0xf1,0xb3,0xe0,0x83,0x07,0xb5}, 64, aad_323, 12, msg_323, 40, ct_323, 56, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 324, "plaintext size > 16", {0x72,0xa7,0x67,0x14,0xe0,0x17,0x1e,0x82,0x13,0xde,0x62,0x4f,0x00,0xe2,0x73,0xbc,0x90,0x00,0x50,0xe6,0x9d,0x25,0xc4,0x54,0xcc,0x42,0xb6,0x1e,0x8b,0x3f,0xbc,0x92,0xd4,0x94,0x2e,0x1a,0xe1,0x44,0x21,0xe1,0x64,0x04,0x6c,0x14,0x79,0xa7,0xb9,0xc9,0xf4,0xb5,0x0b,0x38,0x2c,0xb6,0x2d,0xfe,0xaa,0x21,0x0b,0x98,0xde,0xc7,0xd9,0x37}, 64, aad_324, 12, msg_324, 80, ct_324, 96, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 325, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_325, 16, ct_325, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 326, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, aad_326, 16, msg_326, 16, ct_326, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 327, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_327, 16, ct_327, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 328, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, aad_328, 16, msg_328, 16, ct_328, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 329, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_329, 16, ct_329, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 330, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, aad_330, 16, msg_330, 16, ct_330, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 331, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_331, 16, ct_331, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 332, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, aad_332, 16, msg_332, 16, ct_332, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 333, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_333, 16, ct_333, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 334, "edge case SIV", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, aad_334, 16, msg_334, 16, ct_334, 32, LTC_TEST_CASE_SHOULD_SUCCEED }, + { 335, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_335, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 336, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_336, 8, ct_336, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 337, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_337, 16, ct_337, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 338, "Flipped bit 0 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_338, 20, ct_338, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 339, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_339, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 340, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_340, 8, ct_340, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 341, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_341, 16, ct_341, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 342, "Flipped bit 1 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_342, 20, ct_342, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 343, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_343, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 344, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_344, 8, ct_344, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 345, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_345, 16, ct_345, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 346, "Flipped bit 7 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_346, 20, ct_346, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 347, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_347, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 348, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_348, 8, ct_348, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 349, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_349, 16, ct_349, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 350, "Flipped bit 8 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_350, 20, ct_350, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 351, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_351, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 352, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_352, 8, ct_352, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 353, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_353, 16, ct_353, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 354, "Flipped bit 31 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_354, 20, ct_354, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 355, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_355, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 356, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_356, 8, ct_356, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 357, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_357, 16, ct_357, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 358, "Flipped bit 32 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_358, 20, ct_358, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 359, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_359, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 360, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_360, 8, ct_360, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 361, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_361, 16, ct_361, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 362, "Flipped bit 33 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_362, 20, ct_362, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 363, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_363, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 364, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_364, 8, ct_364, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 365, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_365, 16, ct_365, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 366, "Flipped bit 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_366, 20, ct_366, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 367, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_367, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 368, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_368, 8, ct_368, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 369, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_369, 16, ct_369, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 370, "Flipped bit 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_370, 20, ct_370, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 371, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_371, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 372, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_372, 8, ct_372, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 373, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_373, 16, ct_373, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 374, "Flipped bit 71 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_374, 20, ct_374, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 375, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_375, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 376, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_376, 8, ct_376, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 377, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_377, 16, ct_377, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 378, "Flipped bit 77 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_378, 20, ct_378, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 379, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_379, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 380, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_380, 8, ct_380, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 381, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_381, 16, ct_381, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 382, "Flipped bit 80 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_382, 20, ct_382, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 383, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_383, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 384, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_384, 8, ct_384, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 385, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_385, 16, ct_385, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 386, "Flipped bit 96 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_386, 20, ct_386, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 387, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_387, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 388, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_388, 8, ct_388, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 389, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_389, 16, ct_389, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 390, "Flipped bit 97 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_390, 20, ct_390, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 391, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_391, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 392, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_392, 8, ct_392, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 393, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_393, 16, ct_393, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 394, "Flipped bit 103 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_394, 20, ct_394, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 395, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_395, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 396, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_396, 8, ct_396, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 397, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_397, 16, ct_397, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 398, "Flipped bit 120 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_398, 20, ct_398, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 399, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_399, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 400, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_400, 8, ct_400, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 401, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_401, 16, ct_401, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 402, "Flipped bit 121 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_402, 20, ct_402, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 403, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_403, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 404, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_404, 8, ct_404, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 405, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_405, 16, ct_405, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 406, "Flipped bit 126 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_406, 20, ct_406, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 407, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_407, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 408, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_408, 8, ct_408, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 409, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_409, 16, ct_409, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 410, "Flipped bit 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_410, 20, ct_410, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 411, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_411, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 412, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_412, 8, ct_412, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 413, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_413, 16, ct_413, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 414, "Flipped bits 0 and 64 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_414, 20, ct_414, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 415, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_415, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 416, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_416, 8, ct_416, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 417, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_417, 16, ct_417, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 418, "Flipped bits 31 and 63 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_418, 20, ct_418, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 419, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_419, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 420, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_420, 8, ct_420, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 421, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_421, 16, ct_421, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 422, "Flipped bits 63 and 127 in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_422, 20, ct_422, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 423, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_423, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 424, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_424, 8, ct_424, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 425, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_425, 16, ct_425, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 426, "all bits of tag flipped", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_426, 20, ct_426, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 427, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_427, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 428, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_428, 8, ct_428, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 429, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_429, 16, ct_429, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 430, "Tag changed to all zero", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_430, 20, ct_430, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 431, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_431, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 432, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_432, 8, ct_432, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 433, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_433, 16, ct_433, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 434, "tag changed to all 1", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_434, 20, ct_434, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 435, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_435, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 436, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_436, 8, ct_436, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 437, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_437, 16, ct_437, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 438, "msbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_438, 20, ct_438, 36, LTC_TEST_CASE_SHOULD_FAIL }, + { 439, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, NULL, 0, ct_439, 16, LTC_TEST_CASE_SHOULD_FAIL }, + { 440, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_440, 8, ct_440, 24, LTC_TEST_CASE_SHOULD_FAIL }, + { 441, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_441, 16, ct_441, 32, LTC_TEST_CASE_SHOULD_FAIL }, + { 442, "lsbs changed in tag", {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f}, 64, NULL, 0, msg_442, 20, ct_442, 36, LTC_TEST_CASE_SHOULD_FAIL }, +}; +#endif /* defined(LTC_TEST) && defined(LTC_SIV_MODE) */ diff --git a/tests/siv_wycheproof_test.c b/tests/siv_wycheproof_test.c new file mode 100644 index 000000000..e5ea4832d --- /dev/null +++ b/tests/siv_wycheproof_test.c @@ -0,0 +1,99 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +/* test SIV */ +#include + +#if defined(LTC_TEST) && defined(LTC_SIV_MODE) +#include "siv_wycheproof.h" + +/* typedef struct + * { + * int tcId; + * const char *comment; + * uint8_t key[64]; + * size_t keyLen; + * const uint8_t *aad; + * size_t aadLen; + * const uint8_t *msg; + * size_t msgLen; + * const uint8_t *ct; + * size_t ctLen; + * ltc_aes_siv_test_case_result result; + * } aes_siv_test_case; + */ +int siv_wycheproof_test(void) +{ + unsigned long n, buflen; + unsigned char buf[MAXBLOCKSIZE]; + const unsigned char *aad[2] = {0}; + unsigned long aadlen[2] = {0}; + int cipher; + cipher = find_cipher("aes"); + for (n = 0; n < LTC_ARRAY_SIZE(aes_siv_tests); ++n) { + XMEMSET(buf, 0, sizeof(buf)); + buflen = sizeof(buf); + if (aes_siv_tests[n].result == LTC_TEST_CASE_SHOULD_FAIL) { + SHOULD_FAIL(siv_memory(cipher, LTC_DECRYPT, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, + buf, &buflen, + 1, + aes_siv_tests[n].aad, aes_siv_tests[n].aadLen, + LTC_NULL)); + XMEMSET(buf, 0, sizeof(buf)); + buflen = sizeof(buf); + aad[0] = aes_siv_tests[n].aad; + aadlen[0] = aes_siv_tests[n].aadLen; + SHOULD_FAIL(siv_decrypt_memory(cipher, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + 1, + (const unsigned char **)aad, aadlen, + aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, + buf, &buflen)); + } else { + DO(siv_memory(cipher, LTC_ENCRYPT, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + aes_siv_tests[n].msg, aes_siv_tests[n].msgLen, + buf, &buflen, + 1, + aes_siv_tests[n].aad, aes_siv_tests[n].aadLen, + LTC_NULL)); + COMPARE_TESTVECTOR(buf, buflen, aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, aes_siv_tests[n].comment, aes_siv_tests[n].tcId); + XMEMSET(buf, 0, sizeof(buf)); + buflen = sizeof(buf); + DO(siv_memory(cipher, LTC_DECRYPT, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, + buf, &buflen, + 1, + aes_siv_tests[n].aad, aes_siv_tests[n].aadLen, + LTC_NULL)); + COMPARE_TESTVECTOR(buf, buflen, aes_siv_tests[n].msg, aes_siv_tests[n].msgLen, aes_siv_tests[n].comment, -aes_siv_tests[n].tcId); + + XMEMSET(buf, 0, sizeof(buf)); + buflen = sizeof(buf); + aad[0] = aes_siv_tests[n].aad; + aadlen[0] = aes_siv_tests[n].aadLen; + DO(siv_encrypt_memory(cipher, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + 1, + (const unsigned char **)aad, aadlen, + aes_siv_tests[n].msg, aes_siv_tests[n].msgLen, + buf, &buflen)); + COMPARE_TESTVECTOR(buf, buflen, aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, aes_siv_tests[n].comment, aes_siv_tests[n].tcId); + buflen = sizeof(buf); + DO(siv_decrypt_memory(cipher, + aes_siv_tests[n].key, aes_siv_tests[n].keyLen, + 1, + (const unsigned char **)aad, aadlen, + aes_siv_tests[n].ct, aes_siv_tests[n].ctLen, + buf, &buflen)); + COMPARE_TESTVECTOR(buf, buflen, aes_siv_tests[n].msg, aes_siv_tests[n].msgLen, aes_siv_tests[n].comment, -aes_siv_tests[n].tcId); + } + } + return CRYPT_OK; +} + +#else +int siv_wycheproof_test(void) { return CRYPT_NOP; } +#endif diff --git a/tests/sources.cmake b/tests/sources.cmake index b6eed361f..a24ae5d6c 100644 --- a/tests/sources.cmake +++ b/tests/sources.cmake @@ -1,4 +1,5 @@ set(SOURCES +argon2_test.c base16_test.c base32_test.c base64_test.c @@ -11,6 +12,7 @@ dh_test.c dsa_test.c ecc_test.c ed25519_test.c +ed448_test.c file_test.c mac_test.c misc_test.c @@ -30,9 +32,12 @@ pkcs_1_test.c prng_test.c rotate_test.c rsa_test.c +scrypt_test.c +siv_wycheproof_test.c ssh_test.c store_test.c test.c x25519_test.c +x448_test.c ) diff --git a/tests/test.c b/tests/test.c index e77b292cd..1d5bc6b8b 100644 --- a/tests/test.c +++ b/tests/test.c @@ -17,9 +17,9 @@ static const test_function test_functions[] = { LTC_TEST_FN(store_test), LTC_TEST_FN(rotate_test), + LTC_TEST_FN(cipher_hash_test), LTC_TEST_FN(misc_test), LTC_TEST_FN(mpi_test), - LTC_TEST_FN(cipher_hash_test), LTC_TEST_FN(mac_test), LTC_TEST_FN(modes_test), LTC_TEST_FN(der_test), @@ -34,6 +34,8 @@ static const test_function test_functions[] = LTC_TEST_FN(dsa_test), LTC_TEST_FN(ed25519_test), LTC_TEST_FN(x25519_test), + LTC_TEST_FN(ed448_test), + LTC_TEST_FN(x448_test), LTC_TEST_FN(file_test), LTC_TEST_FN(multi_test), LTC_TEST_FN(pem_test), @@ -204,12 +206,24 @@ static void s_unregister_all(void) unregister_hash(&md5_desc); #endif #ifdef LTC_SHA1 + /* `register_all_hashes()` does not register + * - `sha1_portable_desc` + * - `sha1_x86_desc` + * so we don't have to unregister them */ unregister_hash(&sha1_desc); #endif #ifdef LTC_SHA224 + /* `register_all_hashes()` does not register + * - `sha224_portable_desc` + * - `sha224_x86_desc` + * so we don't have to unregister them */ unregister_hash(&sha224_desc); #endif #ifdef LTC_SHA256 + /* `register_all_hashes()` does not register + * - `sha256_portable_desc` + * - `sha256_x86_desc` + * so we don't have to unregister them */ unregister_hash(&sha256_desc); #endif #ifdef LTC_SHA384 @@ -332,6 +346,9 @@ int main(int argc, char **argv) printf("LTC_VERSION = %s\n%s\n\n", GIT_VERSION, crypt_build_settings); + printf("AES-NI CPU support = %d\n", aesni_is_supported()); + printf("SHA-NI CPU support = %d\n\n", shani_is_supported()); + #ifdef USE_LTM mpi_provider = "ltm"; #elif defined(USE_TFM) diff --git a/tests/tomcrypt_test.h b/tests/tomcrypt_test.h index 4488a450c..3e6eaa03e 100644 --- a/tests/tomcrypt_test.h +++ b/tests/tomcrypt_test.h @@ -17,6 +17,7 @@ typedef struct { int cipher_hash_test(void); int modes_test(void); int mac_test(void); +int siv_wycheproof_test(void); int pkcs_1_test(void); int pkcs_1_pss_test(void); int pkcs_1_oaep_test(void); @@ -40,9 +41,13 @@ int prng_test(void); int mpi_test(void); int padding_test(void); int x25519_test(void); +int x448_test(void); int ed25519_test(void); +int ed448_test(void); int ssh_test(void); +int argon2_test(void); int bcrypt_test(void); +int scrypt_test(void); int no_null_termination_check_test(void); int pk_oid_test(void); int deprecated_test(void); diff --git a/tests/x448_test.c b/tests/x448_test.c new file mode 100644 index 000000000..aae4e0eb4 --- /dev/null +++ b/tests/x448_test.c @@ -0,0 +1,231 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ +#include "tomcrypt_test.h" + +#ifdef LTC_CURVE448 + +/* RFC 7748 Section 5.2 - X448 scalar multiplication test vectors */ +static int s_x448_rfc7748_scalarmult_test(void) +{ + /* First test vector */ + static const unsigned char k1[56] = { + 0x3d, 0x26, 0x2f, 0xdd, 0xf9, 0xec, 0x8e, 0x88, + 0x49, 0x52, 0x66, 0xfe, 0xa1, 0x9a, 0x34, 0xd2, + 0x88, 0x82, 0xac, 0xef, 0x04, 0x51, 0x04, 0xd0, + 0xd1, 0xaa, 0xe1, 0x21, 0x70, 0x0a, 0x77, 0x9c, + 0x98, 0x4c, 0x24, 0xf8, 0xcd, 0xd7, 0x8f, 0xbf, + 0xf4, 0x49, 0x43, 0xeb, 0xa3, 0x68, 0xf5, 0x4b, + 0x29, 0x25, 0x9a, 0x4f, 0x1c, 0x60, 0x0a, 0xd3 + }; + static const unsigned char u1[56] = { + 0x06, 0xfc, 0xe6, 0x40, 0xfa, 0x34, 0x87, 0xbf, + 0xda, 0x5f, 0x6c, 0xf2, 0xd5, 0x26, 0x3f, 0x8a, + 0xad, 0x88, 0x33, 0x4c, 0xbd, 0x07, 0x43, 0x7f, + 0x02, 0x0f, 0x08, 0xf9, 0x81, 0x4d, 0xc0, 0x31, + 0xdd, 0xbd, 0xc3, 0x8c, 0x19, 0xc6, 0xda, 0x25, + 0x83, 0xfa, 0x54, 0x29, 0xdb, 0x94, 0xad, 0xa1, + 0x8a, 0xa7, 0xa7, 0xfb, 0x4e, 0xf8, 0xa0, 0x86 + }; + static const unsigned char expected1[56] = { + 0xce, 0x3e, 0x4f, 0xf9, 0x5a, 0x60, 0xdc, 0x66, + 0x97, 0xda, 0x1d, 0xb1, 0xd8, 0x5e, 0x6a, 0xfb, + 0xdf, 0x79, 0xb5, 0x0a, 0x24, 0x12, 0xd7, 0x54, + 0x6d, 0x5f, 0x23, 0x9f, 0xe1, 0x4f, 0xba, 0xad, + 0xeb, 0x44, 0x5f, 0xc6, 0x6a, 0x01, 0xb0, 0x77, + 0x9d, 0x98, 0x22, 0x39, 0x61, 0x11, 0x1e, 0x21, + 0x76, 0x62, 0x82, 0xf7, 0x3d, 0xd9, 0x6b, 0x6f + }; + + /* Second test vector */ + static const unsigned char k2[56] = { + 0x20, 0x3d, 0x49, 0x44, 0x28, 0xb8, 0x39, 0x93, + 0x52, 0x66, 0x5d, 0xdc, 0xa4, 0x2f, 0x9d, 0xe8, + 0xfe, 0xf6, 0x00, 0x90, 0x8e, 0x0d, 0x46, 0x1c, + 0xb0, 0x21, 0xf8, 0xc5, 0x38, 0x34, 0x5d, 0xd7, + 0x7c, 0x3e, 0x48, 0x06, 0xe2, 0x5f, 0x46, 0xd3, + 0x31, 0x5c, 0x44, 0xe0, 0xa5, 0xb4, 0x37, 0x12, + 0x82, 0xdd, 0x2c, 0x8d, 0x5b, 0xe3, 0x09, 0x5b + }; + static const unsigned char u2[56] = { + 0x0f, 0xbc, 0xc2, 0xf9, 0x93, 0xcd, 0x56, 0xd3, + 0x30, 0x5b, 0x0b, 0x7d, 0x9e, 0x55, 0xd4, 0xc1, + 0xa8, 0xfb, 0x5d, 0xbb, 0x52, 0xf8, 0xe9, 0xa1, + 0xe9, 0xb6, 0x20, 0x1b, 0x16, 0x5d, 0x01, 0x58, + 0x94, 0xe5, 0x6c, 0x4d, 0x35, 0x70, 0xbe, 0xe5, + 0x2f, 0xe2, 0x05, 0xe2, 0x8a, 0x78, 0xb9, 0x1c, + 0xdf, 0xbd, 0xe7, 0x1c, 0xe8, 0xd1, 0x57, 0xdb + }; + static const unsigned char expected2[56] = { + 0xe4, 0x3a, 0x6e, 0x84, 0xc5, 0x41, 0x24, 0x19, + 0x69, 0xe1, 0xbc, 0x13, 0xaf, 0xae, 0xba, 0x34, + 0xe8, 0xe0, 0x91, 0x22, 0xaf, 0x0f, 0xaf, 0x6a, + 0x45, 0xf8, 0xd2, 0x51, 0x38, 0xb4, 0x80, 0x0f, + 0x07, 0xc8, 0x62, 0xd8, 0x04, 0xac, 0xaf, 0x18, + 0xd2, 0xc5, 0xf5, 0x02, 0x76, 0xcd, 0xf0, 0xbd, + 0x06, 0x8e, 0x95, 0x73, 0x73, 0xd3, 0x52, 0x97 + }; + + unsigned char out[56]; + + ec448_scalarmult_internal(out, k1, u1); + COMPARE_TESTVECTOR(out, 56, expected1, 56, "X448 RFC7748 5.2 #1", 0); + + ec448_scalarmult_internal(out, k2, u2); + COMPARE_TESTVECTOR(out, 56, expected2, 56, "X448 RFC7748 5.2 #2", 1); + + return CRYPT_OK; +} + +/* RFC 7748 Section 5.2 - X448 iterative scalar multiplication test + * + * Start with k = u = 5 (as 56-byte little-endian). + * Each iteration: out = X448(k, u), then u = old_k, k = out. + */ +static int s_x448_rfc7748_iter_test(void) +{ + /* Expected result after 1 iteration */ + static const unsigned char expected_1[56] = { + 0x3f, 0x48, 0x2c, 0x8a, 0x9f, 0x19, 0xb0, 0x1e, + 0x6c, 0x46, 0xee, 0x97, 0x11, 0xd9, 0xdc, 0x14, + 0xfd, 0x4b, 0xf6, 0x7a, 0xf3, 0x07, 0x65, 0xc2, + 0xae, 0x2b, 0x84, 0x6a, 0x4d, 0x23, 0xa8, 0xcd, + 0x0d, 0xb8, 0x97, 0x08, 0x62, 0x39, 0x49, 0x2c, + 0xaf, 0x35, 0x0b, 0x51, 0xf8, 0x33, 0x86, 0x8b, + 0x9b, 0xc2, 0xb3, 0xbc, 0xa9, 0xcf, 0x41, 0x13 + }; + + /* Expected result after 1000 iterations */ + static const unsigned char expected_1000[56] = { + 0xaa, 0x3b, 0x47, 0x49, 0xd5, 0x5b, 0x9d, 0xaf, + 0x1e, 0x5b, 0x00, 0x28, 0x88, 0x26, 0xc4, 0x67, + 0x27, 0x4c, 0xe3, 0xeb, 0xbd, 0xd5, 0xc1, 0x7b, + 0x97, 0x5e, 0x09, 0xd4, 0xaf, 0x6c, 0x67, 0xcf, + 0x10, 0xd0, 0x87, 0x20, 0x2d, 0xb8, 0x82, 0x86, + 0xe2, 0xb7, 0x9f, 0xce, 0xea, 0x3e, 0xc3, 0x53, + 0xef, 0x54, 0xfa, 0xa2, 0x6e, 0x21, 0x9f, 0x38 + }; + + unsigned char k[56], u[56], out[56], tmp[56]; + unsigned long i; + + /* k = u = 5 (little-endian) */ + XMEMSET(k, 0, 56); + XMEMSET(u, 0, 56); + k[0] = 5; + u[0] = 5; + + /* 1 iteration */ + ec448_scalarmult_internal(out, k, u); + XMEMCPY(u, k, 56); + XMEMCPY(k, out, 56); + COMPARE_TESTVECTOR(k, 56, expected_1, 56, "X448 RFC7748 iter=1", 0); + + /* Continue to 1000 iterations (we already did 1) */ + for (i = 1; i < 1000; i++) { + ec448_scalarmult_internal(out, k, u); + XMEMCPY(tmp, k, 56); + XMEMCPY(k, out, 56); + XMEMCPY(u, tmp, 56); + } + COMPARE_TESTVECTOR(k, 56, expected_1000, 56, "X448 RFC7748 iter=1000", 1); + + return CRYPT_OK; +} + +static int s_x448_keygen_dh_test(void) +{ + curve448_key alice, bob; + unsigned char ss_a[56], ss_b[56]; + unsigned long sslen; + int prng_idx; + + prng_idx = find_prng("yarrow"); + + /* Generate two key pairs */ + DO(x448_make_key(&yarrow_prng, prng_idx, &alice)); + DO(x448_make_key(&yarrow_prng, prng_idx, &bob)); + ENSURE(alice.type == PK_PRIVATE); + ENSURE(alice.pka == LTC_PKA_X448); + + /* DH: both sides compute the same shared secret */ + sslen = sizeof(ss_a); + DO(x448_shared_secret(&alice, &bob, ss_a, &sslen)); + ENSURE(sslen == 56); + + sslen = sizeof(ss_b); + DO(x448_shared_secret(&bob, &alice, ss_b, &sslen)); + ENSURE(sslen == 56); + + COMPARE_TESTVECTOR(ss_a, 56, ss_b, 56, "X448 DH shared secret", 0); + + /* Export/import raw round-trip */ + { + curve448_key imported; + unsigned char buf[56]; + unsigned long buflen = sizeof(buf); + + DO(x448_export(buf, &buflen, PK_PUBLIC, &alice)); + ENSURE(buflen == 56); + DO(x448_import_raw(buf, buflen, PK_PUBLIC, &imported)); + ENSURE(imported.type == PK_PUBLIC); + ENSURE(imported.pka == LTC_PKA_X448); + COMPARE_TESTVECTOR(imported.pub, 56, alice.pub, 56, "X448 import_raw pub", 0); + } + + return CRYPT_OK; +} + +/* Export/import round-trip (requires MPI for DER/PKCS8) */ +static int s_x448_compat_test(void) +{ + curve448_key priv, pub, imported; + unsigned char buf[1024]; + unsigned long buflen; + int prng_idx = find_prng("yarrow"); + + XMEMSET(&priv, 0, sizeof(priv)); + XMEMSET(&pub, 0, sizeof(pub)); + XMEMSET(&imported, 0, sizeof(imported)); + + DO(x448_make_key(&yarrow_prng, prng_idx, &priv)); + + /* private PKCS#8 export -> import */ + buflen = sizeof(buf); + DO(x448_export(buf, &buflen, PK_PRIVATE | PK_STD, &priv)); + DO(x448_import_pkcs8(buf, buflen, NULL, &imported)); + COMPARE_TESTVECTOR(&priv, sizeof(priv), &imported, sizeof(imported), "X448 priv pkcs8 round-trip", __LINE__); + XMEMSET(&imported, 0, sizeof(imported)); + + /* public raw export -> import */ + buflen = sizeof(buf); + DO(x448_export(buf, &buflen, PK_PUBLIC, &priv)); + DO(x448_import_raw(buf, buflen, PK_PUBLIC, &pub)); + + /* public DER export -> import */ + buflen = sizeof(buf); + DO(x448_export(buf, &buflen, PK_PUBLIC | PK_STD, &priv)); + DO(x448_import(buf, buflen, &imported)); + COMPARE_TESTVECTOR(&pub, sizeof(pub), &imported, sizeof(imported), "X448 pub DER round-trip", __LINE__); + + return CRYPT_OK; +} + +int x448_test(void) +{ + DO(s_x448_rfc7748_scalarmult_test()); + DO(s_x448_rfc7748_iter_test()); + DO(s_x448_keygen_dh_test()); + if (ltc_mp.name != NULL) { + DO(s_x448_compat_test()); + } + return CRYPT_OK; +} + +#else + +int x448_test(void) +{ + return CRYPT_NOP; +} + +#endif