1 /*
2  * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * Derived from the BLAKE2 reference implementation written by Samuel Neves.
12  * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
13  * More information about the BLAKE2 hash function and its implementations
14  * can be found at https://blake2.net.
15  */
16 
17 #include <string.h>
18 #include "internal/endian.h"
19 
load32(const uint8_t * src)20 static ossl_inline uint32_t load32(const uint8_t *src)
21 {
22     DECLARE_IS_ENDIAN;
23 
24     if (IS_LITTLE_ENDIAN) {
25         uint32_t w;
26         memcpy(&w, src, sizeof(w));
27         return w;
28     } else {
29         uint32_t w = ((uint32_t)src[0])
30                    | ((uint32_t)src[1] <<  8)
31                    | ((uint32_t)src[2] << 16)
32                    | ((uint32_t)src[3] << 24);
33         return w;
34     }
35 }
36 
load64(const uint8_t * src)37 static ossl_inline uint64_t load64(const uint8_t *src)
38 {
39     DECLARE_IS_ENDIAN;
40 
41     if (IS_LITTLE_ENDIAN) {
42         uint64_t w;
43         memcpy(&w, src, sizeof(w));
44         return w;
45     } else {
46         uint64_t w = ((uint64_t)src[0])
47                    | ((uint64_t)src[1] <<  8)
48                    | ((uint64_t)src[2] << 16)
49                    | ((uint64_t)src[3] << 24)
50                    | ((uint64_t)src[4] << 32)
51                    | ((uint64_t)src[5] << 40)
52                    | ((uint64_t)src[6] << 48)
53                    | ((uint64_t)src[7] << 56);
54         return w;
55     }
56 }
57 
store32(uint8_t * dst,uint32_t w)58 static ossl_inline void store32(uint8_t *dst, uint32_t w)
59 {
60     DECLARE_IS_ENDIAN;
61 
62     if (IS_LITTLE_ENDIAN) {
63         memcpy(dst, &w, sizeof(w));
64     } else {
65         uint8_t *p = (uint8_t *)dst;
66         int i;
67 
68         for (i = 0; i < 4; i++)
69             p[i] = (uint8_t)(w >> (8 * i));
70     }
71 }
72 
store64(uint8_t * dst,uint64_t w)73 static ossl_inline void store64(uint8_t *dst, uint64_t w)
74 {
75     DECLARE_IS_ENDIAN;
76 
77     if (IS_LITTLE_ENDIAN) {
78         memcpy(dst, &w, sizeof(w));
79     } else {
80         uint8_t *p = (uint8_t *)dst;
81         int i;
82 
83         for (i = 0; i < 8; i++)
84             p[i] = (uint8_t)(w >> (8 * i));
85     }
86 }
87 
load48(const uint8_t * src)88 static ossl_inline uint64_t load48(const uint8_t *src)
89 {
90     uint64_t w = ((uint64_t)src[0])
91                | ((uint64_t)src[1] <<  8)
92                | ((uint64_t)src[2] << 16)
93                | ((uint64_t)src[3] << 24)
94                | ((uint64_t)src[4] << 32)
95                | ((uint64_t)src[5] << 40);
96     return w;
97 }
98 
store48(uint8_t * dst,uint64_t w)99 static ossl_inline void store48(uint8_t *dst, uint64_t w)
100 {
101     uint8_t *p = (uint8_t *)dst;
102     p[0] = (uint8_t)w;
103     p[1] = (uint8_t)(w>>8);
104     p[2] = (uint8_t)(w>>16);
105     p[3] = (uint8_t)(w>>24);
106     p[4] = (uint8_t)(w>>32);
107     p[5] = (uint8_t)(w>>40);
108 }
109 
rotr32(const uint32_t w,const unsigned int c)110 static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
111 {
112     return (w >> c) | (w << (32 - c));
113 }
114 
rotr64(const uint64_t w,const unsigned int c)115 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
116 {
117     return (w >> c) | (w << (64 - c));
118 }
119