85d4267df47987db838fbad04d3f97307bfcf5a2
[trex.git] /
1 /*-
2  * Copyright 2013 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 HAVE_SYS_MMAN_H
22 # include <sys/mman.h>
23 #endif
24 #include <errno.h>
25 #include <stdlib.h>
26
27 #include "crypto_scrypt.h"
28 #include "runtime.h"
29
30 #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
31 # define MAP_ANON MAP_ANONYMOUS
32 #endif
33
34 void *
35 alloc_region(escrypt_region_t * region, size_t size)
36 {
37         uint8_t * base, * aligned;
38 #if defined(MAP_ANON) && defined(HAVE_MMAP)
39         if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE,
40 #ifdef MAP_NOCORE
41             MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
42 #else
43             MAP_ANON | MAP_PRIVATE,
44 #endif
45             -1, 0)) == MAP_FAILED)
46                 base = NULL; /* LCOV_EXCL_LINE */
47         aligned = base;
48 #elif defined(HAVE_POSIX_MEMALIGN)
49         if ((errno = posix_memalign((void **) &base, 64, size)) != 0)
50                 base = NULL;
51         aligned = base;
52 #else
53         base = aligned = NULL;
54         if (size + 63 < size)
55                 errno = ENOMEM;
56         else if ((base = (uint8_t *) malloc(size + 63)) != NULL) {
57                 aligned = base + 63;
58                 aligned -= (uintptr_t)aligned & 63;
59         }
60 #endif
61         region->base = base;
62         region->aligned = aligned;
63         region->size = base ? size : 0;
64         return aligned;
65 }
66
67 static inline void
68 init_region(escrypt_region_t * region)
69 {
70         region->base = region->aligned = NULL;
71         region->size = 0;
72 }
73
74 int
75 free_region(escrypt_region_t * region)
76 {
77         if (region->base) {
78 #if defined(MAP_ANON) && defined(HAVE_MMAP)
79                 if (munmap(region->base, region->size))
80                         return -1; /* LCOV_EXCL_LINE */
81 #else
82                 free(region->base);
83 #endif
84         }
85         init_region(region);
86         return 0;
87 }
88
89 int
90 escrypt_init_local(escrypt_local_t * local)
91 {
92         init_region(local);
93         return 0;
94 }
95
96 int
97 escrypt_free_local(escrypt_local_t * local)
98 {
99         return free_region(local);
100 }