├── poly1305.h ├── README.md ├── chacha.h ├── .travis.yml ├── cipherseed.h ├── sha2.h ├── bench.c ├── poly1305.c ├── chacha.c ├── cipherseed.c ├── tests.c └── sha2.c /poly1305.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */ 2 | 3 | /* 4 | * Public Domain poly1305 from Andrew Moon 5 | * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna 6 | */ 7 | 8 | #ifndef POLY1305_H 9 | #define POLY1305_H 10 | 11 | #include 12 | #include 13 | 14 | #define POLY1305_KEYLEN 32 15 | #define POLY1305_TAGLEN 16 16 | 17 | void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen, 18 | const uint8_t key[POLY1305_KEYLEN]) 19 | __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN))) 20 | __attribute__((__bounded__(__buffer__, 2, 3))) 21 | __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN))); 22 | 23 | #endif /* POLY1305_H */ 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/jonasschnelli/cipherseed.svg?branch=master)](https://travis-ci.org/jonasschnelli/cipherseed) 2 | 3 | cipherseed 4 | ===== 5 | 6 | Cipherseed is a scheme to encrypt 128 or 256bit entropy plus metadata with chacha20 and add two poly1305 MAC tags to allow a pratical form of plausible deniability 7 | 8 | 9 | 128bit/256bit entropy 10 | ---------------- 11 | * 1 byte header unencrypted 12 | * 5 byte unencrypted pbkdf2-salt 13 | * 3 byte header encrypted (1 byte type, 2 byte birthday) 14 | * 16/32 byte encrypted entropy 15 | * 4 byte primary MAC tag (tag covers salt || encrypted header || encrypted entropy) 16 | * 4 byte secondary MAC tag (tag covers salt || encrypted header || encrypted entropy) 17 | * = Total 33/49 bytes 18 | * 33 bytes == 264 bits == 24 word mnemonic == 53 base32 chars (without checksum/hrp) 19 | * 49 bytes == 392 bits == 36 word mnemonic == 79 base32 chars (without checksum/hrp) 20 | 21 | 22 | Compile / Test 23 | ===== 24 | ``` 25 | gcc -O0 -g sha2.c chacha.c poly1305.c cipherseed.c tests.c -o test 26 | ./test 27 | ``` 28 | -------------------------------------------------------------------------------- /chacha.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */ 2 | 3 | /* 4 | chacha-merged.c version 20080118 5 | D. J. Bernstein 6 | Public domain. 7 | */ 8 | 9 | #ifndef CHACHA_H 10 | #define CHACHA_H 11 | 12 | #include 13 | #include 14 | 15 | struct chacha_ctx { 16 | uint32_t input[16]; 17 | }; 18 | 19 | #define CHACHA_MINKEYLEN 16 20 | #define CHACHA_NONCELEN 8 21 | #define CHACHA_CTRLEN 8 22 | #define CHACHA_STATELEN (CHACHA_NONCELEN + CHACHA_CTRLEN) 23 | #define CHACHA_BLOCKLEN 64 24 | 25 | void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits) 26 | __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN))); 27 | void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr) 28 | __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN))) 29 | __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN))); 30 | void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m, uint8_t *c, 31 | uint32_t bytes) 32 | __attribute__((__bounded__(__buffer__, 2, 4))) 33 | __attribute__((__bounded__(__buffer__, 3, 4))); 34 | 35 | #endif /* CHACHA_H */ 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | os: 3 | - osx 4 | - linux 5 | 6 | compiler: 7 | - clang 8 | - gcc 9 | - x86_64-w64-mingw32-gcc 10 | 11 | addons: 12 | apt: 13 | packages: 14 | - valgrind 15 | - binutils-mingw-w64 16 | - gcc-mingw-w64 17 | - wine 18 | 19 | before_install: 20 | - pip install --user cpp-coveralls 21 | - if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew install valgrind gnu-sed --default-names; fi 22 | 23 | matrix: 24 | fast_finish: 25 | - true 26 | exclude: 27 | - os: osx 28 | compiler: x86_64-w64-mingw32-gcc 29 | 30 | script: 31 | - $CC -O3 poly1305.c chacha.c chachapoly_aead.c bench.c -o bench 32 | - rm *.o 33 | - $CC -O0 -g poly1305.c chacha.c chachapoly_aead.c tests.c -o test 34 | - if ( [ "${TRAVIS_OS_NAME}" == "linux" ] ) && ( [ "$CC" == "gcc" ] ); then 35 | valgrind --track-origins=yes --leak-check=full --error-exitcode=1 ./test; 36 | ./test; 37 | else 38 | if ( [ "$CC" == x86_64-w64-mingw32-gcc ] ) || ( [ "$CC" == i686-w64-mingw32-gcc ] ); then 39 | ls -la; 40 | else 41 | ./test; 42 | fi 43 | fi 44 | -------------------------------------------------------------------------------- /cipherseed.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2018 Jonas Schnelli 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 21 | OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | // the used PBKDF2 salt is 'btcseed'+random-5byte-salt (12 bytes total) 32 | static uint8_t PBKDF2_SALTPREFIX[7] = {'b', 't', 'c', 's', 'e', 'e', 'd'}; 33 | #define PBKDF2_SALTLEN 5 34 | #define PBKDF2_ROUNDS 20480 35 | #define PBKDF2_HMACLEN 64 36 | 37 | void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, 38 | const uint8_t salt_in[PBKDF2_SALTLEN], uint8_t *key, 39 | int keylen); 40 | 41 | int encrypt_seed(const uint8_t key256[32], const uint8_t key256_sec[32], 42 | const uint8_t *seed, unsigned int seedlen, 43 | const uint8_t *salt_5bytes, const uint16_t bday_15bit, 44 | const uint8_t type, uint8_t *dest, int is_encrypt); 45 | 46 | int decrypt_seed(const uint8_t key256[32], const uint8_t *payload, 47 | unsigned int payload_len, uint16_t *bday_15bit_out, 48 | uint8_t *type_out, uint8_t *seed_out); 49 | -------------------------------------------------------------------------------- /sha2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2000-2001 Aaron D. Gifford 3 | * Copyright (c) 2013 Pavol Rusnak 4 | * Copyright (c) 2015 Jonas Schnelli 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the copyright holder nor the names of contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #ifndef __SHA2_H__ 33 | #define __SHA2_H__ 34 | 35 | #define SHA256_BLOCK_LENGTH 64 36 | #define SHA256_DIGEST_LENGTH 32 37 | #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) 38 | #define SHA512_BLOCK_LENGTH 128 39 | #define SHA512_DIGEST_LENGTH 64 40 | #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) 41 | 42 | typedef struct _SHA256_CTX { 43 | uint32_t state[8]; 44 | uint64_t bitcount; 45 | uint8_t buffer[SHA256_BLOCK_LENGTH]; 46 | } SHA256_CTX; 47 | 48 | typedef struct _SHA512_CTX { 49 | uint64_t state[8]; 50 | uint64_t bitcount[2]; 51 | uint8_t buffer[SHA512_BLOCK_LENGTH]; 52 | } SHA512_CTX; 53 | 54 | void sha256_Init(SHA256_CTX*); 55 | void sha256_Update(SHA256_CTX*, const uint8_t*, size_t); 56 | void sha256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); 57 | void sha256_Raw(const uint8_t*, size_t, uint8_t[SHA256_DIGEST_LENGTH]); 58 | 59 | void sha512_Init(SHA512_CTX*); 60 | void sha512_Update(SHA512_CTX*, const uint8_t*, size_t); 61 | void sha512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); 62 | void sha512_Raw(const uint8_t*, size_t, uint8_t[SHA512_DIGEST_LENGTH]); 63 | 64 | void hmac_sha256(const uint8_t* key, const uint32_t keylen, const uint8_t* msg, const uint32_t msglen, uint8_t* hmac); 65 | void hmac_sha512(const uint8_t* key, const uint32_t keylen, const uint8_t* msg, const uint32_t msglen, uint8_t* hmac); 66 | 67 | #endif // __SHA2_H__ 68 | -------------------------------------------------------------------------------- /bench.c: -------------------------------------------------------------------------------- 1 | #include "sys/time.h" 2 | #include 3 | #include 4 | 5 | #include "chachapoly_aead.h" 6 | #include "poly1305.h" 7 | 8 | static const uint8_t testkey[32] = { 9 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 10 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 11 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; 12 | 13 | static const uint8_t testnonce[32] = {0x00, 0x01, 0x02, 0x03, 14 | 0x04, 0x05, 0x06, 0x07}; 15 | 16 | static const uint8_t testdata[12] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 17 | 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21}; 18 | 19 | static const uint64_t BUFFER_SIZE = 1000 * 1000; 20 | 21 | static const uint8_t aead_keys[64] = { 22 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 23 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 24 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 28 | 29 | static double gettimedouble(void) { 30 | struct timeval tv; 31 | gettimeofday(&tv, NULL); 32 | return tv.tv_usec * 0.000001 + tv.tv_sec; 33 | } 34 | 35 | static void print_number(double x) { 36 | double y = x; 37 | int c = 0; 38 | if (y < 0.0) { 39 | y = -y; 40 | } 41 | while (y < 100.0) { 42 | y *= 10.0; 43 | c++; 44 | } 45 | printf("%.*f", c, x); 46 | } 47 | 48 | static void run_benchmark(char *name, void (*benchmark)(void *), 49 | void (*setup)(void *), void (*teardown)(void *), 50 | void *data, int count, int iter) { 51 | int i; 52 | double min = HUGE_VAL; 53 | double sum = 0.0; 54 | double max = 0.0; 55 | for (i = 0; i < count; i++) { 56 | double begin, total; 57 | if (setup != NULL) { 58 | setup(data); 59 | } 60 | begin = gettimedouble(); 61 | benchmark(data); 62 | total = gettimedouble() - begin; 63 | if (teardown != NULL) { 64 | teardown(data); 65 | } 66 | if (total < min) { 67 | min = total; 68 | } 69 | if (total > max) { 70 | max = total; 71 | } 72 | sum += total; 73 | } 74 | printf("%s: min ", name); 75 | print_number(min * 1000000000.0 / iter); 76 | printf("ns / avg "); 77 | print_number((sum / count) * 1000000000.0 / iter); 78 | printf("ns / max "); 79 | print_number(max * 1000000000.0 / iter); 80 | printf("ns\n"); 81 | } 82 | 83 | static void bench_chacha_ivsetup(void *data) { 84 | struct chacha_ctx *ctx = (struct chacha_ctx *)data; 85 | int i; 86 | for (i = 0; i < 50000; i++) { 87 | chacha_ivsetup(ctx, testnonce, NULL); 88 | } 89 | } 90 | 91 | static void bench_chacha_keysetup(void *data) { 92 | struct chacha_ctx *ctx = (struct chacha_ctx *)data; 93 | int i; 94 | for (i = 0; i < 50000; i++) { 95 | chacha_keysetup(ctx, testkey, 256); 96 | } 97 | } 98 | 99 | static void bench_chacha_encrypt(void *data) { 100 | struct chacha_ctx *ctx = (struct chacha_ctx *)data; 101 | uint8_t scratch[16] = {0}; 102 | int i; 103 | for (i = 0; i < 4000000 / 16; i++) { 104 | chacha_encrypt_bytes(ctx, scratch, scratch, 16); 105 | } 106 | } 107 | 108 | static void bench_poly1305_auth(void *data) { 109 | struct chacha_ctx *ctx = (struct chacha_ctx *)data; 110 | uint8_t poly1305_tag[16] = {0}; 111 | int i; 112 | for (i = 0; i < 4000000 / 12; i++) { 113 | poly1305_auth(poly1305_tag, testdata, 12, testkey); 114 | } 115 | } 116 | 117 | static void bench_chacha20poly1305_init(void *data) { 118 | struct chachapolyaead_ctx *ctx = (struct chachapolyaead_ctx *)data; 119 | int i; 120 | for (i = 0; i < 50000; i++) { 121 | chacha20poly1305_init(ctx, aead_keys, 64); 122 | } 123 | } 124 | 125 | static void bench_chacha20poly1305_crypt(void *data) { 126 | struct chachapolyaead_ctx *ctx = (struct chachapolyaead_ctx *)data; 127 | int i; 128 | uint32_t seqnr = 0; 129 | 130 | uint8_t buffer[BUFFER_SIZE + 16]; 131 | for (i = 0; i < 30; i++) { 132 | chacha20poly1305_crypt(ctx, seqnr, buffer, buffer, BUFFER_SIZE - 4, 4, 1); 133 | } 134 | } 135 | 136 | int main(void) { 137 | struct chacha_ctx ctx_chacha; 138 | struct chachapolyaead_ctx aead_ctx; 139 | run_benchmark("chacha_ivsetup", bench_chacha_ivsetup, NULL, NULL, &ctx_chacha, 140 | 20, 50000); 141 | run_benchmark("chacha_keysetup", bench_chacha_keysetup, NULL, NULL, 142 | &ctx_chacha, 20, 50000); 143 | run_benchmark("chacha_encrypt", bench_chacha_encrypt, NULL, NULL, &ctx_chacha, 144 | 20, 4000000); 145 | run_benchmark("poly1305_auth", bench_poly1305_auth, NULL, NULL, &ctx_chacha, 146 | 20, 4000000); 147 | run_benchmark("chacha20poly1305_init", bench_chacha20poly1305_init, NULL, 148 | NULL, &aead_ctx, 20, 4000000); 149 | run_benchmark("chacha20poly1305_crypt 1MB", bench_chacha20poly1305_crypt, 150 | NULL, NULL, &aead_ctx, 20, 30); 151 | return 0; 152 | } -------------------------------------------------------------------------------- /poly1305.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Public Domain poly1305 from Andrew Moon 3 | * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna 4 | */ 5 | 6 | /* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */ 7 | 8 | #include "poly1305.h" 9 | 10 | #define mul32x32_64(a, b) ((uint64_t)(a) * (b)) 11 | 12 | #define U8TO32_LE(p) \ 13 | (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ 14 | ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) 15 | 16 | #define U32TO8_LE(p, v) \ 17 | do { \ 18 | (p)[0] = (uint8_t)((v)); \ 19 | (p)[1] = (uint8_t)((v) >> 8); \ 20 | (p)[2] = (uint8_t)((v) >> 16); \ 21 | (p)[3] = (uint8_t)((v) >> 24); \ 22 | } while (0) 23 | 24 | void poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, 25 | size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { 26 | uint32_t t0, t1, t2, t3; 27 | uint32_t h0, h1, h2, h3, h4; 28 | uint32_t r0, r1, r2, r3, r4; 29 | uint32_t s1, s2, s3, s4; 30 | uint32_t b, nb; 31 | size_t j; 32 | uint64_t t[5]; 33 | uint64_t f0, f1, f2, f3; 34 | uint32_t g0, g1, g2, g3, g4; 35 | uint64_t c; 36 | unsigned char mp[16]; 37 | 38 | /* clamp key */ 39 | t0 = U8TO32_LE(key + 0); 40 | t1 = U8TO32_LE(key + 4); 41 | t2 = U8TO32_LE(key + 8); 42 | t3 = U8TO32_LE(key + 12); 43 | 44 | /* precompute multipliers */ 45 | r0 = t0 & 0x3ffffff; 46 | t0 >>= 26; 47 | t0 |= t1 << 6; 48 | r1 = t0 & 0x3ffff03; 49 | t1 >>= 20; 50 | t1 |= t2 << 12; 51 | r2 = t1 & 0x3ffc0ff; 52 | t2 >>= 14; 53 | t2 |= t3 << 18; 54 | r3 = t2 & 0x3f03fff; 55 | t3 >>= 8; 56 | r4 = t3 & 0x00fffff; 57 | 58 | s1 = r1 * 5; 59 | s2 = r2 * 5; 60 | s3 = r3 * 5; 61 | s4 = r4 * 5; 62 | 63 | /* init state */ 64 | h0 = 0; 65 | h1 = 0; 66 | h2 = 0; 67 | h3 = 0; 68 | h4 = 0; 69 | 70 | /* full blocks */ 71 | if (inlen < 16) 72 | goto poly1305_donna_atmost15bytes; 73 | poly1305_donna_16bytes: 74 | m += 16; 75 | inlen -= 16; 76 | 77 | t0 = U8TO32_LE(m - 16); 78 | t1 = U8TO32_LE(m - 12); 79 | t2 = U8TO32_LE(m - 8); 80 | t3 = U8TO32_LE(m - 4); 81 | 82 | h0 += t0 & 0x3ffffff; 83 | h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; 84 | h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; 85 | h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; 86 | h4 += (t3 >> 8) | (1 << 24); 87 | 88 | poly1305_donna_mul: 89 | t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) + 90 | mul32x32_64(h3, s2) + mul32x32_64(h4, s1); 91 | t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) + 92 | mul32x32_64(h3, s3) + mul32x32_64(h4, s2); 93 | t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) + 94 | mul32x32_64(h3, s4) + mul32x32_64(h4, s3); 95 | t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) + 96 | mul32x32_64(h3, r0) + mul32x32_64(h4, s4); 97 | t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) + 98 | mul32x32_64(h3, r1) + mul32x32_64(h4, r0); 99 | 100 | h0 = (uint32_t)t[0] & 0x3ffffff; 101 | c = (t[0] >> 26); 102 | t[1] += c; 103 | h1 = (uint32_t)t[1] & 0x3ffffff; 104 | b = (uint32_t)(t[1] >> 26); 105 | t[2] += b; 106 | h2 = (uint32_t)t[2] & 0x3ffffff; 107 | b = (uint32_t)(t[2] >> 26); 108 | t[3] += b; 109 | h3 = (uint32_t)t[3] & 0x3ffffff; 110 | b = (uint32_t)(t[3] >> 26); 111 | t[4] += b; 112 | h4 = (uint32_t)t[4] & 0x3ffffff; 113 | b = (uint32_t)(t[4] >> 26); 114 | h0 += b * 5; 115 | 116 | if (inlen >= 16) 117 | goto poly1305_donna_16bytes; 118 | 119 | /* final bytes */ 120 | poly1305_donna_atmost15bytes: 121 | if (!inlen) 122 | goto poly1305_donna_finish; 123 | 124 | for (j = 0; j < inlen; j++) 125 | mp[j] = m[j]; 126 | mp[j++] = 1; 127 | for (; j < 16; j++) 128 | mp[j] = 0; 129 | inlen = 0; 130 | 131 | t0 = U8TO32_LE(mp + 0); 132 | t1 = U8TO32_LE(mp + 4); 133 | t2 = U8TO32_LE(mp + 8); 134 | t3 = U8TO32_LE(mp + 12); 135 | 136 | h0 += t0 & 0x3ffffff; 137 | h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; 138 | h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; 139 | h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; 140 | h4 += (t3 >> 8); 141 | 142 | goto poly1305_donna_mul; 143 | 144 | poly1305_donna_finish: 145 | b = h0 >> 26; 146 | h0 = h0 & 0x3ffffff; 147 | h1 += b; 148 | b = h1 >> 26; 149 | h1 = h1 & 0x3ffffff; 150 | h2 += b; 151 | b = h2 >> 26; 152 | h2 = h2 & 0x3ffffff; 153 | h3 += b; 154 | b = h3 >> 26; 155 | h3 = h3 & 0x3ffffff; 156 | h4 += b; 157 | b = h4 >> 26; 158 | h4 = h4 & 0x3ffffff; 159 | h0 += b * 5; 160 | b = h0 >> 26; 161 | h0 = h0 & 0x3ffffff; 162 | h1 += b; 163 | 164 | g0 = h0 + 5; 165 | b = g0 >> 26; 166 | g0 &= 0x3ffffff; 167 | g1 = h1 + b; 168 | b = g1 >> 26; 169 | g1 &= 0x3ffffff; 170 | g2 = h2 + b; 171 | b = g2 >> 26; 172 | g2 &= 0x3ffffff; 173 | g3 = h3 + b; 174 | b = g3 >> 26; 175 | g3 &= 0x3ffffff; 176 | g4 = h4 + b - (1 << 26); 177 | 178 | b = (g4 >> 31) - 1; 179 | nb = ~b; 180 | h0 = (h0 & nb) | (g0 & b); 181 | h1 = (h1 & nb) | (g1 & b); 182 | h2 = (h2 & nb) | (g2 & b); 183 | h3 = (h3 & nb) | (g3 & b); 184 | h4 = (h4 & nb) | (g4 & b); 185 | 186 | f0 = ((h0) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]); 187 | f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]); 188 | f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]); 189 | f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]); 190 | 191 | U32TO8_LE(&out[0], f0); 192 | f1 += (f0 >> 32); 193 | U32TO8_LE(&out[4], f1); 194 | f2 += (f1 >> 32); 195 | U32TO8_LE(&out[8], f2); 196 | f3 += (f2 >> 32); 197 | U32TO8_LE(&out[12], f3); 198 | } 199 | -------------------------------------------------------------------------------- /chacha.c: -------------------------------------------------------------------------------- 1 | /* 2 | chacha-merged.c version 20080118 3 | D. J. Bernstein 4 | Public domain. 5 | */ 6 | 7 | #include "chacha.h" 8 | 9 | /* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */ 10 | 11 | typedef unsigned char u8; 12 | typedef unsigned int u32; 13 | 14 | typedef struct chacha_ctx chacha_ctx; 15 | 16 | #define U8C(v) (v##U) 17 | #define U32C(v) (v##U) 18 | 19 | #define U8V(v) ((u8)(v)&U8C(0xFF)) 20 | #define U32V(v) ((u32)(v)&U32C(0xFFFFFFFF)) 21 | 22 | #define ROTL32(v, n) (U32V((v) << (n)) | ((v) >> (32 - (n)))) 23 | 24 | #define U8TO32_LITTLE(p) \ 25 | (((u32)((p)[0])) | ((u32)((p)[1]) << 8) | ((u32)((p)[2]) << 16) | \ 26 | ((u32)((p)[3]) << 24)) 27 | 28 | #define U32TO8_LITTLE(p, v) \ 29 | do { \ 30 | (p)[0] = U8V((v)); \ 31 | (p)[1] = U8V((v) >> 8); \ 32 | (p)[2] = U8V((v) >> 16); \ 33 | (p)[3] = U8V((v) >> 24); \ 34 | } while (0) 35 | 36 | #define ROTATE(v, c) (ROTL32(v, c)) 37 | #define XOR(v, w) ((v) ^ (w)) 38 | #define PLUS(v, w) (U32V((v) + (w))) 39 | #define PLUSONE(v) (PLUS((v), 1)) 40 | 41 | #define QUARTERROUND(a, b, c, d) \ 42 | a = PLUS(a, b); \ 43 | d = ROTATE(XOR(d, a), 16); \ 44 | c = PLUS(c, d); \ 45 | b = ROTATE(XOR(b, c), 12); \ 46 | a = PLUS(a, b); \ 47 | d = ROTATE(XOR(d, a), 8); \ 48 | c = PLUS(c, d); \ 49 | b = ROTATE(XOR(b, c), 7); 50 | 51 | static const char sigma[16] = "expand 32-byte k"; 52 | static const char tau[16] = "expand 16-byte k"; 53 | 54 | void chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits) { 55 | const char *constants; 56 | 57 | x->input[4] = U8TO32_LITTLE(k + 0); 58 | x->input[5] = U8TO32_LITTLE(k + 4); 59 | x->input[6] = U8TO32_LITTLE(k + 8); 60 | x->input[7] = U8TO32_LITTLE(k + 12); 61 | if (kbits == 256) { /* recommended */ 62 | k += 16; 63 | constants = sigma; 64 | } else { /* kbits == 128 */ 65 | constants = tau; 66 | } 67 | x->input[8] = U8TO32_LITTLE(k + 0); 68 | x->input[9] = U8TO32_LITTLE(k + 4); 69 | x->input[10] = U8TO32_LITTLE(k + 8); 70 | x->input[11] = U8TO32_LITTLE(k + 12); 71 | x->input[0] = U8TO32_LITTLE(constants + 0); 72 | x->input[1] = U8TO32_LITTLE(constants + 4); 73 | x->input[2] = U8TO32_LITTLE(constants + 8); 74 | x->input[3] = U8TO32_LITTLE(constants + 12); 75 | } 76 | 77 | void chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) { 78 | x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); 79 | x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); 80 | x->input[14] = U8TO32_LITTLE(iv + 0); 81 | x->input[15] = U8TO32_LITTLE(iv + 4); 82 | } 83 | 84 | void chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes) { 85 | u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; 86 | u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; 87 | u8 *ctarget = NULL; 88 | u8 tmp[64]; 89 | uint32_t i; 90 | 91 | if (!bytes) 92 | return; 93 | 94 | j0 = x->input[0]; 95 | j1 = x->input[1]; 96 | j2 = x->input[2]; 97 | j3 = x->input[3]; 98 | j4 = x->input[4]; 99 | j5 = x->input[5]; 100 | j6 = x->input[6]; 101 | j7 = x->input[7]; 102 | j8 = x->input[8]; 103 | j9 = x->input[9]; 104 | j10 = x->input[10]; 105 | j11 = x->input[11]; 106 | j12 = x->input[12]; 107 | j13 = x->input[13]; 108 | j14 = x->input[14]; 109 | j15 = x->input[15]; 110 | 111 | for (;;) { 112 | if (bytes < 64) { 113 | for (i = 0; i < bytes; ++i) 114 | tmp[i] = m[i]; 115 | m = tmp; 116 | ctarget = c; 117 | c = tmp; 118 | } 119 | x0 = j0; 120 | x1 = j1; 121 | x2 = j2; 122 | x3 = j3; 123 | x4 = j4; 124 | x5 = j5; 125 | x6 = j6; 126 | x7 = j7; 127 | x8 = j8; 128 | x9 = j9; 129 | x10 = j10; 130 | x11 = j11; 131 | x12 = j12; 132 | x13 = j13; 133 | x14 = j14; 134 | x15 = j15; 135 | for (i = 20; i > 0; i -= 2) { 136 | QUARTERROUND(x0, x4, x8, x12) 137 | QUARTERROUND(x1, x5, x9, x13) 138 | QUARTERROUND(x2, x6, x10, x14) 139 | QUARTERROUND(x3, x7, x11, x15) 140 | QUARTERROUND(x0, x5, x10, x15) 141 | QUARTERROUND(x1, x6, x11, x12) 142 | QUARTERROUND(x2, x7, x8, x13) 143 | QUARTERROUND(x3, x4, x9, x14) 144 | } 145 | x0 = PLUS(x0, j0); 146 | x1 = PLUS(x1, j1); 147 | x2 = PLUS(x2, j2); 148 | x3 = PLUS(x3, j3); 149 | x4 = PLUS(x4, j4); 150 | x5 = PLUS(x5, j5); 151 | x6 = PLUS(x6, j6); 152 | x7 = PLUS(x7, j7); 153 | x8 = PLUS(x8, j8); 154 | x9 = PLUS(x9, j9); 155 | x10 = PLUS(x10, j10); 156 | x11 = PLUS(x11, j11); 157 | x12 = PLUS(x12, j12); 158 | x13 = PLUS(x13, j13); 159 | x14 = PLUS(x14, j14); 160 | x15 = PLUS(x15, j15); 161 | 162 | x0 = XOR(x0, U8TO32_LITTLE(m + 0)); 163 | x1 = XOR(x1, U8TO32_LITTLE(m + 4)); 164 | x2 = XOR(x2, U8TO32_LITTLE(m + 8)); 165 | x3 = XOR(x3, U8TO32_LITTLE(m + 12)); 166 | x4 = XOR(x4, U8TO32_LITTLE(m + 16)); 167 | x5 = XOR(x5, U8TO32_LITTLE(m + 20)); 168 | x6 = XOR(x6, U8TO32_LITTLE(m + 24)); 169 | x7 = XOR(x7, U8TO32_LITTLE(m + 28)); 170 | x8 = XOR(x8, U8TO32_LITTLE(m + 32)); 171 | x9 = XOR(x9, U8TO32_LITTLE(m + 36)); 172 | x10 = XOR(x10, U8TO32_LITTLE(m + 40)); 173 | x11 = XOR(x11, U8TO32_LITTLE(m + 44)); 174 | x12 = XOR(x12, U8TO32_LITTLE(m + 48)); 175 | x13 = XOR(x13, U8TO32_LITTLE(m + 52)); 176 | x14 = XOR(x14, U8TO32_LITTLE(m + 56)); 177 | x15 = XOR(x15, U8TO32_LITTLE(m + 60)); 178 | 179 | j12 = PLUSONE(j12); 180 | if (!j12) { 181 | j13 = PLUSONE(j13); 182 | /* stopping at 2^70 bytes per nonce is user's responsibility */ 183 | } 184 | 185 | U32TO8_LITTLE(c + 0, x0); 186 | U32TO8_LITTLE(c + 4, x1); 187 | U32TO8_LITTLE(c + 8, x2); 188 | U32TO8_LITTLE(c + 12, x3); 189 | U32TO8_LITTLE(c + 16, x4); 190 | U32TO8_LITTLE(c + 20, x5); 191 | U32TO8_LITTLE(c + 24, x6); 192 | U32TO8_LITTLE(c + 28, x7); 193 | U32TO8_LITTLE(c + 32, x8); 194 | U32TO8_LITTLE(c + 36, x9); 195 | U32TO8_LITTLE(c + 40, x10); 196 | U32TO8_LITTLE(c + 44, x11); 197 | U32TO8_LITTLE(c + 48, x12); 198 | U32TO8_LITTLE(c + 52, x13); 199 | U32TO8_LITTLE(c + 56, x14); 200 | U32TO8_LITTLE(c + 60, x15); 201 | 202 | if (bytes <= 64) { 203 | if (bytes < 64) { 204 | for (i = 0; i < bytes; ++i) 205 | ctarget[i] = c[i]; 206 | } 207 | x->input[12] = j12; 208 | x->input[13] = j13; 209 | return; 210 | } 211 | bytes -= 64; 212 | c += 64; 213 | m += 64; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /cipherseed.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2018 Jonas Schnelli 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included 15 | in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 21 | OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | */ 26 | 27 | #include "cipherseed.h" 28 | 29 | #include "chacha.h" 30 | #include "poly1305.h" 31 | #include "sha2.h" 32 | 33 | #ifndef HAVE_TIMINGSAFE_BCMP 34 | 35 | int timingsafe_bcmp(const void *b1, const void *b2, size_t n) { 36 | const unsigned char *p1 = b1, *p2 = b2; 37 | int ret = 0; 38 | 39 | for (; n > 0; n--) 40 | ret |= *p1++ ^ *p2++; 41 | return (ret != 0); 42 | } 43 | 44 | #endif /* TIMINGSAFE_BCMP */ 45 | 46 | #ifndef HAVE_MEMSET_S 47 | void memory_cleanse(void *p, size_t n) { 48 | #if defined(__has_feature) 49 | #if __has_feature(memory_sanitizer) 50 | memset(p, 0, n); 51 | #endif 52 | #endif 53 | } 54 | 55 | #else /* no memset_s available */ 56 | void memory_cleanse(void *p, size_t n) { (void)memset_s(p, n, 0, n); } 57 | #endif 58 | 59 | void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, 60 | const uint8_t salt_in[PBKDF2_SALTLEN], uint8_t *key, 61 | int keylen) { 62 | uint32_t i, j, k; 63 | uint8_t f[PBKDF2_HMACLEN], g[PBKDF2_HMACLEN]; 64 | uint32_t blocks = keylen / PBKDF2_HMACLEN; 65 | 66 | uint8_t salt[PBKDF2_SALTLEN + 4 + sizeof(PBKDF2_SALTPREFIX)]; 67 | memset(salt, 0, sizeof(salt)); 68 | memcpy(salt, PBKDF2_SALTPREFIX, sizeof(PBKDF2_SALTPREFIX)); 69 | memcpy(salt+sizeof(PBKDF2_SALTPREFIX), salt_in, PBKDF2_SALTLEN); 70 | 71 | if (keylen & (PBKDF2_HMACLEN - 1)) { 72 | blocks++; 73 | } 74 | for (i = 1; i <= blocks; i++) { 75 | salt[PBKDF2_SALTLEN] = (i >> 24) & 0xFF; 76 | salt[PBKDF2_SALTLEN + 1] = (i >> 16) & 0xFF; 77 | salt[PBKDF2_SALTLEN + 2] = (i >> 8) & 0xFF; 78 | salt[PBKDF2_SALTLEN + 3] = i & 0xFF; 79 | hmac_sha512(pass, passlen, salt, PBKDF2_SALTLEN + 4, g); 80 | memcpy(f, g, PBKDF2_HMACLEN); 81 | for (j = 1; j < PBKDF2_ROUNDS; j++) { 82 | hmac_sha512(pass, passlen, g, PBKDF2_HMACLEN, g); 83 | for (k = 0; k < PBKDF2_HMACLEN; k++) { 84 | f[k] ^= g[k]; 85 | } 86 | } 87 | if (i == blocks && (keylen & (PBKDF2_HMACLEN - 1))) { 88 | memcpy(key + PBKDF2_HMACLEN * (i - 1), f, 89 | keylen & (PBKDF2_HMACLEN - 1)); 90 | } else { 91 | memcpy(key + PBKDF2_HMACLEN * (i - 1), f, PBKDF2_HMACLEN); 92 | } 93 | } 94 | memset(f, 0, sizeof(f)); 95 | memset(g, 0, sizeof(g)); 96 | } 97 | 98 | static const uint8_t version_byte = 0x00; 99 | static const uint8_t one[8] = {1, 0, 0, 0, 0, 0, 0, 0}; /* NB little-endian */ 100 | static const uint64_t nonce_polykey = 0; 101 | static const uint64_t nonce_seedcipher = 1; 102 | static const unsigned int saltlen = 5; 103 | static const unsigned int tag_truncation_length = 4; // 32bit tag 104 | static const unsigned int enc_header_length = 3; // 1 usage type + 2 byte bday 105 | 106 | int encrypt_seed(const uint8_t key256[32], const uint8_t key256_sec[32], 107 | const uint8_t *seed, unsigned int seedlen, 108 | const uint8_t *salt_5bytes, const uint16_t bday, 109 | const uint8_t type, uint8_t *dest_out, int is_encrypt) { 110 | struct chacha_ctx ctx_prim, ctx_sec; 111 | int r = -1; 112 | 113 | uint8_t expected_tag[POLY1305_TAGLEN] = {}; 114 | uint8_t prim_tag_container[POLY1305_TAGLEN] = {}; 115 | uint8_t poly_key_prim[POLY1305_KEYLEN] = {0}, 116 | poly_key_sec[POLY1305_KEYLEN] = {0}; 117 | 118 | memset(poly_key_prim, 0, POLY1305_TAGLEN); 119 | memset(poly_key_sec, 0, POLY1305_TAGLEN); 120 | 121 | /* setup the primary key */ 122 | chacha_ivsetup(&ctx_prim, (uint8_t *)&nonce_polykey, NULL); 123 | chacha_keysetup(&ctx_prim, key256, 256); 124 | 125 | /* run once to generate primary poly1305 key */ 126 | chacha_encrypt_bytes(&ctx_prim, poly_key_prim, poly_key_prim, 127 | POLY1305_KEYLEN); 128 | 129 | /* setup the secondary key if we encrypt */ 130 | chacha_ivsetup(&ctx_sec, (uint8_t *)&nonce_polykey, NULL); 131 | chacha_keysetup(&ctx_sec, key256_sec, 256); 132 | 133 | /* run once to generate secondary poly1305 key */ 134 | chacha_encrypt_bytes(&ctx_sec, poly_key_sec, poly_key_sec, POLY1305_KEYLEN); 135 | 136 | /* set nonce / IV for seed ciphering */ 137 | chacha_ivsetup(&ctx_prim, (uint8_t *)&nonce_seedcipher, one); 138 | 139 | /* set the plaintext version-byte & salt */ 140 | memcpy(dest_out, &version_byte, 1); 141 | memcpy(dest_out+1, salt_5bytes, saltlen); 142 | 143 | /* encrypt the usage type (1 byte)*/ 144 | chacha_encrypt_bytes(&ctx_prim, (uint8_t *)&type, 145 | (uint8_t *)dest_out + 1 + saltlen, 1); 146 | 147 | /* encrypt the birthday (2 bytes) */ 148 | chacha_encrypt_bytes(&ctx_prim, (uint8_t *)&bday, 149 | (uint8_t *)dest_out + 1 + saltlen + 1, 2); 150 | 151 | /* encrypt the seed */ 152 | chacha_encrypt_bytes(&ctx_prim, seed, (uint8_t *)dest_out + 1 + saltlen + enc_header_length, 153 | seedlen); 154 | 155 | /* poly1305 auth of encrypted seed + salt */ 156 | poly1305_auth(prim_tag_container, dest_out, 157 | 1 + saltlen + enc_header_length + seedlen, poly_key_prim); 158 | /* append 1st truncated tag (32bit) to the dest buffer */ 159 | memcpy(dest_out + 1 + saltlen + enc_header_length + seedlen, prim_tag_container, 160 | tag_truncation_length); 161 | memory_cleanse(prim_tag_container, sizeof(poly_key_sec)); 162 | 163 | /* perform and append the second poly1305 auth tag */ 164 | poly1305_auth(prim_tag_container, dest_out, 165 | 1 + saltlen + enc_header_length + seedlen, poly_key_sec); 166 | 167 | /* append 2nd truncated tag (32bit) to the dest buffer */ 168 | memcpy(dest_out + 1 + saltlen + enc_header_length + seedlen + 169 | tag_truncation_length, 170 | prim_tag_container, tag_truncation_length); 171 | 172 | r = 0; 173 | out: 174 | memory_cleanse(expected_tag, sizeof(expected_tag)); 175 | memory_cleanse(poly_key_prim, sizeof(poly_key_prim)); 176 | memory_cleanse(poly_key_sec, sizeof(poly_key_sec)); 177 | memory_cleanse(prim_tag_container, sizeof(poly_key_sec)); 178 | return r; 179 | } 180 | 181 | int decrypt_seed(const uint8_t key256[32], const uint8_t *payload, 182 | unsigned int payload_len, uint16_t *bday_out, 183 | uint8_t *usage_type_out, uint8_t *seed_out) { 184 | struct chacha_ctx ctx_prim; 185 | int r = -1; 186 | uint8_t poly_key_prim[POLY1305_KEYLEN] = {0}; 187 | memset(poly_key_prim, 0, POLY1305_TAGLEN); 188 | 189 | if (payload_len < 1 || payload == NULL || payload[0] != version_byte) { 190 | /* invalid payload or version */ 191 | return r; 192 | } 193 | const unsigned int seedlen = 194 | payload_len - saltlen - enc_header_length - 2 * tag_truncation_length; 195 | uint8_t expected_tag[POLY1305_TAGLEN] = {}; 196 | 197 | /* setup the primary key */ 198 | chacha_ivsetup(&ctx_prim, (uint8_t *)&nonce_polykey, NULL); 199 | chacha_keysetup(&ctx_prim, key256, 256); 200 | 201 | /* run once to generate primary poly1305 key */ 202 | chacha_encrypt_bytes(&ctx_prim, poly_key_prim, poly_key_prim, 203 | POLY1305_KEYLEN); 204 | 205 | const uint8_t *tag_prim = payload + 1 + saltlen + enc_header_length + seedlen; 206 | const uint8_t *tag_sec = 207 | payload + 1 + saltlen + tag_truncation_length + seedlen; 208 | poly1305_auth(expected_tag, payload, 1 + saltlen + enc_header_length + seedlen, 209 | poly_key_prim); 210 | if (timingsafe_bcmp(expected_tag, tag_prim, tag_truncation_length) != 0 && 211 | timingsafe_bcmp(expected_tag, tag_sec, tag_truncation_length) != 0) { 212 | r = -1; 213 | goto out; 214 | } 215 | 216 | /* set nonce / IV for seed decryption */ 217 | chacha_ivsetup(&ctx_prim, (uint8_t *)&nonce_seedcipher, one); 218 | 219 | /* decrypt the version byte */ 220 | chacha_encrypt_bytes(&ctx_prim, payload + 1 + saltlen, (uint8_t *)usage_type_out, 221 | 1); 222 | 223 | /* decrypt the birthday */ 224 | chacha_encrypt_bytes(&ctx_prim, payload + 1 + saltlen + 1, (uint8_t *)bday_out, 225 | 2); 226 | 227 | /* decrypt the seed */ 228 | chacha_encrypt_bytes(&ctx_prim, payload + 1 + saltlen + enc_header_length, seed_out, 229 | seedlen); 230 | r = 0; 231 | out: 232 | memory_cleanse(expected_tag, sizeof(expected_tag)); 233 | memory_cleanse(poly_key_prim, sizeof(poly_key_prim)); 234 | return r; 235 | } 236 | -------------------------------------------------------------------------------- /tests.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Copyright (c) 2016 Jonas Schnelli * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "chacha.h" 13 | #include "cipherseed.h" 14 | #include "poly1305.h" 15 | 16 | struct chacha20_testvector { 17 | uint8_t key[32]; 18 | uint8_t nonce[8]; 19 | uint8_t resulting_keystream[512]; 20 | int keystream_check_size; 21 | }; 22 | 23 | struct poly1305_testvector { 24 | uint8_t input[64]; 25 | int inputlen; 26 | uint8_t key[64]; 27 | uint8_t resulting_tag[16]; 28 | }; 29 | 30 | /* 31 | Testvectors have been taken from the draft RFC 32 | https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7 33 | */ 34 | 35 | static const struct chacha20_testvector chacha20_testvectors[] = { 36 | {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 39 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 40 | {0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, 0x40, 0x5d, 0x6a, 41 | 0xe5, 0x53, 0x86, 0xbd, 0x28, 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 42 | 0xed, 0x1a, 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, 0xda, 43 | 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, 0x77, 0x24, 0xe0, 0x3f, 44 | 0xb8, 0xd8, 0x4a, 0x37, 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 45 | 0x1c, 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86}, 46 | 64}, 47 | {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 50 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 51 | {0x45, 0x40, 0xf0, 0x5a, 0x9f, 0x1f, 0xb2, 0x96, 0xd7, 0x73, 0x6e, 52 | 0x7b, 0x20, 0x8e, 0x3c, 0x96, 0xeb, 0x4f, 0xe1, 0x83, 0x46, 0x88, 53 | 0xd2, 0x60, 0x4f, 0x45, 0x09, 0x52, 0xed, 0x43, 0x2d, 0x41, 0xbb, 54 | 0xe2, 0xa0, 0xb6, 0xea, 0x75, 0x66, 0xd2, 0xa5, 0xd1, 0xe7, 0xe2, 55 | 0x0d, 0x42, 0xaf, 0x2c, 0x53, 0xd7, 0x92, 0xb1, 0xc4, 0x3f, 0xea, 56 | 0x81, 0x7e, 0x9a, 0xd2, 0x75, 0xae, 0x54, 0x69, 0x63}, 57 | 64}, 58 | {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 61 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 62 | {0xde, 0x9c, 0xba, 0x7b, 0xf3, 0xd6, 0x9e, 0xf5, 0xe7, 0x86, 0xdc, 0x63, 63 | 0x97, 0x3f, 0x65, 0x3a, 0x0b, 0x49, 0xe0, 0x15, 0xad, 0xbf, 0xf7, 0x13, 64 | 0x4f, 0xcb, 0x7d, 0xf1, 0x37, 0x82, 0x10, 0x31, 0xe8, 0x5a, 0x05, 0x02, 65 | 0x78, 0xa7, 0x08, 0x45, 0x27, 0x21, 0x4f, 0x73, 0xef, 0xc7, 0xfa, 0x5b, 66 | 0x52, 0x77, 0x06, 0x2e, 0xb7, 0xa0, 0x43, 0x3e, 0x44, 0x5f, 0x41, 0xe3}, 67 | 60}, 68 | {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 71 | {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 72 | {0xef, 0x3f, 0xdf, 0xd6, 0xc6, 0x15, 0x78, 0xfb, 0xf5, 0xcf, 0x35, 73 | 0xbd, 0x3d, 0xd3, 0x3b, 0x80, 0x09, 0x63, 0x16, 0x34, 0xd2, 0x1e, 74 | 0x42, 0xac, 0x33, 0x96, 0x0b, 0xd1, 0x38, 0xe5, 0x0d, 0x32, 0x11, 75 | 0x1e, 0x4c, 0xaf, 0x23, 0x7e, 0xe5, 0x3c, 0xa8, 0xad, 0x64, 0x26, 76 | 0x19, 0x4a, 0x88, 0x54, 0x5d, 0xdc, 0x49, 0x7a, 0x0b, 0x46, 0x6e, 77 | 0x7d, 0x6b, 0xbd, 0xb0, 0x04, 0x1b, 0x2f, 0x58, 0x6b}, 78 | 64}, 79 | {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 80 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 81 | 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}, 82 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, 83 | {0xf7, 0x98, 0xa1, 0x89, 0xf1, 0x95, 0xe6, 0x69, 0x82, 0x10, 0x5f, 0xfb, 84 | 0x64, 0x0b, 0xb7, 0x75, 0x7f, 0x57, 0x9d, 0xa3, 0x16, 0x02, 0xfc, 0x93, 85 | 0xec, 0x01, 0xac, 0x56, 0xf8, 0x5a, 0xc3, 0xc1, 0x34, 0xa4, 0x54, 0x7b, 86 | 0x73, 0x3b, 0x46, 0x41, 0x30, 0x42, 0xc9, 0x44, 0x00, 0x49, 0x17, 0x69, 87 | 0x05, 0xd3, 0xbe, 0x59, 0xea, 0x1c, 0x53, 0xf1, 0x59, 0x16, 0x15, 0x5c, 88 | 0x2b, 0xe8, 0x24, 0x1a, 0x38, 0x00, 0x8b, 0x9a, 0x26, 0xbc, 0x35, 0x94, 89 | 0x1e, 0x24, 0x44, 0x17, 0x7c, 0x8a, 0xde, 0x66, 0x89, 0xde, 0x95, 0x26, 90 | 0x49, 0x86, 0xd9, 0x58, 0x89, 0xfb, 0x60, 0xe8, 0x46, 0x29, 0xc9, 0xbd, 91 | 0x9a, 0x5a, 0xcb, 0x1c, 0xc1, 0x18, 0xbe, 0x56, 0x3e, 0xb9, 0xb3, 0xa4, 92 | 0xa4, 0x72, 0xf8, 0x2e, 0x09, 0xa7, 0xe7, 0x78, 0x49, 0x2b, 0x56, 0x2e, 93 | 0xf7, 0x13, 0x0e, 0x88, 0xdf, 0xe0, 0x31, 0xc7, 0x9d, 0xb9, 0xd4, 0xf7, 94 | 0xc7, 0xa8, 0x99, 0x15, 0x1b, 0x9a, 0x47, 0x50, 0x32, 0xb6, 0x3f, 0xc3, 95 | 0x85, 0x24, 0x5f, 0xe0, 0x54, 0xe3, 0xdd, 0x5a, 0x97, 0xa5, 0xf5, 0x76, 96 | 0xfe, 0x06, 0x40, 0x25, 0xd3, 0xce, 0x04, 0x2c, 0x56, 0x6a, 0xb2, 0xc5, 97 | 0x07, 0xb1, 0x38, 0xdb, 0x85, 0x3e, 0x3d, 0x69, 0x59, 0x66, 0x09, 0x96, 98 | 0x54, 0x6c, 0xc9, 0xc4, 0xa6, 0xea, 0xfd, 0xc7, 0x77, 0xc0, 0x40, 0xd7, 99 | 0x0e, 0xaf, 0x46, 0xf7, 0x6d, 0xad, 0x39, 0x79, 0xe5, 0xc5, 0x36, 0x0c, 100 | 0x33, 0x17, 0x16, 0x6a, 0x1c, 0x89, 0x4c, 0x94, 0xa3, 0x71, 0x87, 0x6a, 101 | 0x94, 0xdf, 0x76, 0x28, 0xfe, 0x4e, 0xaa, 0xf2, 0xcc, 0xb2, 0x7d, 0x5a, 102 | 0xaa, 0xe0, 0xad, 0x7a, 0xd0, 0xf9, 0xd4, 0xb6, 0xad, 0x3b, 0x54, 0x09, 103 | 0x87, 0x46, 0xd4, 0x52, 0x4d, 0x38, 0x40, 0x7a, 0x6d, 0xeb, 0x3a, 0xb7, 104 | 0x8f, 0xab, 0x78, 0xc9}, 105 | 256}}; 106 | 107 | static const struct poly1305_testvector poly1305_testvectors[] = { 108 | { 109 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 112 | 32, 113 | {0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x33, 0x32, 0x2d, 114 | 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x66, 0x6f, 115 | 0x72, 0x20, 0x50, 0x6f, 0x6c, 0x79, 0x31, 0x33, 0x30, 0x35}, 116 | {0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 117 | 0x1c, 0xcc, 0x03, 0x07}, 118 | }, 119 | {{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21}, 120 | 12, 121 | {0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x33, 0x32, 0x2d, 122 | 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x66, 0x6f, 123 | 0x72, 0x20, 0x50, 0x6f, 0x6c, 0x79, 0x31, 0x33, 0x30, 0x35}, 124 | {0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 125 | 0xee, 0xf2, 0xb2, 0xf0}}}; 126 | 127 | int main(void) { 128 | struct chacha_ctx ctx; 129 | const uint8_t one[8] = {1, 0, 0, 0, 0, 0, 0, 0}; /* NB little-endian */ 130 | unsigned int i = 0; 131 | uint8_t keystream[512]; 132 | uint8_t poly1305_tag[16]; 133 | 134 | /* test chacha20 */ 135 | for (i = 0; 136 | i < (sizeof(chacha20_testvectors) / sizeof(chacha20_testvectors[0])); 137 | i++) { 138 | chacha_ivsetup(&ctx, chacha20_testvectors[i].nonce, NULL); 139 | memset(keystream, 0, 512); 140 | chacha_keysetup(&ctx, chacha20_testvectors[i].key, 256); 141 | chacha_encrypt_bytes(&ctx, keystream, keystream, 512); 142 | assert(memcmp(keystream, chacha20_testvectors[i].resulting_keystream, 143 | chacha20_testvectors[i].keystream_check_size) == 0); 144 | } 145 | 146 | /* test poly1305 */ 147 | for (i = 0; 148 | i < (sizeof(poly1305_testvectors) / sizeof(poly1305_testvectors[0])); 149 | i++) { 150 | memset(poly1305_tag, 0, 16); 151 | poly1305_auth(poly1305_tag, poly1305_testvectors[i].input, 152 | poly1305_testvectors[i].inputlen, 153 | poly1305_testvectors[i].key); 154 | assert(memcmp(poly1305_tag, poly1305_testvectors[i].resulting_tag, 155 | 16) == 0); 156 | int i = 100; 157 | } 158 | 159 | /* test cipherseed */ 160 | const uint8_t salt[5] = {1, 2, 3, 4, 5}; 161 | 162 | uint8_t key_stretched_prim[64] = {}; 163 | const uint8_t passphrase[5] = {'d', 'u', 'm', 'm', 'y'}; 164 | pbkdf2_hmac_sha512(passphrase, 5, salt, key_stretched_prim, 64); 165 | 166 | uint8_t key_stretched_sec[64] = {}; 167 | const uint8_t passphrase_sec[5] = {'m', 'u', 'm', 'm', 'y'}; 168 | pbkdf2_hmac_sha512(passphrase_sec, 5, salt, key_stretched_sec, 64); 169 | 170 | uint8_t key_stretched_invalid[64] = {}; 171 | const uint8_t passphrase_invalid[5] = {'s', 'u', 'm', 'm', 'y'}; 172 | pbkdf2_hmac_sha512(passphrase_invalid, 5, salt, key_stretched_invalid, 64); 173 | 174 | uint16_t bday_15bit = 1; 175 | uint8_t type = 1; 176 | uint16_t bday_15bit_check = 0; 177 | uint8_t type_check = 0; 178 | uint8_t dest[128] = {}; 179 | uint8_t dest_check[128] = {}; 180 | const uint8_t key[32] = {0x71, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 181 | 0x33, 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 182 | 0x6b, 0x65, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 183 | 0x50, 0x6f, 0x6c, 0x79, 0x31, 0x33, 0x30, 0x35}; 184 | const uint8_t seed[16] = { 185 | 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 186 | }; 187 | if (encrypt_seed(key_stretched_prim, key_stretched_sec, seed, 16, salt, 188 | bday_15bit, type, dest, 1) != 0) { 189 | printf("Error encrypting\n"); 190 | return -1; 191 | } 192 | if (decrypt_seed(key_stretched_prim, dest, 32, &bday_15bit_check, 193 | &type_check, dest_check) != 0) { 194 | printf("Error decrypting with primary key\n"); 195 | return -1; 196 | } 197 | if (bday_15bit_check != bday_15bit || type_check != type) { 198 | printf("Decryption integrity check failed\n"); 199 | return -1; 200 | } 201 | if (decrypt_seed(passphrase_invalid, dest, 32, &bday_15bit_check, 202 | &type_check, dest_check) == 0) { 203 | printf("Error decrypting with invalid key was possible\n"); 204 | return -1; 205 | } 206 | 207 | return 0; 208 | } 209 | -------------------------------------------------------------------------------- /sha2.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2000-2001 Aaron D. Gifford 3 | * Copyright (c) 2013 Pavol Rusnak 4 | * Copyright (c) 2015 Jonas Schnelli 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the copyright holder nor the names of contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | #include "sha2.h" 36 | 37 | /* 38 | * ASSERT NOTE: 39 | * Some sanity checking code is included using assert(). On my FreeBSD 40 | * system, this additional code can be removed by compiling with NDEBUG 41 | * defined. Check your own systems manpage on assert() to see how to 42 | * compile WITHOUT the sanity checking code on your system. 43 | * 44 | * UNROLLED TRANSFORM LOOP NOTE: 45 | * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 46 | * loop version for the hash transform rounds (defined using macros 47 | * later in this file). Either define on the command line, for example: 48 | * 49 | * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 50 | * 51 | * or define below: 52 | * 53 | * #define SHA2_UNROLL_TRANSFORM 54 | * 55 | */ 56 | 57 | 58 | /*** SHA-256/384/512 Machine Architecture Definitions *****************/ 59 | /* 60 | * BYTE_ORDER NOTE: 61 | * 62 | * Please make sure that your system defines BYTE_ORDER. If your 63 | * architecture is little-endian, make sure it also defines 64 | * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 65 | * equivilent. 66 | * 67 | * If your system does not define the above, then you can do so by 68 | * hand like this: 69 | * 70 | * #define LITTLE_ENDIAN 1234 71 | * #define BIG_ENDIAN 4321 72 | * 73 | * And for little-endian machines, add: 74 | * 75 | * #define BYTE_ORDER LITTLE_ENDIAN 76 | * 77 | * Or for big-endian machines: 78 | * 79 | * #define BYTE_ORDER BIG_ENDIAN 80 | * 81 | * The FreeBSD machine this was written on defines BYTE_ORDER 82 | * appropriately by including (which in turn includes 83 | * where the appropriate definitions are actually 84 | * made). 85 | */ 86 | 87 | #ifndef LITTLE_ENDIAN 88 | #define LITTLE_ENDIAN 1234 89 | #define BIG_ENDIAN 4321 90 | #endif 91 | 92 | #ifndef BYTE_ORDER 93 | #define BYTE_ORDER LITTLE_ENDIAN 94 | #endif 95 | 96 | #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 97 | #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 98 | #endif 99 | 100 | typedef uint8_t sha2_byte; /* Exactly 1 byte */ 101 | typedef uint32_t sha2_word32; /* Exactly 4 bytes */ 102 | typedef uint64_t sha2_word64; /* Exactly 8 bytes */ 103 | 104 | /*** SHA-256/384/512 Various Length Definitions ***********************/ 105 | /* NOTE: Most of these are in sha2.h */ 106 | #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) 107 | #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) 108 | 109 | 110 | /*** ENDIAN REVERSAL MACROS *******************************************/ 111 | #if BYTE_ORDER == LITTLE_ENDIAN 112 | #define REVERSE32(w, x) \ 113 | { \ 114 | sha2_word32 tmp = (w); \ 115 | tmp = (tmp >> 16) | (tmp << 16); \ 116 | (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ 117 | } 118 | #define REVERSE64(w, x) \ 119 | { \ 120 | sha2_word64 tmp = (w); \ 121 | tmp = (tmp >> 32) | (tmp << 32); \ 122 | tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ 123 | (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | ((tmp & 0x0000ffff0000ffffULL) << 16); \ 124 | } 125 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 126 | 127 | /* 128 | * Macro for incrementally adding the unsigned 64-bit integer n to the 129 | * unsigned 128-bit integer (represented using a two-element array of 130 | * 64-bit words): 131 | */ 132 | #define ADDINC128(w, n) \ 133 | { \ 134 | (w)[0] += (sha2_word64)(n); \ 135 | if ((w)[0] < (n)) { \ 136 | (w)[1]++; \ 137 | } \ 138 | } 139 | 140 | #define MEMSET_BZERO(p, l) memset((p), 0, (l)) 141 | #define MEMCPY_BCOPY(d, s, l) memcpy((d), (s), (l)) 142 | 143 | /*** THE SIX LOGICAL FUNCTIONS ****************************************/ 144 | /* 145 | * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 146 | * 147 | * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 148 | * S is a ROTATION) because the SHA-256/384/512 description document 149 | * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 150 | * same "backwards" definition. 151 | */ 152 | /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ 153 | #define R(b, x) ((x) >> (b)) 154 | /* 32-bit Rotate-right (used in SHA-256): */ 155 | #define S32(b, x) (((x) >> (b)) | ((x) << (32 - (b)))) 156 | /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ 157 | #define S64(b, x) (((x) >> (b)) | ((x) << (64 - (b)))) 158 | 159 | /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ 160 | #define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) 161 | #define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 162 | 163 | /* Four of six logical functions used in SHA-256: */ 164 | #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 165 | #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 166 | #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3, (x))) 167 | #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 168 | 169 | /* Four of six logical functions used in SHA-384 and SHA-512: */ 170 | #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 171 | #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 172 | #define sigma0_512(x) (S64(1, (x)) ^ S64(8, (x)) ^ R(7, (x))) 173 | #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R(6, (x))) 174 | 175 | /*** INTERNAL FUNCTION PROTOTYPES *************************************/ 176 | /* NOTE: These should not be accessed directly from outside this 177 | * library -- they are intended for private internal visibility/use 178 | * only. 179 | */ 180 | void sha512_Last(SHA512_CTX*); 181 | void sha256_Transform(SHA256_CTX*, const sha2_word32*); 182 | void sha512_Transform(SHA512_CTX*, const sha2_word64*); 183 | 184 | 185 | /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 186 | /* Hash constant words K for SHA-256: */ 187 | static const sha2_word32 K256[64] = { 188 | 0x428a2f98UL, 189 | 0x71374491UL, 190 | 0xb5c0fbcfUL, 191 | 0xe9b5dba5UL, 192 | 0x3956c25bUL, 193 | 0x59f111f1UL, 194 | 0x923f82a4UL, 195 | 0xab1c5ed5UL, 196 | 0xd807aa98UL, 197 | 0x12835b01UL, 198 | 0x243185beUL, 199 | 0x550c7dc3UL, 200 | 0x72be5d74UL, 201 | 0x80deb1feUL, 202 | 0x9bdc06a7UL, 203 | 0xc19bf174UL, 204 | 0xe49b69c1UL, 205 | 0xefbe4786UL, 206 | 0x0fc19dc6UL, 207 | 0x240ca1ccUL, 208 | 0x2de92c6fUL, 209 | 0x4a7484aaUL, 210 | 0x5cb0a9dcUL, 211 | 0x76f988daUL, 212 | 0x983e5152UL, 213 | 0xa831c66dUL, 214 | 0xb00327c8UL, 215 | 0xbf597fc7UL, 216 | 0xc6e00bf3UL, 217 | 0xd5a79147UL, 218 | 0x06ca6351UL, 219 | 0x14292967UL, 220 | 0x27b70a85UL, 221 | 0x2e1b2138UL, 222 | 0x4d2c6dfcUL, 223 | 0x53380d13UL, 224 | 0x650a7354UL, 225 | 0x766a0abbUL, 226 | 0x81c2c92eUL, 227 | 0x92722c85UL, 228 | 0xa2bfe8a1UL, 229 | 0xa81a664bUL, 230 | 0xc24b8b70UL, 231 | 0xc76c51a3UL, 232 | 0xd192e819UL, 233 | 0xd6990624UL, 234 | 0xf40e3585UL, 235 | 0x106aa070UL, 236 | 0x19a4c116UL, 237 | 0x1e376c08UL, 238 | 0x2748774cUL, 239 | 0x34b0bcb5UL, 240 | 0x391c0cb3UL, 241 | 0x4ed8aa4aUL, 242 | 0x5b9cca4fUL, 243 | 0x682e6ff3UL, 244 | 0x748f82eeUL, 245 | 0x78a5636fUL, 246 | 0x84c87814UL, 247 | 0x8cc70208UL, 248 | 0x90befffaUL, 249 | 0xa4506cebUL, 250 | 0xbef9a3f7UL, 251 | 0xc67178f2UL}; 252 | 253 | /* Initial hash value H for SHA-256: */ 254 | static const sha2_word32 sha256_initial_hash_value[8] = { 255 | 0x6a09e667UL, 256 | 0xbb67ae85UL, 257 | 0x3c6ef372UL, 258 | 0xa54ff53aUL, 259 | 0x510e527fUL, 260 | 0x9b05688cUL, 261 | 0x1f83d9abUL, 262 | 0x5be0cd19UL}; 263 | 264 | /* Hash constant words K for SHA-384 and SHA-512: */ 265 | static const sha2_word64 K512[80] = { 266 | 0x428a2f98d728ae22ULL, 267 | 0x7137449123ef65cdULL, 268 | 0xb5c0fbcfec4d3b2fULL, 269 | 0xe9b5dba58189dbbcULL, 270 | 0x3956c25bf348b538ULL, 271 | 0x59f111f1b605d019ULL, 272 | 0x923f82a4af194f9bULL, 273 | 0xab1c5ed5da6d8118ULL, 274 | 0xd807aa98a3030242ULL, 275 | 0x12835b0145706fbeULL, 276 | 0x243185be4ee4b28cULL, 277 | 0x550c7dc3d5ffb4e2ULL, 278 | 0x72be5d74f27b896fULL, 279 | 0x80deb1fe3b1696b1ULL, 280 | 0x9bdc06a725c71235ULL, 281 | 0xc19bf174cf692694ULL, 282 | 0xe49b69c19ef14ad2ULL, 283 | 0xefbe4786384f25e3ULL, 284 | 0x0fc19dc68b8cd5b5ULL, 285 | 0x240ca1cc77ac9c65ULL, 286 | 0x2de92c6f592b0275ULL, 287 | 0x4a7484aa6ea6e483ULL, 288 | 0x5cb0a9dcbd41fbd4ULL, 289 | 0x76f988da831153b5ULL, 290 | 0x983e5152ee66dfabULL, 291 | 0xa831c66d2db43210ULL, 292 | 0xb00327c898fb213fULL, 293 | 0xbf597fc7beef0ee4ULL, 294 | 0xc6e00bf33da88fc2ULL, 295 | 0xd5a79147930aa725ULL, 296 | 0x06ca6351e003826fULL, 297 | 0x142929670a0e6e70ULL, 298 | 0x27b70a8546d22ffcULL, 299 | 0x2e1b21385c26c926ULL, 300 | 0x4d2c6dfc5ac42aedULL, 301 | 0x53380d139d95b3dfULL, 302 | 0x650a73548baf63deULL, 303 | 0x766a0abb3c77b2a8ULL, 304 | 0x81c2c92e47edaee6ULL, 305 | 0x92722c851482353bULL, 306 | 0xa2bfe8a14cf10364ULL, 307 | 0xa81a664bbc423001ULL, 308 | 0xc24b8b70d0f89791ULL, 309 | 0xc76c51a30654be30ULL, 310 | 0xd192e819d6ef5218ULL, 311 | 0xd69906245565a910ULL, 312 | 0xf40e35855771202aULL, 313 | 0x106aa07032bbd1b8ULL, 314 | 0x19a4c116b8d2d0c8ULL, 315 | 0x1e376c085141ab53ULL, 316 | 0x2748774cdf8eeb99ULL, 317 | 0x34b0bcb5e19b48a8ULL, 318 | 0x391c0cb3c5c95a63ULL, 319 | 0x4ed8aa4ae3418acbULL, 320 | 0x5b9cca4f7763e373ULL, 321 | 0x682e6ff3d6b2b8a3ULL, 322 | 0x748f82ee5defb2fcULL, 323 | 0x78a5636f43172f60ULL, 324 | 0x84c87814a1f0ab72ULL, 325 | 0x8cc702081a6439ecULL, 326 | 0x90befffa23631e28ULL, 327 | 0xa4506cebde82bde9ULL, 328 | 0xbef9a3f7b2c67915ULL, 329 | 0xc67178f2e372532bULL, 330 | 0xca273eceea26619cULL, 331 | 0xd186b8c721c0c207ULL, 332 | 0xeada7dd6cde0eb1eULL, 333 | 0xf57d4f7fee6ed178ULL, 334 | 0x06f067aa72176fbaULL, 335 | 0x0a637dc5a2c898a6ULL, 336 | 0x113f9804bef90daeULL, 337 | 0x1b710b35131c471bULL, 338 | 0x28db77f523047d84ULL, 339 | 0x32caab7b40c72493ULL, 340 | 0x3c9ebe0a15c9bebcULL, 341 | 0x431d67c49c100d4cULL, 342 | 0x4cc5d4becb3e42b6ULL, 343 | 0x597f299cfc657e2aULL, 344 | 0x5fcb6fab3ad6faecULL, 345 | 0x6c44198c4a475817ULL}; 346 | 347 | /* Initial hash value H for SHA-512 */ 348 | static const sha2_word64 sha512_initial_hash_value[8] = { 349 | 0x6a09e667f3bcc908ULL, 350 | 0xbb67ae8584caa73bULL, 351 | 0x3c6ef372fe94f82bULL, 352 | 0xa54ff53a5f1d36f1ULL, 353 | 0x510e527fade682d1ULL, 354 | 0x9b05688c2b3e6c1fULL, 355 | 0x1f83d9abfb41bd6bULL, 356 | 0x5be0cd19137e2179ULL}; 357 | 358 | 359 | /*** SHA-256: *********************************************************/ 360 | void sha256_Init(SHA256_CTX* context) 361 | { 362 | if (context == (SHA256_CTX*)0) { 363 | return; 364 | } 365 | MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); 366 | MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); 367 | context->bitcount = 0; 368 | } 369 | 370 | #ifdef SHA2_UNROLL_TRANSFORM 371 | 372 | /* Unrolled SHA-256 round macros: */ 373 | 374 | #if BYTE_ORDER == LITTLE_ENDIAN 375 | 376 | #define ROUND256_0_TO_15(a, b, c, d, e, f, g, h) \ 377 | REVERSE32(*data++, W256[j]); \ 378 | T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ 379 | (d) += T1; \ 380 | (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 381 | j++ 382 | 383 | 384 | #else /* BYTE_ORDER == LITTLE_ENDIAN */ 385 | 386 | #define ROUND256_0_TO_15(a, b, c, d, e, f, g, h) \ 387 | T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + (W256[j] = *data++); \ 388 | (d) += T1; \ 389 | (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 390 | j++ 391 | 392 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 393 | 394 | #define ROUND256(a, b, c, d, e, f, g, h) \ 395 | s0 = W256[(j + 1) & 0x0f]; \ 396 | s0 = sigma0_256(s0); \ 397 | s1 = W256[(j + 14) & 0x0f]; \ 398 | s1 = sigma1_256(s1); \ 399 | T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0); \ 400 | (d) += T1; \ 401 | (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ 402 | j++ 403 | 404 | void sha256_Transform(SHA256_CTX* context, const sha2_word32* data) 405 | { 406 | sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 407 | sha2_word32 T1, *W256; 408 | int j; 409 | 410 | W256 = (sha2_word32*)context->buffer; 411 | 412 | /* Initialize registers with the prev. intermediate value */ 413 | a = context->state[0]; 414 | b = context->state[1]; 415 | c = context->state[2]; 416 | d = context->state[3]; 417 | e = context->state[4]; 418 | f = context->state[5]; 419 | g = context->state[6]; 420 | h = context->state[7]; 421 | 422 | j = 0; 423 | do { 424 | /* Rounds 0 to 15 (unrolled): */ 425 | ROUND256_0_TO_15(a, b, c, d, e, f, g, h); 426 | ROUND256_0_TO_15(h, a, b, c, d, e, f, g); 427 | ROUND256_0_TO_15(g, h, a, b, c, d, e, f); 428 | ROUND256_0_TO_15(f, g, h, a, b, c, d, e); 429 | ROUND256_0_TO_15(e, f, g, h, a, b, c, d); 430 | ROUND256_0_TO_15(d, e, f, g, h, a, b, c); 431 | ROUND256_0_TO_15(c, d, e, f, g, h, a, b); 432 | ROUND256_0_TO_15(b, c, d, e, f, g, h, a); 433 | } while (j < 16); 434 | 435 | /* Now for the remaining rounds to 64: */ 436 | do { 437 | ROUND256(a, b, c, d, e, f, g, h); 438 | ROUND256(h, a, b, c, d, e, f, g); 439 | ROUND256(g, h, a, b, c, d, e, f); 440 | ROUND256(f, g, h, a, b, c, d, e); 441 | ROUND256(e, f, g, h, a, b, c, d); 442 | ROUND256(d, e, f, g, h, a, b, c); 443 | ROUND256(c, d, e, f, g, h, a, b); 444 | ROUND256(b, c, d, e, f, g, h, a); 445 | } while (j < 64); 446 | 447 | /* Compute the current intermediate hash value */ 448 | context->state[0] += a; 449 | context->state[1] += b; 450 | context->state[2] += c; 451 | context->state[3] += d; 452 | context->state[4] += e; 453 | context->state[5] += f; 454 | context->state[6] += g; 455 | context->state[7] += h; 456 | 457 | /* Clean up */ 458 | a = b = c = d = e = f = g = h = T1 = 0; 459 | } 460 | 461 | #else /* SHA2_UNROLL_TRANSFORM */ 462 | 463 | void sha256_Transform(SHA256_CTX* context, const sha2_word32* data) 464 | { 465 | sha2_word32 a, b, c, d, e, f, g, h, s0, s1; 466 | sha2_word32 T1, T2, *W256; 467 | int j; 468 | 469 | W256 = (sha2_word32*)context->buffer; 470 | 471 | /* Initialize registers with the prev. intermediate value */ 472 | a = context->state[0]; 473 | b = context->state[1]; 474 | c = context->state[2]; 475 | d = context->state[3]; 476 | e = context->state[4]; 477 | f = context->state[5]; 478 | g = context->state[6]; 479 | h = context->state[7]; 480 | 481 | j = 0; 482 | do { 483 | #if BYTE_ORDER == LITTLE_ENDIAN 484 | /* Copy data while converting to host byte order */ 485 | REVERSE32(*data++, W256[j]); 486 | /* Apply the SHA-256 compression function to update a..h */ 487 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 488 | #else /* BYTE_ORDER == LITTLE_ENDIAN */ 489 | /* Apply the SHA-256 compression function to update a..h with copy */ 490 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); 491 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 492 | T2 = Sigma0_256(a) + Maj(a, b, c); 493 | h = g; 494 | g = f; 495 | f = e; 496 | e = d + T1; 497 | d = c; 498 | c = b; 499 | b = a; 500 | a = T1 + T2; 501 | 502 | j++; 503 | } while (j < 16); 504 | 505 | do { 506 | /* Part of the message block expansion: */ 507 | s0 = W256[(j + 1) & 0x0f]; 508 | s0 = sigma0_256(s0); 509 | s1 = W256[(j + 14) & 0x0f]; 510 | s1 = sigma1_256(s1); 511 | 512 | /* Apply the SHA-256 compression function to update a..h */ 513 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 514 | (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0); 515 | T2 = Sigma0_256(a) + Maj(a, b, c); 516 | h = g; 517 | g = f; 518 | f = e; 519 | e = d + T1; 520 | d = c; 521 | c = b; 522 | b = a; 523 | a = T1 + T2; 524 | 525 | j++; 526 | } while (j < 64); 527 | 528 | /* Compute the current intermediate hash value */ 529 | context->state[0] += a; 530 | context->state[1] += b; 531 | context->state[2] += c; 532 | context->state[3] += d; 533 | context->state[4] += e; 534 | context->state[5] += f; 535 | context->state[6] += g; 536 | context->state[7] += h; 537 | 538 | /* Clean up */ 539 | a = b = c = d = e = f = g = h = T1 = T2 = 0; 540 | } 541 | 542 | #endif /* SHA2_UNROLL_TRANSFORM */ 543 | 544 | void sha256_Update(SHA256_CTX* context, const sha2_byte* data, size_t len) 545 | { 546 | unsigned int freespace, usedspace; 547 | 548 | if (len == 0) { 549 | /* Calling with no data is valid - we do nothing */ 550 | return; 551 | } 552 | 553 | usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 554 | if (usedspace > 0) { 555 | /* Calculate how much free space is available in the buffer */ 556 | freespace = SHA256_BLOCK_LENGTH - usedspace; 557 | 558 | if (len >= freespace) { 559 | /* Fill the buffer completely and process it */ 560 | MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); 561 | context->bitcount += freespace << 3; 562 | len -= freespace; 563 | data += freespace; 564 | sha256_Transform(context, (sha2_word32*)context->buffer); 565 | } else { 566 | /* The buffer is not yet full */ 567 | MEMCPY_BCOPY(&context->buffer[usedspace], data, len); 568 | context->bitcount += len << 3; 569 | /* Clean up: */ 570 | usedspace = freespace = 0; 571 | return; 572 | } 573 | } 574 | while (len >= SHA256_BLOCK_LENGTH) { 575 | /* Process as many complete blocks as we can */ 576 | sha256_Transform(context, (const sha2_word32*)data); 577 | context->bitcount += SHA256_BLOCK_LENGTH << 3; 578 | len -= SHA256_BLOCK_LENGTH; 579 | data += SHA256_BLOCK_LENGTH; 580 | } 581 | if (len > 0) { 582 | /* There's left-overs, so save 'em */ 583 | MEMCPY_BCOPY(context->buffer, data, len); 584 | context->bitcount += len << 3; 585 | } 586 | /* Clean up: */ 587 | usedspace = freespace = 0; 588 | } 589 | 590 | void sha256_Final(sha2_byte digest[], SHA256_CTX* context) 591 | { 592 | sha2_word32* d = (sha2_word32*)digest; 593 | unsigned int usedspace; 594 | sha2_word64* t; 595 | 596 | /* If no digest buffer is passed, we don't bother doing this: */ 597 | if (digest != (sha2_byte*)0) { 598 | usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; 599 | #if BYTE_ORDER == LITTLE_ENDIAN 600 | /* Convert FROM host byte order */ 601 | REVERSE64(context->bitcount, context->bitcount); 602 | #endif 603 | if (usedspace > 0) { 604 | /* Begin padding with a 1 bit: */ 605 | context->buffer[usedspace++] = 0x80; 606 | 607 | if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { 608 | /* Set-up for the last transform: */ 609 | MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); 610 | } else { 611 | if (usedspace < SHA256_BLOCK_LENGTH) { 612 | MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); 613 | } 614 | /* Do second-to-last transform: */ 615 | sha256_Transform(context, (sha2_word32*)context->buffer); 616 | 617 | /* And set-up for the last transform: */ 618 | MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); 619 | } 620 | } else { 621 | /* Set-up for the last transform: */ 622 | MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); 623 | 624 | /* Begin padding with a 1 bit: */ 625 | *context->buffer = 0x80; 626 | } 627 | /* Set the bit count: */ 628 | t = (sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH]; 629 | *t = context->bitcount; 630 | 631 | /* Final transform: */ 632 | sha256_Transform(context, (sha2_word32*)context->buffer); 633 | 634 | #if BYTE_ORDER == LITTLE_ENDIAN 635 | { 636 | /* Convert TO host byte order */ 637 | int j; 638 | for (j = 0; j < 8; j++) { 639 | REVERSE32(context->state[j], context->state[j]); 640 | *d++ = context->state[j]; 641 | } 642 | } 643 | #else 644 | MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); 645 | #endif 646 | } 647 | 648 | /* Clean up state data: */ 649 | MEMSET_BZERO(context, sizeof(SHA256_CTX)); 650 | usedspace = 0; 651 | } 652 | 653 | void sha256_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH]) 654 | { 655 | SHA256_CTX context; 656 | sha256_Init(&context); 657 | sha256_Update(&context, data, len); 658 | sha256_Final(digest, &context); 659 | } 660 | 661 | 662 | /*** SHA-512: *********************************************************/ 663 | void sha512_Init(SHA512_CTX* context) 664 | { 665 | if (context == (SHA512_CTX*)0) { 666 | return; 667 | } 668 | MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); 669 | MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); 670 | context->bitcount[0] = context->bitcount[1] = 0; 671 | } 672 | 673 | #ifdef SHA2_UNROLL_TRANSFORM 674 | 675 | /* Unrolled SHA-512 round macros: */ 676 | #if BYTE_ORDER == LITTLE_ENDIAN 677 | 678 | #define ROUND512_0_TO_15(a, b, c, d, e, f, g, h) \ 679 | REVERSE64(*data++, W512[j]); \ 680 | T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + W512[j]; \ 681 | (d) += T1, \ 682 | (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ 683 | j++ 684 | 685 | 686 | #else /* BYTE_ORDER == LITTLE_ENDIAN */ 687 | 688 | #define ROUND512_0_TO_15(a, b, c, d, e, f, g, h) \ 689 | T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + (W512[j] = *data++); \ 690 | (d) += T1; \ 691 | (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 692 | j++ 693 | 694 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 695 | 696 | #define ROUND512(a, b, c, d, e, f, g, h) \ 697 | s0 = W512[(j + 1) & 0x0f]; \ 698 | s0 = sigma0_512(s0); \ 699 | s1 = W512[(j + 14) & 0x0f]; \ 700 | s1 = sigma1_512(s1); \ 701 | T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0); \ 702 | (d) += T1; \ 703 | (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ 704 | j++ 705 | 706 | void sha512_Transform(SHA512_CTX* context, const sha2_word64* data) 707 | { 708 | sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 709 | sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; 710 | int j; 711 | 712 | /* Initialize registers with the prev. intermediate value */ 713 | a = context->state[0]; 714 | b = context->state[1]; 715 | c = context->state[2]; 716 | d = context->state[3]; 717 | e = context->state[4]; 718 | f = context->state[5]; 719 | g = context->state[6]; 720 | h = context->state[7]; 721 | 722 | j = 0; 723 | do { 724 | ROUND512_0_TO_15(a, b, c, d, e, f, g, h); 725 | ROUND512_0_TO_15(h, a, b, c, d, e, f, g); 726 | ROUND512_0_TO_15(g, h, a, b, c, d, e, f); 727 | ROUND512_0_TO_15(f, g, h, a, b, c, d, e); 728 | ROUND512_0_TO_15(e, f, g, h, a, b, c, d); 729 | ROUND512_0_TO_15(d, e, f, g, h, a, b, c); 730 | ROUND512_0_TO_15(c, d, e, f, g, h, a, b); 731 | ROUND512_0_TO_15(b, c, d, e, f, g, h, a); 732 | } while (j < 16); 733 | 734 | /* Now for the remaining rounds up to 79: */ 735 | do { 736 | ROUND512(a, b, c, d, e, f, g, h); 737 | ROUND512(h, a, b, c, d, e, f, g); 738 | ROUND512(g, h, a, b, c, d, e, f); 739 | ROUND512(f, g, h, a, b, c, d, e); 740 | ROUND512(e, f, g, h, a, b, c, d); 741 | ROUND512(d, e, f, g, h, a, b, c); 742 | ROUND512(c, d, e, f, g, h, a, b); 743 | ROUND512(b, c, d, e, f, g, h, a); 744 | } while (j < 80); 745 | 746 | /* Compute the current intermediate hash value */ 747 | context->state[0] += a; 748 | context->state[1] += b; 749 | context->state[2] += c; 750 | context->state[3] += d; 751 | context->state[4] += e; 752 | context->state[5] += f; 753 | context->state[6] += g; 754 | context->state[7] += h; 755 | 756 | /* Clean up */ 757 | a = b = c = d = e = f = g = h = T1 = 0; 758 | } 759 | 760 | #else /* SHA2_UNROLL_TRANSFORM */ 761 | 762 | void sha512_Transform(SHA512_CTX* context, const sha2_word64* data) 763 | { 764 | sha2_word64 a, b, c, d, e, f, g, h, s0, s1; 765 | sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; 766 | int j; 767 | 768 | /* Initialize registers with the prev. intermediate value */ 769 | a = context->state[0]; 770 | b = context->state[1]; 771 | c = context->state[2]; 772 | d = context->state[3]; 773 | e = context->state[4]; 774 | f = context->state[5]; 775 | g = context->state[6]; 776 | h = context->state[7]; 777 | 778 | j = 0; 779 | do { 780 | #if BYTE_ORDER == LITTLE_ENDIAN 781 | /* Convert TO host byte order */ 782 | REVERSE64(*data++, W512[j]); 783 | /* Apply the SHA-512 compression function to update a..h */ 784 | T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; 785 | #else /* BYTE_ORDER == LITTLE_ENDIAN */ 786 | /* Apply the SHA-512 compression function to update a..h with copy */ 787 | T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); 788 | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ 789 | T2 = Sigma0_512(a) + Maj(a, b, c); 790 | h = g; 791 | g = f; 792 | f = e; 793 | e = d + T1; 794 | d = c; 795 | c = b; 796 | b = a; 797 | a = T1 + T2; 798 | 799 | j++; 800 | } while (j < 16); 801 | 802 | do { 803 | /* Part of the message block expansion: */ 804 | s0 = W512[(j + 1) & 0x0f]; 805 | s0 = sigma0_512(s0); 806 | s1 = W512[(j + 14) & 0x0f]; 807 | s1 = sigma1_512(s1); 808 | 809 | /* Apply the SHA-512 compression function to update a..h */ 810 | T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + 811 | (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0); 812 | T2 = Sigma0_512(a) + Maj(a, b, c); 813 | h = g; 814 | g = f; 815 | f = e; 816 | e = d + T1; 817 | d = c; 818 | c = b; 819 | b = a; 820 | a = T1 + T2; 821 | 822 | j++; 823 | } while (j < 80); 824 | 825 | /* Compute the current intermediate hash value */ 826 | context->state[0] += a; 827 | context->state[1] += b; 828 | context->state[2] += c; 829 | context->state[3] += d; 830 | context->state[4] += e; 831 | context->state[5] += f; 832 | context->state[6] += g; 833 | context->state[7] += h; 834 | 835 | /* Clean up */ 836 | a = b = c = d = e = f = g = h = T1 = T2 = 0; 837 | } 838 | 839 | #endif /* SHA2_UNROLL_TRANSFORM */ 840 | 841 | void sha512_Update(SHA512_CTX* context, const sha2_byte* data, size_t len) 842 | { 843 | unsigned int freespace, usedspace; 844 | 845 | if (len == 0) { 846 | /* Calling with no data is valid - we do nothing */ 847 | return; 848 | } 849 | 850 | usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 851 | if (usedspace > 0) { 852 | /* Calculate how much free space is available in the buffer */ 853 | freespace = SHA512_BLOCK_LENGTH - usedspace; 854 | 855 | if (len >= freespace) { 856 | /* Fill the buffer completely and process it */ 857 | MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); 858 | ADDINC128(context->bitcount, freespace << 3); 859 | len -= freespace; 860 | data += freespace; 861 | sha512_Transform(context, (sha2_word64*)context->buffer); 862 | } else { 863 | /* The buffer is not yet full */ 864 | MEMCPY_BCOPY(&context->buffer[usedspace], data, len); 865 | ADDINC128(context->bitcount, len << 3); 866 | /* Clean up: */ 867 | usedspace = freespace = 0; 868 | return; 869 | } 870 | } 871 | while (len >= SHA512_BLOCK_LENGTH) { 872 | /* Process as many complete blocks as we can */ 873 | sha512_Transform(context, (const sha2_word64*)data); 874 | ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); 875 | len -= SHA512_BLOCK_LENGTH; 876 | data += SHA512_BLOCK_LENGTH; 877 | } 878 | if (len > 0) { 879 | /* There's left-overs, so save 'em */ 880 | MEMCPY_BCOPY(context->buffer, data, len); 881 | ADDINC128(context->bitcount, len << 3); 882 | } 883 | /* Clean up: */ 884 | usedspace = freespace = 0; 885 | } 886 | 887 | void sha512_Last(SHA512_CTX* context) 888 | { 889 | unsigned int usedspace; 890 | sha2_word64* t; 891 | 892 | usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 893 | #if BYTE_ORDER == LITTLE_ENDIAN 894 | /* Convert FROM host byte order */ 895 | REVERSE64(context->bitcount[0], context->bitcount[0]); 896 | REVERSE64(context->bitcount[1], context->bitcount[1]); 897 | #endif 898 | if (usedspace > 0) { 899 | /* Begin padding with a 1 bit: */ 900 | context->buffer[usedspace++] = 0x80; 901 | 902 | if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { 903 | /* Set-up for the last transform: */ 904 | MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); 905 | } else { 906 | if (usedspace < SHA512_BLOCK_LENGTH) { 907 | MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); 908 | } 909 | /* Do second-to-last transform: */ 910 | sha512_Transform(context, (sha2_word64*)context->buffer); 911 | 912 | /* And set-up for the last transform: */ 913 | MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); 914 | } 915 | } else { 916 | /* Prepare for final transform: */ 917 | MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); 918 | 919 | /* Begin padding with a 1 bit: */ 920 | *context->buffer = 0x80; 921 | } 922 | /* Store the length of input data (in bits): */ 923 | t = (sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH]; 924 | *t = context->bitcount[1]; 925 | t = (sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8]; 926 | *t = context->bitcount[0]; 927 | 928 | /* Final transform: */ 929 | sha512_Transform(context, (sha2_word64*)context->buffer); 930 | } 931 | 932 | void sha512_Final(sha2_byte digest[], SHA512_CTX* context) 933 | { 934 | sha2_word64* d = (sha2_word64*)digest; 935 | 936 | /* If no digest buffer is passed, we don't bother doing this: */ 937 | if (digest != (sha2_byte*)0) { 938 | sha512_Last(context); 939 | 940 | /* Save the hash data for output: */ 941 | #if BYTE_ORDER == LITTLE_ENDIAN 942 | { 943 | /* Convert TO host byte order */ 944 | int j; 945 | for (j = 0; j < 8; j++) { 946 | REVERSE64(context->state[j], context->state[j]); 947 | *d++ = context->state[j]; 948 | } 949 | } 950 | #else 951 | MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); 952 | #endif 953 | } 954 | 955 | /* Zero out state data */ 956 | MEMSET_BZERO(context, sizeof(SHA512_CTX)); 957 | } 958 | 959 | void sha512_Raw(const sha2_byte* data, size_t len, uint8_t digest[SHA512_DIGEST_LENGTH]) 960 | { 961 | SHA512_CTX context; 962 | sha512_Init(&context); 963 | sha512_Update(&context, data, len); 964 | sha512_Final(digest, &context); 965 | } 966 | 967 | void hmac_sha256(const uint8_t* key, const uint32_t keylen, const uint8_t* msg, const uint32_t msglen, uint8_t* hmac) 968 | { 969 | int i; 970 | uint8_t buf[SHA256_BLOCK_LENGTH], o_key_pad[SHA256_BLOCK_LENGTH], 971 | i_key_pad[SHA256_BLOCK_LENGTH]; 972 | SHA256_CTX ctx; 973 | 974 | memset(buf, 0, SHA256_BLOCK_LENGTH); 975 | if (keylen > SHA256_BLOCK_LENGTH) { 976 | sha256_Raw(key, keylen, buf); 977 | } else { 978 | memcpy(buf, key, keylen); 979 | } 980 | 981 | for (i = 0; i < SHA256_BLOCK_LENGTH; i++) { 982 | o_key_pad[i] = buf[i] ^ 0x5c; 983 | i_key_pad[i] = buf[i] ^ 0x36; 984 | } 985 | 986 | sha256_Init(&ctx); 987 | sha256_Update(&ctx, i_key_pad, SHA256_BLOCK_LENGTH); 988 | sha256_Update(&ctx, msg, msglen); 989 | sha256_Final(buf, &ctx); 990 | 991 | sha256_Init(&ctx); 992 | sha256_Update(&ctx, o_key_pad, SHA256_BLOCK_LENGTH); 993 | sha256_Update(&ctx, buf, SHA256_DIGEST_LENGTH); 994 | sha256_Final(hmac, &ctx); 995 | } 996 | 997 | void hmac_sha512(const uint8_t* key, const uint32_t keylen, const uint8_t* msg, const uint32_t msglen, uint8_t* hmac) 998 | { 999 | int i; 1000 | uint8_t buf[SHA512_BLOCK_LENGTH], o_key_pad[SHA512_BLOCK_LENGTH], 1001 | i_key_pad[SHA512_BLOCK_LENGTH]; 1002 | SHA512_CTX ctx; 1003 | 1004 | memset(buf, 0, SHA512_BLOCK_LENGTH); 1005 | if (keylen > SHA512_BLOCK_LENGTH) { 1006 | sha512_Raw(key, keylen, buf); 1007 | } else { 1008 | memcpy(buf, key, keylen); 1009 | } 1010 | 1011 | for (i = 0; i < SHA512_BLOCK_LENGTH; i++) { 1012 | o_key_pad[i] = buf[i] ^ 0x5c; 1013 | i_key_pad[i] = buf[i] ^ 0x36; 1014 | } 1015 | 1016 | sha512_Init(&ctx); 1017 | sha512_Update(&ctx, i_key_pad, SHA512_BLOCK_LENGTH); 1018 | sha512_Update(&ctx, msg, msglen); 1019 | sha512_Final(buf, &ctx); 1020 | 1021 | sha512_Init(&ctx); 1022 | sha512_Update(&ctx, o_key_pad, SHA512_BLOCK_LENGTH); 1023 | sha512_Update(&ctx, buf, SHA512_DIGEST_LENGTH); 1024 | sha512_Final(hmac, &ctx); 1025 | } 1026 | --------------------------------------------------------------------------------