blob: 80b717e79c08ab4ae9dd5163c13c0cdc58ec9a6d [file] [log] [blame]
Bill Cox2d0b4412016-03-09 23:08:31 +01001/*
Pauli677963e2017-08-18 13:52:46 +10002 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
Bill Cox2d0b4412016-03-09 23:08:31 +01003 *
Rich Salzb1322252016-05-17 14:52:22 -04004 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
Kurt Roeckx208527a2016-03-10 00:49:55 +01007 * https://www.openssl.org/source/license.html
Bill Cox2d0b4412016-03-09 23:08:31 +01008 */
9
Kurt Roeckx208527a2016-03-10 00:49:55 +010010/*
11 * Derived from the BLAKE2 reference implementation written by Samuel Neves.
Rich Salzb1322252016-05-17 14:52:22 -040012 * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
Kurt Roeckx208527a2016-03-10 00:49:55 +010013 * More information about the BLAKE2 hash function and its implementations
14 * can be found at https://blake2.net.
15 */
Bill Cox2d0b4412016-03-09 23:08:31 +010016
Bill Cox2d0b4412016-03-09 23:08:31 +010017#include <string.h>
18
Kurt Roeckxa5741082016-03-11 01:06:51 +010019static ossl_inline uint32_t load32(const uint8_t *src)
Bill Cox2d0b4412016-03-09 23:08:31 +010020{
Kurt Roeckx208527a2016-03-10 00:49:55 +010021 const union {
22 long one;
23 char little;
24 } is_endian = { 1 };
25
26 if (is_endian.little) {
27 uint32_t w;
28 memcpy(&w, src, sizeof(w));
29 return w;
30 } else {
Andy Polyakov1fab06a2016-03-13 22:19:53 +010031 uint32_t w = ((uint32_t)src[0])
32 | ((uint32_t)src[1] << 8)
33 | ((uint32_t)src[2] << 16)
34 | ((uint32_t)src[3] << 24);
Kurt Roeckx208527a2016-03-10 00:49:55 +010035 return w;
36 }
Bill Cox2d0b4412016-03-09 23:08:31 +010037}
38
Kurt Roeckxa5741082016-03-11 01:06:51 +010039static ossl_inline uint64_t load64(const uint8_t *src)
Bill Cox2d0b4412016-03-09 23:08:31 +010040{
Kurt Roeckx208527a2016-03-10 00:49:55 +010041 const union {
42 long one;
43 char little;
44 } is_endian = { 1 };
45
46 if (is_endian.little) {
47 uint64_t w;
48 memcpy(&w, src, sizeof(w));
49 return w;
50 } else {
Andy Polyakov1fab06a2016-03-13 22:19:53 +010051 uint64_t w = ((uint64_t)src[0])
52 | ((uint64_t)src[1] << 8)
53 | ((uint64_t)src[2] << 16)
54 | ((uint64_t)src[3] << 24)
55 | ((uint64_t)src[4] << 32)
56 | ((uint64_t)src[5] << 40)
57 | ((uint64_t)src[6] << 48)
58 | ((uint64_t)src[7] << 56);
Kurt Roeckx208527a2016-03-10 00:49:55 +010059 return w;
60 }
Bill Cox2d0b4412016-03-09 23:08:31 +010061}
62
Kurt Roeckxa5741082016-03-11 01:06:51 +010063static ossl_inline void store32(uint8_t *dst, uint32_t w)
Bill Cox2d0b4412016-03-09 23:08:31 +010064{
Kurt Roeckx208527a2016-03-10 00:49:55 +010065 const union {
66 long one;
67 char little;
68 } is_endian = { 1 };
69
70 if (is_endian.little) {
71 memcpy(dst, &w, sizeof(w));
72 } else {
73 uint8_t *p = (uint8_t *)dst;
74 int i;
75
76 for (i = 0; i < 4; i++)
77 p[i] = (uint8_t)(w >> (8 * i));
78 }
Bill Cox2d0b4412016-03-09 23:08:31 +010079}
80
Kurt Roeckxa5741082016-03-11 01:06:51 +010081static ossl_inline void store64(uint8_t *dst, uint64_t w)
Bill Cox2d0b4412016-03-09 23:08:31 +010082{
Kurt Roeckx208527a2016-03-10 00:49:55 +010083 const union {
84 long one;
85 char little;
86 } is_endian = { 1 };
87
88 if (is_endian.little) {
89 memcpy(dst, &w, sizeof(w));
90 } else {
91 uint8_t *p = (uint8_t *)dst;
92 int i;
93
94 for (i = 0; i < 8; i++)
95 p[i] = (uint8_t)(w >> (8 * i));
96 }
Bill Cox2d0b4412016-03-09 23:08:31 +010097}
98
Kurt Roeckxa5741082016-03-11 01:06:51 +010099static ossl_inline uint64_t load48(const uint8_t *src)
Bill Cox2d0b4412016-03-09 23:08:31 +0100100{
Andy Polyakov1fab06a2016-03-13 22:19:53 +0100101 uint64_t w = ((uint64_t)src[0])
102 | ((uint64_t)src[1] << 8)
103 | ((uint64_t)src[2] << 16)
104 | ((uint64_t)src[3] << 24)
105 | ((uint64_t)src[4] << 32)
106 | ((uint64_t)src[5] << 40);
Bill Cox2d0b4412016-03-09 23:08:31 +0100107 return w;
108}
109
Kurt Roeckxa5741082016-03-11 01:06:51 +0100110static ossl_inline void store48(uint8_t *dst, uint64_t w)
Bill Cox2d0b4412016-03-09 23:08:31 +0100111{
112 uint8_t *p = (uint8_t *)dst;
Andy Polyakov1fab06a2016-03-13 22:19:53 +0100113 p[0] = (uint8_t)w;
114 p[1] = (uint8_t)(w>>8);
115 p[2] = (uint8_t)(w>>16);
116 p[3] = (uint8_t)(w>>24);
117 p[4] = (uint8_t)(w>>32);
118 p[5] = (uint8_t)(w>>40);
Bill Cox2d0b4412016-03-09 23:08:31 +0100119}
120
Kurt Roeckx53a51672016-03-11 01:19:43 +0100121static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
Bill Cox2d0b4412016-03-09 23:08:31 +0100122{
123 return (w >> c) | (w << (32 - c));
124}
125
Kurt Roeckx53a51672016-03-11 01:19:43 +0100126static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
Bill Cox2d0b4412016-03-09 23:08:31 +0100127{
128 return (w >> c) | (w << (64 - c));
129}