Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/yescrypt/yescrypt-platform.h
1201 views
1
/*-
2
* Copyright 2013,2014 Alexander Peslyak
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted.
7
*
8
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
9
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
12
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18
* SUCH DAMAGE.
19
*/
20
21
#ifdef MAP_ANON
22
#include <sys/mman.h>
23
#endif
24
25
#include "yescrypt.h"
26
#define HUGEPAGE_THRESHOLD (12 * 1024 * 1024)
27
28
#ifdef __x86_64__
29
#define HUGEPAGE_SIZE (2 * 1024 * 1024)
30
#else
31
#undef HUGEPAGE_SIZE
32
#endif
33
34
static __inline uint32_t
35
le32dec(const void *pp)
36
{
37
const uint8_t *p = (uint8_t const *)pp;
38
39
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
40
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
41
}
42
43
static __inline void
44
le32enc(void *pp, uint32_t x)
45
{
46
uint8_t * p = (uint8_t *)pp;
47
48
p[0] = x & 0xff;
49
p[1] = (x >> 8) & 0xff;
50
p[2] = (x >> 16) & 0xff;
51
p[3] = (x >> 24) & 0xff;
52
}
53
54
static void *
55
alloc_region(yescrypt_region_t * region, size_t size)
56
{
57
size_t base_size = size;
58
uint8_t * base, * aligned;
59
#ifdef MAP_ANON
60
int flags =
61
#ifdef MAP_NOCORE
62
MAP_NOCORE |
63
#endif
64
MAP_ANON | MAP_PRIVATE;
65
#if defined(MAP_HUGETLB) && defined(HUGEPAGE_SIZE)
66
size_t new_size = size;
67
const size_t hugepage_mask = (size_t)HUGEPAGE_SIZE - 1;
68
if (size >= HUGEPAGE_THRESHOLD && size + hugepage_mask >= size) {
69
flags |= MAP_HUGETLB;
70
/*
71
* Linux's munmap() fails on MAP_HUGETLB mappings if size is not a multiple of
72
* huge page size, so let's round up to huge page size here.
73
*/
74
new_size = size + hugepage_mask;
75
new_size &= ~hugepage_mask;
76
}
77
base = mmap(NULL, new_size, PROT_READ | PROT_WRITE, flags, -1, 0);
78
if (base != MAP_FAILED) {
79
base_size = new_size;
80
} else
81
if (flags & MAP_HUGETLB) {
82
flags &= ~MAP_HUGETLB;
83
base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
84
}
85
86
#else
87
base = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, -1, 0);
88
#endif
89
if (base == MAP_FAILED)
90
base = NULL;
91
aligned = base;
92
#elif defined(HAVE_POSIX_MEMALIGN)
93
if ((errno = posix_memalign((void **)&base, 64, size)) != 0)
94
base = NULL;
95
aligned = base;
96
#else
97
base = aligned = NULL;
98
if (size + 63 < size) {
99
errno = ENOMEM;
100
} else if ((base = malloc(size + 63)) != NULL) {
101
aligned = base + 63;
102
aligned -= (uintptr_t)aligned & 63;
103
}
104
#endif
105
region->base = base;
106
region->aligned = aligned;
107
region->base_size = base ? base_size : 0;
108
region->aligned_size = base ? size : 0;
109
return aligned;
110
}
111
112
static __inline void
113
init_region(yescrypt_region_t * region)
114
{
115
region->base = region->aligned = NULL;
116
region->base_size = region->aligned_size = 0;
117
}
118
119
static int
120
free_region(yescrypt_region_t * region)
121
{
122
if (region->base) {
123
#ifdef MAP_ANON
124
if (munmap(region->base, region->base_size))
125
return -1;
126
#else
127
free(region->base);
128
#endif
129
}
130
init_region(region);
131
return 0;
132
}
133
134
int yescrypt_init_shared(yescrypt_shared_t * shared, const uint8_t * param, size_t paramlen,
135
uint64_t N, uint32_t r, uint32_t p, yescrypt_init_shared_flags_t flags, uint32_t mask,
136
uint8_t * buf, size_t buflen)
137
{
138
yescrypt_shared1_t* shared1 = &shared->shared1;
139
yescrypt_shared_t dummy, half1, half2;
140
uint8_t salt[32];
141
142
if (flags & YESCRYPT_SHARED_PREALLOCATED) {
143
if (!shared1->aligned || !shared1->aligned_size)
144
return -1;
145
} else {
146
init_region(shared1);
147
}
148
shared->mask1 = 1;
149
if (!param && !paramlen && !N && !r && !p && !buf && !buflen)
150
return 0;
151
152
init_region(&dummy.shared1);
153
dummy.mask1 = 1;
154
if (yescrypt_kdf(&dummy, shared1,
155
param, paramlen, NULL, 0, N, r, p, 0,
156
YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1,
157
salt, sizeof(salt)))
158
goto out;
159
160
half1 = half2 = *shared;
161
half1.shared1.aligned_size /= 2;
162
half2.shared1.aligned = (void*) ((size_t)half2.shared1.aligned + half1.shared1.aligned_size);
163
half2.shared1.aligned_size = half1.shared1.aligned_size;
164
N /= 2;
165
166
if (p > 1 && yescrypt_kdf(&half1, &half2.shared1,
167
param, paramlen, salt, sizeof(salt), N, r, p, 0,
168
YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_2,
169
salt, sizeof(salt)))
170
goto out;
171
172
if (yescrypt_kdf(&half2, &half1.shared1,
173
param, paramlen, salt, sizeof(salt), N, r, p, 0,
174
YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1,
175
salt, sizeof(salt)))
176
goto out;
177
178
if (yescrypt_kdf(&half1, &half2.shared1,
179
param, paramlen, salt, sizeof(salt), N, r, p, 0,
180
YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1,
181
buf, buflen))
182
goto out;
183
184
shared->mask1 = mask;
185
186
return 0;
187
188
out:
189
if (!(flags & YESCRYPT_SHARED_PREALLOCATED))
190
free_region(shared1);
191
return -1;
192
}
193
194
int
195
yescrypt_free_shared(yescrypt_shared_t * shared)
196
{
197
return free_region(&shared->shared1);
198
}
199
200
int
201
yescrypt_init_local(yescrypt_local_t * local)
202
{
203
init_region(local);
204
return 0;
205
}
206
207
int
208
yescrypt_free_local(yescrypt_local_t * local)
209
{
210
return free_region(local);
211
}
212
213