Index: Makefile =================================================================== RCS file: /cvs/src/lib/libcrypto/Makefile,v retrieving revision 1.27 diff -u -p -r1.27 Makefile --- Makefile 17 Mar 2018 16:20:01 -0000 1.27 +++ Makefile 18 Oct 2018 03:28:33 -0000 @@ -153,7 +153,7 @@ SRCS+= encode.c digest.c evp_enc.c evp_k SRCS+= e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c SRCS+= e_rc4.c e_aes.c names.c SRCS+= e_xcbc_d.c e_rc2.c e_cast.c -SRCS+= m_null.c m_md4.c m_md5.c m_sha1.c m_wp.c +SRCS+= m_null.c m_md4.c m_md5.c m_sha1.c m_blake2.c m_wp.c SRCS+= m_dss.c m_dss1.c m_ripemd.c m_ecdsa.c SRCS+= p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c SRCS+= bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c @@ -233,6 +233,9 @@ SRCS+= rsa_pmeth.c rsa_crpt.c rsa_meth.c # sha/ SRCS+= sha1dgst.c sha1_one.c sha256.c sha512.c +# blake2/ +SRCS+= blake2.c + # stack/ SRCS+= stack.c @@ -312,6 +315,7 @@ SRCS+= pcy_cache.c pcy_node.c pcy_data.c ${LCRYPTO_SRC}/ripemd \ ${LCRYPTO_SRC}/rsa \ ${LCRYPTO_SRC}/sha \ + ${LCRYPTO_SRC}/blake2 \ ${LCRYPTO_SRC}/stack \ ${LCRYPTO_SRC}/threads \ ${LCRYPTO_SRC}/ts \ @@ -373,6 +377,7 @@ HDRS=\ ${LCRYPTO_SRC}/ripemd/ripemd.h \ ${LCRYPTO_SRC}/rsa/rsa.h \ ${LCRYPTO_SRC}/sha/sha.h \ + ${LCRYPTO_SRC}/blake2/blake2.h \ ${LCRYPTO_SRC}/stack/safestack.h \ ${LCRYPTO_SRC}/stack/stack.h \ ${LCRYPTO_SRC}/ts/ts.h \ Index: Symbols.list =================================================================== RCS file: /cvs/src/lib/libcrypto/Symbols.list,v retrieving revision 1.76 diff -u -p -r1.76 Symbols.list --- Symbols.list 12 Sep 2018 06:35:38 -0000 1.76 +++ Symbols.list 18 Oct 2018 03:28:33 -0000 @@ -368,6 +368,14 @@ BIO_vfree BIO_vprintf BIO_vsnprintf BIO_write +BLAKE2b_Init +BLAKE2b_Init_Key +BLAKE2b_Update +BLAKE2b_Final +BLAKE2s_Init +BLAKE2s_Init_Key +BLAKE2s_Update +BLAKE2s_Final BN_BLINDING_convert BN_BLINDING_convert_ex BN_BLINDING_create_param @@ -1515,6 +1526,8 @@ EVP_bf_cfb EVP_bf_cfb64 EVP_bf_ecb EVP_bf_ofb +EVP_blake2b512 +EVP_blake2s256 EVP_camellia_128_cbc EVP_camellia_128_cfb1 EVP_camellia_128_cfb128 Index: shlib_version =================================================================== RCS file: /cvs/src/lib/libcrypto/shlib_version,v retrieving revision 1.46 diff -u -p -r1.46 shlib_version --- shlib_version 12 Sep 2018 06:35:38 -0000 1.46 +++ shlib_version 18 Oct 2018 03:28:33 -0000 @@ -1,3 +1,3 @@ # Don't forget to give libssl and libtls the same type of bump! major=44 -minor=1 +minor=2 Index: blake2/blake2.c =================================================================== RCS file: blake2/blake2.c diff -N blake2/blake2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blake2/blake2.c 18 Oct 2018 03:28:33 -0000 @@ -0,0 +1,573 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2018 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * this code was inspired by the BLAKE2 reference implementation + * written by Samuel Neves + */ + +#include + +#ifndef OPENSSL_NO_BLAKE2 + +#include + +#include +#include +#include + +#ifndef nitems +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#endif + +#include + +struct BLAKE2s_param { + uint8_t digest_length; + uint8_t key_length; + uint8_t fanout; + uint8_t depth; + uint32_t leaf_length; + uint32_t node_offset; + uint16_t xof_length; + uint8_t node_depth; + uint8_t inner_length; + uint8_t salt[BLAKE2S_SALTBYTES]; + uint8_t personal[BLAKE2S_PERSONALBYTES]; +} __packed __aligned(4); + +struct BLAKE2b_param { + uint8_t digest_length; + uint8_t key_length; + uint8_t fanout; + uint8_t depth; + uint32_t leaf_length; + uint32_t node_offset; + uint32_t xof_length; + uint8_t node_depth; + uint8_t inner_length; + uint8_t reserved[14]; + uint8_t salt[BLAKE2B_SALTBYTES]; + uint8_t personal[BLAKE2B_PERSONALBYTES]; +} __packed __aligned(4); + +#if (_BYTE_ORDER == _LITTLE_ENDIAN) +#define memcpyle32(_dst, _src, _len) memcpy((_dst), (_src), (_len)) +#else +static void +memcpyle32(void *dst, const void *src, size_t len) +{ + uint8_t *d = dst; + const uint8_t *s = src; + + while (len > 0) { + size_t i = len; + + switch (i) { + default: + i = 4; + case 4: + d[3] = s[0]; + case 3: + d[2] = s[1]; + case 2: + d[1] = s[2]; + case 1: + d[0] = s[3]; + } + + d += 4; + s += 4; + + len -= i; + } +} +#endif + +static inline uint32_t +ror32(uint32_t v, unsigned int r) +{ + return ((v >> r)|(v << (32 - r))); +} + +#if (_BYTE_ORDER == _LITTLE_ENDIAN) +#define memcpyle64(_dst, _src, _len) memcpy((_dst), (_src), (_len)) +#else +static void +memcpyle64(void *dst, const void *src, size_t len) +{ + uint8_t *d = dst; + const uint8_t *s = src; + + while (len > 0) { + size_t i = len; + + switch (i) { + default: + i = 8; + case 8: + d[7] = s[0]; + case 7: + d[6] = s[1]; + case 6: + d[5] = s[2]; + case 5: + d[4] = s[3]; + case 4: + d[3] = s[4]; + case 3: + d[2] = s[5]; + case 2: + d[1] = s[6]; + case 1: + d[0] = s[7]; + } + + d += 8; + s += 8; + + len -= i; + } +} +#endif + +static inline uint64_t +ror64(uint64_t v, unsigned int r) +{ + return ((v >> r)|(v << (64 - r))); +} + +/* + * BLAKE2s + */ + +static const uint32_t BLAKE2s_IV[8] = { + 0x6a09e667U, + 0xbb67ae85U, + 0x3c6ef372U, + 0xa54ff53aU, + 0x510e527fU, + 0x9b05688CU, + 0x1f83d9abU, + 0x5be0cd19U, +}; + +static const uint8_t BLAKE2s_Sigma[10][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, +}; + +static int +BLAKE2s_Init_State(struct BLAKE2s_state *s, size_t outbytes, size_t keybytes) +{ + struct BLAKE2s_param p; + const uint32_t *w; + unsigned int i; + + if (outbytes == 0 || outbytes > BLAKE2S_OUTBYTES) + return (0); + if (keybytes > BLAKE2S_KEYBYTES) + return (0); + + p.digest_length = outbytes; + p.key_length = 0; + p.fanout = 1; + p.depth = 1; + p.leaf_length = htole32(0); + p.node_offset = htole32(0); + p.xof_length = htole16(0); + p.node_depth = 0; + p.inner_length = 0; + memset(p.salt, 0, sizeof(p.salt)); + memset(p.personal, 0, sizeof(p.personal)); + + memset(s, 0, sizeof(*s)); + + w = (const uint32_t *)&p; + for (i = 0; i < nitems(s->h); i++) + s->h[i] = BLAKE2s_IV[i] ^ htole32(w[i]); + + return (1); +} + +int +BLAKE2s_Init(struct BLAKE2s_state *s, size_t outbytes) +{ + return (BLAKE2s_Init_State(s, outbytes, 0)); +} + +int +BLAKE2s_Init_Key(struct BLAKE2s_state *s, size_t outbytes, + const void *key, size_t keybytes) +{ + uint8_t zero[BLAKE2S_BLOCKBYTES]; + int rv; + + if (keybytes == 0) + return (0); + + rv = BLAKE2s_Init_State(s, outbytes, keybytes); + if (rv != 1) + return (rv); + + memset(zero, 0, sizeof(zero)); + + BLAKE2s_Update(s, key, keybytes); + BLAKE2s_Update(s, zero, sizeof(zero) - keybytes); + + return (1); +} + +#define BLAKE2s_G(r, m, i, a, b, c, d) do { \ + a = a + b + m[BLAKE2s_Sigma[r][2 * i + 0]]; \ + d = ror32(d ^ a, 16); \ + c = c + d; \ + b = ror32(b ^ c, 12); \ + a = a + b + m[BLAKE2s_Sigma[r][2*i+1]]; \ + d = ror32(d ^ a, 8); \ + c = c + d; \ + b = ror32(b ^ c, 7); \ +} while (0) + +static inline void +BLAKE2s_Round(unsigned int r, const uint32_t *m, uint32_t *v) +{ + BLAKE2s_G(r, m, 0, v[ 0], v[ 4], v[ 8], v[12]); + BLAKE2s_G(r, m, 1, v[ 1], v[ 5], v[ 9], v[13]); + BLAKE2s_G(r, m, 2, v[ 2], v[ 6], v[10], v[14]); + BLAKE2s_G(r, m, 3, v[ 3], v[ 7], v[11], v[15]); + BLAKE2s_G(r, m, 4, v[ 0], v[ 5], v[10], v[15]); + BLAKE2s_G(r, m, 5, v[ 1], v[ 6], v[11], v[12]); + BLAKE2s_G(r, m, 6, v[ 2], v[ 7], v[ 8], v[13]); + BLAKE2s_G(r, m, 7, v[ 3], v[ 4], v[ 9], v[14]); +} + +static void +BLAKE2s_Compress(struct BLAKE2s_state *s, const uint8_t *in) +{ + uint32_t m[16]; + uint32_t v[16]; + unsigned int i; + + memcpyle32(m, in, sizeof(m)); + + for (i = 0; i < nitems(s->h); i++) + v[i] = s->h[i]; + + v[ 8] = BLAKE2s_IV[0]; + v[ 9] = BLAKE2s_IV[1]; + v[10] = BLAKE2s_IV[2]; + v[11] = BLAKE2s_IV[3]; + v[12] = BLAKE2s_IV[4] ^ s->t[0]; + v[13] = BLAKE2s_IV[5] ^ s->t[1]; + v[14] = BLAKE2s_IV[6] ^ s->f[0]; + v[15] = BLAKE2s_IV[7] ^ s->f[1]; + + BLAKE2s_Round(0, m, v); + BLAKE2s_Round(1, m, v); + BLAKE2s_Round(2, m, v); + BLAKE2s_Round(3, m, v); + BLAKE2s_Round(4, m, v); + BLAKE2s_Round(5, m, v); + BLAKE2s_Round(6, m, v); + BLAKE2s_Round(7, m, v); + BLAKE2s_Round(8, m, v); + BLAKE2s_Round(9, m, v); + + for (i = 0; i < nitems(s->h); ++i) + s->h[i] = s->h[i] ^ v[i] ^ v[i + 8]; +} + +static inline void +BLAKE2s_Count(struct BLAKE2s_state *s, uint32_t c) +{ + s->t[0] += c; + s->t[1] += (s->t[0] < c); +} + +void +BLAKE2s_Update(struct BLAKE2s_state *s, const void *data, size_t len) +{ + const uint8_t *buf = data; + size_t used, free; + + if (len == 0) + return; + + used = s->buflen; + free = BLAKE2S_BLOCKBYTES - used; + + if (len > free) { + memcpy(s->buf + used, buf, free); + BLAKE2s_Count(s, BLAKE2S_BLOCKBYTES); + BLAKE2s_Compress(s, s->buf); + + used = 0; + buf += free; + len -= free; + + while (len > BLAKE2S_BLOCKBYTES) { + BLAKE2s_Count(s, BLAKE2S_BLOCKBYTES); + BLAKE2s_Compress(s, buf); + + buf += BLAKE2S_BLOCKBYTES; + len -= BLAKE2S_BLOCKBYTES; + } + } + memcpy(s->buf + used, buf, len); + s->buflen = used + len; +} + +void +BLAKE2s_Final(struct BLAKE2s_state *s, void *out, size_t outlen) +{ + size_t used, free; + + s->f[0] = ~0U; /* last block */ + + used = s->buflen; + free = BLAKE2S_BLOCKBYTES - used; + + memset(s->buf + used, 0, free); + BLAKE2s_Count(s, used); + BLAKE2s_Compress(s, s->buf); + + memcpyle32(out, s->h, outlen); +} + +/* + * BLAKE2b + */ + +static const uint64_t BLAKE2b_IV[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL, +}; + +static const uint8_t BLAKE2b_Sigma[12][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, +}; + +static int +BLAKE2b_Init_State(struct BLAKE2b_state *s, size_t outbytes, size_t keybytes) +{ + struct BLAKE2b_param p; + const uint64_t *w; + unsigned int i; + + if (outbytes == 0 || outbytes > BLAKE2B_OUTBYTES) + return (0); + if (keybytes > BLAKE2B_KEYBYTES) + return (0); + + p.digest_length = outbytes; + p.key_length = keybytes; + p.fanout = 1; + p.depth = 1; + p.leaf_length = htole32(0); + p.node_offset = htole32(0); + p.xof_length = htole32(0); + p.node_depth = 0; + p.inner_length = 0; + memset(p.reserved, 0, sizeof(p.reserved)); + memset(p.salt, 0, sizeof(p.salt)); + memset(p.personal, 0, sizeof(p.personal)); + + memset(s, 0, sizeof(*s)); + + w = (const uint64_t *)&p; + for (i = 0; i < nitems(s->h); i++) + s->h[i] = BLAKE2b_IV[i] ^ htole64(w[i]); + + return (1); +} + +int +BLAKE2b_Init(struct BLAKE2b_state *s, size_t outbytes) +{ + return (BLAKE2b_Init_State(s, outbytes, 0)); +} + +int +BLAKE2b_Init_Key(struct BLAKE2b_state *s, size_t outbytes, + const void *key, size_t keybytes) +{ + uint8_t zero[BLAKE2B_BLOCKBYTES]; + int rv; + + if (keybytes == 0) + return (0); + + rv = BLAKE2b_Init_State(s, outbytes, keybytes); + if (rv != 1) + return (rv); + + memset(zero, 0, sizeof(zero)); + + BLAKE2b_Update(s, key, keybytes); + BLAKE2b_Update(s, zero, sizeof(zero) - keybytes); + + return (1); +} + +#define BLAKE2b_G(r, m, i, a, b, c, d) do { \ + a = a + b + m[BLAKE2b_Sigma[r][2 * i + 0]]; \ + d = ror64(d ^ a, 32); \ + c = c + d; \ + b = ror64(b ^ c, 24); \ + a = a + b + m[BLAKE2b_Sigma[r][2 * i + 1]]; \ + d = ror64(d ^ a, 16); \ + c = c + d; \ + b = ror64(b ^ c, 63); \ +} while (0) + +static inline void +BLAKE2b_Round(unsigned int r, const uint64_t *m, uint64_t *v) +{ + BLAKE2b_G(r, m, 0, v[ 0], v[ 4], v[ 8], v[12]); + BLAKE2b_G(r, m, 1, v[ 1] ,v[ 5] ,v[ 9] ,v[13]); + BLAKE2b_G(r, m, 2, v[ 2] ,v[ 6] ,v[10] ,v[14]); + BLAKE2b_G(r, m, 3, v[ 3] ,v[ 7] ,v[11] ,v[15]); + BLAKE2b_G(r, m, 4, v[ 0] ,v[ 5] ,v[10] ,v[15]); + BLAKE2b_G(r, m, 5, v[ 1] ,v[ 6] ,v[11] ,v[12]); + BLAKE2b_G(r, m, 6, v[ 2] ,v[ 7] ,v[ 8] ,v[13]); + BLAKE2b_G(r, m, 7, v[ 3] ,v[ 4] ,v[ 9] ,v[14]); +} + +static void +BLAKE2b_Compress(struct BLAKE2b_state *s, const uint8_t *in) +{ + uint64_t m[16]; + uint64_t v[16]; + unsigned int i; + + memcpyle64(m, in, sizeof(m)); + + for (i = 0; i < nitems(s->h); i++) + v[i] = s->h[i]; + + v[ 8] = BLAKE2b_IV[0]; + v[ 9] = BLAKE2b_IV[1]; + v[10] = BLAKE2b_IV[2]; + v[11] = BLAKE2b_IV[3]; + v[12] = BLAKE2b_IV[4] ^ s->t[0]; + v[13] = BLAKE2b_IV[5] ^ s->t[1]; + v[14] = BLAKE2b_IV[6] ^ s->f[0]; + v[15] = BLAKE2b_IV[7] ^ s->f[1]; + + BLAKE2b_Round(0, m, v); + BLAKE2b_Round(1, m, v); + BLAKE2b_Round(2, m, v); + BLAKE2b_Round(3, m, v); + BLAKE2b_Round(4, m, v); + BLAKE2b_Round(5, m, v); + BLAKE2b_Round(6, m, v); + BLAKE2b_Round(7, m, v); + BLAKE2b_Round(8, m, v); + BLAKE2b_Round(9, m, v); + BLAKE2b_Round(10, m, v); + BLAKE2b_Round(11, m, v); + + for (i = 0; i < nitems(s->h); ++i) + s->h[i] = s->h[i] ^ v[i] ^ v[i + 8]; +} + +static inline void +BLAKE2b_Count(struct BLAKE2b_state *s, uint64_t c) +{ + s->t[0] += c; + s->t[1] += (s->t[0] < c); +} + +void +BLAKE2b_Update(struct BLAKE2b_state *s, const void *data, size_t len) +{ + const uint8_t *buf = data; + size_t used, free; + + if (len == 0) + return; + + used = s->buflen; + free = sizeof(s->buf) - used; + + if (len > free) { + memcpy(s->buf + used, buf, free); + BLAKE2b_Count(s, sizeof(s->buf)); + BLAKE2b_Compress(s, s->buf); + + used = 0; + buf += free; + len -= free; + + while (len > sizeof(s->buf)) { + BLAKE2b_Count(s, sizeof(s->buf)); + BLAKE2b_Compress(s, buf); + + buf += sizeof(s->buf); + len -= sizeof(s->buf); + } + } + + memcpy(s->buf + used, buf, len); + s->buflen = used + len; +} + +void +BLAKE2b_Final(struct BLAKE2b_state *s, void *out, size_t outlen) +{ + size_t used, free; + + s->f[0] = ~0ULL; /* last block */ + + used = s->buflen; + free = BLAKE2B_BLOCKBYTES - used; + + memset(s->buf + used, 0, free); + BLAKE2b_Count(s, used); + BLAKE2b_Compress(s, s->buf); + + memcpyle64(out, s->h, outlen); +} + +#endif /* OPENSSL_NO_BLAKE2 */ Index: blake2/blake2.h =================================================================== RCS file: blake2/blake2.h diff -N blake2/blake2.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blake2/blake2.h 18 Oct 2018 03:28:33 -0000 @@ -0,0 +1,80 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2018 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HEADER_BLAKE2_H +#define HEADER_BLAKE2_H + +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__OpenBSD__) +#define __bounded__(x, y, z) +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLAKE2S_BLOCKBYTES 64 +#define BLAKE2S_OUTBYTES 32 +#define BLAKE2S_KEYBYTES 32 +#define BLAKE2S_SALTBYTES 8 +#define BLAKE2S_PERSONALBYTES 8 + +#define BLAKE2B_BLOCKBYTES 128 +#define BLAKE2B_OUTBYTES 64 +#define BLAKE2B_KEYBYTES 64 +#define BLAKE2B_SALTBYTES 16 +#define BLAKE2B_PERSONALBYTES 16 + +struct BLAKE2s_state { + uint32_t h[8]; + uint32_t t[2]; + uint32_t f[2]; + uint8_t buf[BLAKE2S_BLOCKBYTES]; + size_t buflen; + uint8_t last_node; +}; + +typedef struct BLAKE2s_state BLAKE2S_CTX; + +struct BLAKE2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + size_t buflen; + uint8_t last_node; +}; + +typedef struct BLAKE2b_state BLAKE2B_CTX; + +int BLAKE2s_Init(struct BLAKE2s_state *, size_t); +int BLAKE2s_Init_Key(struct BLAKE2s_state *, size_t, const void *, size_t); +void BLAKE2s_Update(struct BLAKE2s_state *, const void *, size_t); +void BLAKE2s_Final(struct BLAKE2s_state *, void *, size_t); + +int BLAKE2b_Init(struct BLAKE2b_state *, size_t); +int BLAKE2b_Init_Key(struct BLAKE2b_state *, size_t, const void *, size_t); +void BLAKE2b_Update(struct BLAKE2b_state *, const void *, size_t); +void BLAKE2b_Final(struct BLAKE2b_state *, void *, size_t); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_BLAKE2_H */ Index: evp/c_all.c =================================================================== RCS file: /cvs/src/lib/libcrypto/evp/c_all.c,v retrieving revision 1.22 diff -u -p -r1.22 c_all.c --- evp/c_all.c 17 Mar 2018 16:20:01 -0000 1.22 +++ evp/c_all.c 18 Oct 2018 03:28:33 -0000 @@ -289,6 +289,10 @@ OpenSSL_add_all_digests_internal(void) #ifndef OPENSSL_NO_WHIRLPOOL EVP_add_digest(EVP_whirlpool()); #endif +#ifndef OPENSSL_NO_BLAKE2 + EVP_add_digest(EVP_blake2b512()); + EVP_add_digest(EVP_blake2s256()); +#endif } void Index: evp/evp.h =================================================================== RCS file: /cvs/src/lib/libcrypto/evp/evp.h,v retrieving revision 1.69 diff -u -p -r1.69 evp.h --- evp/evp.h 12 Sep 2018 06:35:38 -0000 1.69 +++ evp/evp.h 18 Oct 2018 03:28:33 -0000 @@ -692,6 +692,10 @@ const EVP_MD *EVP_ripemd160(void); #ifndef OPENSSL_NO_WHIRLPOOL const EVP_MD *EVP_whirlpool(void); #endif +#ifndef OPENSSL_NO_BLAKE2 +const EVP_MD *EVP_blake2b512(void); +const EVP_MD *EVP_blake2s256(void); +#endif #ifndef OPENSSL_NO_GOST const EVP_MD *EVP_gostr341194(void); const EVP_MD *EVP_gost2814789imit(void); Index: evp/m_blake2.c =================================================================== RCS file: evp/m_blake2.c diff -N evp/m_blake2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ evp/m_blake2.c 18 Oct 2018 03:28:33 -0000 @@ -0,0 +1,107 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2018 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifndef OPENSSL_NO_BLAKE2 + +#include +#include +#include + +static int +BLAKE2s256_Init(EVP_MD_CTX *ctx) +{ + return (BLAKE2s_Init(ctx->md_data, BLAKE2S_OUTBYTES)); +} + +static int +BLAKE2s256_Update(EVP_MD_CTX *ctx, const void *buf, size_t len) +{ + BLAKE2s_Update(ctx->md_data, buf, len); + + return (1); +} + +static int +BLAKE2s256_Final(EVP_MD_CTX *ctx, unsigned char *md) +{ + BLAKE2s_Final(ctx->md_data, md, BLAKE2S_OUTBYTES); + + return (1); +} + +static const EVP_MD BLAKE2s256_md = { + .type = NID_blake2s256, + .pkey_type = 0, + .md_size = BLAKE2S_OUTBYTES, + .flags = 0, + .init = BLAKE2s256_Init, + .update = BLAKE2s256_Update, + .final = BLAKE2s256_Final, + .block_size = BLAKE2S_BLOCKBYTES, + .ctx_size = sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX), +}; + +const EVP_MD * +EVP_blake2s256(void) +{ + return (&BLAKE2s256_md); +} + +static int +BLAKE2b512_Init(EVP_MD_CTX *ctx) +{ + return (BLAKE2b_Init(ctx->md_data, BLAKE2B_OUTBYTES)); +} + +static int +BLAKE2b512_Update(EVP_MD_CTX *ctx, const void *buf, size_t len) +{ + BLAKE2b_Update(ctx->md_data, buf, len); + + return (1); +} + +static int +BLAKE2b512_Final(EVP_MD_CTX *ctx, unsigned char *md) +{ + BLAKE2b_Final(ctx->md_data, md, BLAKE2B_OUTBYTES); + + return (1); +} + +static const EVP_MD BLAKE2b512_md = { + .type = NID_blake2b512, + .pkey_type = 0, + .md_size = BLAKE2B_OUTBYTES, + .flags = 0, + .init = BLAKE2b512_Init, + .update = BLAKE2b512_Update, + .final = BLAKE2b512_Final, + .block_size = BLAKE2B_BLOCKBYTES, + .ctx_size = sizeof(EVP_MD *) + sizeof(BLAKE2B_CTX), +}; + +const EVP_MD * +EVP_blake2b512(void) +{ + return (&BLAKE2b512_md); +} + +#endif /* ifndef OPENSSL_NO_BLAKE2 */ Index: man/BLAKE2.3 =================================================================== RCS file: man/BLAKE2.3 diff -N man/BLAKE2.3 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ man/BLAKE2.3 18 Oct 2018 03:28:33 -0000 @@ -0,0 +1,160 @@ +.\" $OpenBSD$ +.\" +.\" Copyright (c) 2018 David Gwynne +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt BLAKE2 3 +.Os +.Sh NAME +.Nm BLAKE2b_Init , +.Nm BLAKE2b_Init_Key , +.Nm BLAKE2b_Update , +.Nm BLAKE2b_Final , +.Nm BLAKE2s_Init , +.Nm BLAKE2s_Init_Key , +.Nm BLAKE2s_Update , +.Nm BLAKE2s_Final +.Nd BLAKE2 Hash Algorithm +.Sh SYNOPSIS +.In openssl/blake2.h +.Ft int +.Fo BLAKE2b_Init +.Fa "BLAKE2B_CTX *ctx" +.Fa "size_t digest_length" +.Fc +.Ft int +.Fo BLAKE2b_Init_Key +.Fa "BLAKE2B_CTX *ctx" +.Fa "size_t digest_length" +.Fa "const void *key" +.Fa "size_t key_length" +.Fc +.Ft void +.Fo BLAKE2b_Update +.Fa "BLAKE2B_CTX *ctx" +.Fa "const void *data" +.Fa "size_t length" +.Fc +.Ft void +.Fo BLAKE2b_Final +.Fa "BLAKE2B_CTX *ctx" +.Fa "void *digest" +.Fa "size_t digest_length" +.Fc +.Ft int +.Fo BLAKE2s_Init +.Fa "BLAKE2S_CTX *ctx" +.Fa "size_t digest_length" +.Fc +.Ft int +.Fo BLAKE2s_Init_Key +.Fa "BLAKE2S_CTX *ctx" +.Fa "size_t digest_length" +.Fa "const void *key" +.Fa "size_t key_length" +.Fc +.Ft void +.Fo BLAKE2s_Update +.Fa "BLAKE2S_CTX *ctx" +.Fa "const void *data" +.Fa "size_t length" +.Fc +.Ft void +.Fo BLAKE2s_Final +.Fa "BLAKE2s_CTX *ctx" +.Fa "void *digest" +.Fa "size_t digest_length" +.Fc +.Fd #define BLAKE2B_OUTBYTES 64 +.Fd #define BLAKE2B_KEYBYTES 64 +.Fd #define BLAKE2S_OUTBYTES 32 +.Fd #define BLAKE2S_KEYBYTES 32 +.Sh DESCRIPTION +BLAKE2b and BLAKE2s are flavours of the BLAKE2 cryptographic hash +function specified in RFC 7693. +.Pp +BLAKE2b is optimised for 64 bit platforms, and produces digests +between 1 and +.Dv BLAKE2B_OUTBYTES +bytes in length. +.Pp +BLAKE2s is optimised for 8 to 32 bit platforms, and produces digests +between 1 and +.Dv BLAKE2S_OUTBYTES +bytes in length. +.Pp +.Fn BLAKE2b_Init +and +.Fn BLAKE2s_Init +initialise their respective context types referenced by +.Fa ctx +for generating digests of the length specified by +.Fa digest_length . +.Pp +.Fn BLAKE2b_Init_Key +and +.Fn BLAKE2s_Init_Key +initialise their respective context types referenced by +.Fa ctx +for generating keyed hashes of the length specified by +.Fa digest_length . +The hash is inititialised with +.Fa key +of length +.Fa key_length . +.Pp +.Fn BLAKE2b_Update +and +.Fn BLAKE2s_Update +feeds +.Fa data +of length +.Fa len +into the context +.Fa ctx . +Multiple updates may occur to feed multiple chunks of data into the hash. +.Pp +.Fn BLAKE2b_Final +and +.Fn BLAKE2s_Final +generates the hash in the context +.Fa ctx +and places it in +.Fa digest . +.Fa digest_length +must match the value used to initialize +.Fa ctx . +.Pp +Applications should use the higher level functions +.Xr EVP_DigestInit 3 +etc. instead of calling the hash functions directly. +.Sh RETURN VALUES +.Fn BLAKE2b_Init , +.Fn BLAKE2b_Init_Key , +.Fn BLAKE2s_Init , +and +.Fn BLAKE2s_Init_Key +return 1 for success or 0 for failure. +.Sh SEE ALSO +.Xr EVP_DigestInit 3 , +.Xr HMAC 3 +.Sh STANDARDS +.Rs +.%A M-J. Saarinen +.%A J-P. Aumasson +.%D November 2015 +.%R RFC 7693 +.%T The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC) +.Re Index: man/EVP_DigestInit.3 =================================================================== RCS file: /cvs/src/lib/libcrypto/man/EVP_DigestInit.3,v retrieving revision 1.15 diff -u -p -r1.15 EVP_DigestInit.3 --- man/EVP_DigestInit.3 27 Mar 2018 17:35:50 -0000 1.15 +++ man/EVP_DigestInit.3 18 Oct 2018 03:28:33 -0000 @@ -90,6 +90,8 @@ .Nm EVP_dss , .Nm EVP_dss1 , .Nm EVP_ripemd160 , +.Nm EVP_blake2b512 , +.Nm EVP_blake2s256 , .Nm EVP_get_digestbyname , .Nm EVP_get_digestbynid , .Nm EVP_get_digestbyobj @@ -222,6 +224,10 @@ .Ft const EVP_MD * .Fn EVP_ripemd160 void .Ft const EVP_MD * +.Fn EVP_blake2b512 void +.Ft const EVP_MD * +.Fn EVP_blake2s256 void +.Ft const EVP_MD * .Fo EVP_get_digestbyname .Fa "const char *name" .Fc @@ -420,12 +426,14 @@ function is only retained for compatibil .Fn EVP_sha256 , .Fn EVP_sha384 , .Fn EVP_sha512 , +.Fn EVP_ripemd160 , +.Fn EVP_blake2b512 , and -.Fn EVP_ripemd160 +.Fn EVP_blake2s256 return .Vt EVP_MD -structures for the MD5, SHA1, SHA224, SHA256, SHA384, SHA512 and -RIPEMD160 digest algorithms respectively. +structures for the MD5, SHA1, SHA224, SHA256, SHA384, SHA512, +RIPEMD160, BLAKE2b512, and BLAKE2s256 digest algorithms respectively. .Pp .Fn EVP_md5_sha1 returns an @@ -556,8 +564,10 @@ is .Fn EVP_sha1 , .Fn EVP_dss , .Fn EVP_dss1 , +.Fn EVP_ripemd160 , +.Fn EVP_blake2b512 , and -.Fn EVP_ripemd160 +.Fn EVP_blake2s256 , return pointers to the corresponding .Vt EVP_MD structures. Index: man/Makefile =================================================================== RCS file: /cvs/src/lib/libcrypto/man/Makefile,v retrieving revision 1.142 diff -u -p -r1.142 Makefile --- man/Makefile 8 Jul 2018 23:00:17 -0000 1.142 +++ man/Makefile 18 Oct 2018 03:28:33 -0000 @@ -43,6 +43,7 @@ MAN= \ BIO_s_socket.3 \ BIO_set_callback.3 \ BIO_should_retry.3 \ + BLAKE2.3 \ BN_BLINDING_new.3 \ BN_CTX_new.3 \ BN_CTX_start.3 \ Index: objects/objects.txt =================================================================== RCS file: /cvs/src/lib/libcrypto/objects/objects.txt,v retrieving revision 1.21 diff -u -p -r1.21 objects.txt --- objects/objects.txt 17 Mar 2018 14:37:41 -0000 1.21 +++ objects/objects.txt 18 Oct 2018 03:28:33 -0000 @@ -657,6 +657,9 @@ algorithm 29 : RSA-SHA1-2 : sha1WithRS 1 3 36 3 2 1 : RIPEMD160 : ripemd160 1 3 36 3 3 1 2 : RSA-RIPEMD160 : ripemd160WithRSA +1 3 6 1 4 1 1722 12 2 1 16 : BLAKE2b512 : blake2b512 +1 3 6 1 4 1 1722 12 2 2 8 : BLAKE2s256 : blake2s256 + !Cname sxnet 1 3 101 1 4 1 : SXNetID : Strong Extranet ID