bd02de9ad2ac52f6637c479782427b086ca7115f
[openssl.git] / crypto / blake2 / blake2_impl.h
1 /*
2  * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>.
3  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
4  *
5  * Licensed under the OpenSSL licenses, (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * https://www.openssl.org/source/license.html
9  * or in the file LICENSE in the source distribution.
10  */
11
12 /*
13  * Derived from the BLAKE2 reference implementation written by Samuel Neves.
14  * More information about the BLAKE2 hash function and its implementations
15  * can be found at https://blake2.net.
16  */
17
18 #include <string.h>
19 #include "e_os.h"
20
21 static ossl_inline uint32_t load32(const void *src)
22 {
23     const union {
24         long one;
25         char little;
26     } is_endian = { 1 };
27
28     if (is_endian.little) {
29         uint32_t w;
30         memcpy(&w, src, sizeof(w));
31         return w;
32     } else {
33         const uint8_t *p = (const uint8_t *)src;
34         uint32_t w = *p++;
35         w |= (uint32_t)(*p++) <<  8;
36         w |= (uint32_t)(*p++) << 16;
37         w |= (uint32_t)(*p++) << 24;
38         return w;
39     }
40 }
41
42 static ossl_inline uint64_t load64(const void *src)
43 {
44     const union {
45         long one;
46         char little;
47     } is_endian = { 1 };
48
49     if (is_endian.little) {
50         uint64_t w;
51         memcpy(&w, src, sizeof(w));
52         return w;
53     } else {
54         const uint8_t *p = (const uint8_t *)src;
55         uint64_t w = *p++;
56         w |= (uint64_t)(*p++) <<  8;
57         w |= (uint64_t)(*p++) << 16;
58         w |= (uint64_t)(*p++) << 24;
59         w |= (uint64_t)(*p++) << 32;
60         w |= (uint64_t)(*p++) << 40;
61         w |= (uint64_t)(*p++) << 48;
62         w |= (uint64_t)(*p++) << 56;
63         return w;
64     }
65 }
66
67 static ossl_inline void store32(void *dst, uint32_t w)
68 {
69     const union {
70         long one;
71         char little;
72     } is_endian = { 1 };
73
74     if (is_endian.little) {
75         memcpy(dst, &w, sizeof(w));
76     } else {
77         uint8_t *p = (uint8_t *)dst;
78         int i;
79
80         for (i = 0; i < 4; i++)
81             p[i] = (uint8_t)(w >> (8 * i));
82     }
83 }
84
85 static ossl_inline void store64(void *dst, uint64_t w)
86 {
87     const union {
88         long one;
89         char little;
90     } is_endian = { 1 };
91
92     if (is_endian.little) {
93         memcpy(dst, &w, sizeof(w));
94     } else {
95         uint8_t *p = (uint8_t *)dst;
96         int i;
97
98         for (i = 0; i < 8; i++)
99             p[i] = (uint8_t)(w >> (8 * i));
100     }
101 }
102
103 static ossl_inline uint64_t load48(const void *src)
104 {
105     const uint8_t *p = (const uint8_t *)src;
106     uint64_t w = *p++;
107     w |= (uint64_t)(*p++) <<  8;
108     w |= (uint64_t)(*p++) << 16;
109     w |= (uint64_t)(*p++) << 24;
110     w |= (uint64_t)(*p++) << 32;
111     w |= (uint64_t)(*p++) << 40;
112     return w;
113 }
114
115 static ossl_inline void store48(void *dst, uint64_t w)
116 {
117     uint8_t *p = (uint8_t *)dst;
118     *p++ = (uint8_t)w;
119     w >>= 8;
120     *p++ = (uint8_t)w;
121     w >>= 8;
122     *p++ = (uint8_t)w;
123     w >>= 8;
124     *p++ = (uint8_t)w;
125     w >>= 8;
126     *p++ = (uint8_t)w;
127     w >>= 8;
128     *p++ = (uint8_t)w;
129 }
130
131 static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned c)
132 {
133     return (w >> c) | (w << (32 - c));
134 }
135
136 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned c)
137 {
138     return (w >> c) | (w << (64 - c));
139 }