From 6d9f2cae7956dc8c614ca9e8e6fa24c9ab0458eb Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 29 Dec 2015 19:00:52 +0100 Subject: [PATCH] argon2: ensure that memory is cacheline aligned; use mmap(2) if possible --- .../crypto_pwhash/argon2/argon2-core.c | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-core.c b/src/libsodium/crypto_pwhash/argon2/argon2-core.c index aced92bd..b8f5327f 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-core.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-core.c @@ -66,6 +66,7 @@ static void store_block(void *output, const block *src) { /***************Memory allocators*****************/ int allocate_memory(block_region **region, uint32_t m_cost) { + void *base; block *memory; size_t memory_size; @@ -82,11 +83,39 @@ int allocate_memory(block_region **region, uint32_t m_cost) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - memory = (block *)malloc(memory_size); /*3. Try to allocate block*/ +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, +# ifdef MAP_NOCORE + MAP_ANON | MAP_PRIVATE | MAP_NOCORE, +# else + MAP_ANON | MAP_PRIVATE, +# endif + -1, 0)) == MAP_FAILED) { + base = NULL; /* LCOV_EXCL_LINE */ + } + memcpy(&memory, &base, sizeof memory); +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) { + base = NULL; + } + memcpy(&memory, &base, sizeof memory); +#else + memory = NULL; + if (size + 63 < size) { + base = NULL; + errno = ENOMEM; + } else if ((base = malloc(memory_size + 63)) != NULL) { + uint8_t *aligned = ((uint8_t *) base) + 63; + aligned -= (uintptr_t) aligned & 63; + memcpy(&memory, &aligned, sizeof memory); + } +#endif if (!memory) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - (*region)->memory = memory; + (*region)->base = base; + (*region)->memory = memory; + (*region)->size = base ? memory_size : 0; return ARGON2_OK; } @@ -101,7 +130,15 @@ void clear_memory(argon2_instance_t *instance, int clear) { } void free_memory(block_region *region) { - free(region->memory); + if (region->base) { +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if (munmap(region->base, region->size)) { + return; /* LCOV_EXCL_LINE */ + } +#else + free(region->base); +#endif + } free(region); }