694f9bb434dee0a2e7fadf6c8a554fb98e87f182
[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 uint8_t *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         uint32_t w = *src++;
34         w |= (uint32_t)(*src++) <<  8;
35         w |= (uint32_t)(*src++) << 16;
36         w |= (uint32_t)(*src++) << 24;
37         return w;
38     }
39 }
40
41 static ossl_inline uint64_t load64(const uint8_t *src)
42 {
43     const union {
44         long one;
45         char little;
46     } is_endian = { 1 };
47
48     if (is_endian.little) {
49         uint64_t w;
50         memcpy(&w, src, sizeof(w));
51         return w;
52     } else {
53         uint64_t w = *src++;
54         w |= (uint64_t)(*src++) <<  8;
55         w |= (uint64_t)(*src++) << 16;
56         w |= (uint64_t)(*src++) << 24;
57         w |= (uint64_t)(*src++) << 32;
58         w |= (uint64_t)(*src++) << 40;
59         w |= (uint64_t)(*src++) << 48;
60         w |= (uint64_t)(*src++) << 56;
61         return w;
62     }
63 }
64
65 static ossl_inline void store32(uint8_t *dst, uint32_t w)
66 {
67     const union {
68         long one;
69         char little;
70     } is_endian = { 1 };
71
72     if (is_endian.little) {
73         memcpy(dst, &w, sizeof(w));
74     } else {
75         uint8_t *p = (uint8_t *)dst;
76         int i;
77
78         for (i = 0; i < 4; i++)
79             p[i] = (uint8_t)(w >> (8 * i));
80     }
81 }
82
83 static ossl_inline void store64(uint8_t *dst, uint64_t w)
84 {
85     const union {
86         long one;
87         char little;
88     } is_endian = { 1 };
89
90     if (is_endian.little) {
91         memcpy(dst, &w, sizeof(w));
92     } else {
93         uint8_t *p = (uint8_t *)dst;
94         int i;
95
96         for (i = 0; i < 8; i++)
97             p[i] = (uint8_t)(w >> (8 * i));
98     }
99 }
100
101 static ossl_inline uint64_t load48(const uint8_t *src)
102 {
103     uint64_t w = *src++;
104     w |= (uint64_t)(*src++) <<  8;
105     w |= (uint64_t)(*src++) << 16;
106     w |= (uint64_t)(*src++) << 24;
107     w |= (uint64_t)(*src++) << 32;
108     w |= (uint64_t)(*src++) << 40;
109     return w;
110 }
111
112 static ossl_inline void store48(uint8_t *dst, uint64_t w)
113 {
114     uint8_t *p = (uint8_t *)dst;
115     *p++ = (uint8_t)w;
116     w >>= 8;
117     *p++ = (uint8_t)w;
118     w >>= 8;
119     *p++ = (uint8_t)w;
120     w >>= 8;
121     *p++ = (uint8_t)w;
122     w >>= 8;
123     *p++ = (uint8_t)w;
124     w >>= 8;
125     *p++ = (uint8_t)w;
126 }
127
128 static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned c)
129 {
130     return (w >> c) | (w << (32 - c));
131 }
132
133 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned c)
134 {
135     return (w >> c) | (w << (64 - c));
136 }