Add and use internal header that implements endianness check
[openssl.git] / providers / implementations / digests / blake2_impl.h
1 /*
2  * Copyright 2016-2017 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
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
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
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
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
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
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
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
115 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
116 {
117     return (w >> c) | (w << (64 - c));
118 }