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 #ifndef MAP_NOCORE 34 # define MAP_NOCORE 0 35 #endif 36 #ifndef MAP_POPULATE 37 # define MAP_POPULATE 0 38 #endif 39 40 void * 41 alloc_region(escrypt_region_t *region, size_t size) 42 { 43 uint8_t *base, *aligned; 44 #if defined(MAP_ANON) && defined(HAVE_MMAP) 45 if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE, 46 MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE, 47 -1, 0)) == MAP_FAILED) { 48 base = NULL; /* LCOV_EXCL_LINE */ 49 } /* LCOV_EXCL_LINE */ 50 aligned = base; 51 #elif defined(HAVE_POSIX_MEMALIGN) 52 if ((errno = posix_memalign((void **) &base, 64, size)) != 0) { 53 base = NULL; 54 } 55 aligned = base; 56 #else 57 base = aligned = NULL; 58 if (size + 63 < size) { 59 errno = ENOMEM; 60 } else if ((base = (uint8_t *) malloc(size + 63)) != NULL) { 61 aligned = base + 63; 62 aligned -= (uintptr_t) aligned & 63; 63 } 64 #endif 65 region->base = base; 66 region->aligned = aligned; 67 region->size = base ? size : 0; 68 69 return aligned; 70 } 71 72 static inline void 73 init_region(escrypt_region_t *region) 74 { 75 region->base = region->aligned = NULL; 76 region->size = 0; 77 } 78 79 int 80 free_region(escrypt_region_t *region) 81 { 82 if (region->base) { 83 #if defined(MAP_ANON) && defined(HAVE_MMAP) 84 if (munmap(region->base, region->size)) { 85 return -1; /* LCOV_EXCL_LINE */ 86 } 87 #else 88 free(region->base); 89 #endif 90 } 91 init_region(region); 92 93 return 0; 94 } 95 96 int 97 escrypt_init_local(escrypt_local_t *local) 98 { 99 init_region(local); 100 101 return 0; 102 } 103 104 int 105 escrypt_free_local(escrypt_local_t *local) 106 { 107 return free_region(local); 108 } 109