From a50a2dd85cfeff4aefb80cf793a1beb0816ca2ec Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Fri, 19 Dec 2014 15:55:14 +0900 Subject: [PATCH 01/13] Add src/windows that contains necessary files to produce native JNI library for Windows. Signed-off-by: Haochen Xie --- src/windows/README | 26 ++ src/windows/build.bat | 18 ++ src/windows/c/crypto_scrypt-sse.c | 370 +++++++++++++++++++++++ src/windows/c/mman.c | 180 +++++++++++ src/windows/c/scrypt_jni.c | 54 ++++ src/windows/c/sha256.c | 412 ++++++++++++++++++++++++++ src/windows/include/config.h | 99 +++++++ src/windows/include/crypto_scrypt.h | 46 +++ src/windows/include/inttypes.h | 305 +++++++++++++++++++ src/windows/include/memlimit.h | 42 +++ src/windows/include/scrypt_jni.h | 21 ++ src/windows/include/scrypt_platform.h | 12 + src/windows/include/sha256.h | 62 ++++ src/windows/include/stdint.h | 247 +++++++++++++++ src/windows/include/sys/mman.h | 57 ++++ src/windows/include/sysendian.h | 146 +++++++++ src/windows/include/unistd.h | 48 +++ 17 files changed, 2145 insertions(+) create mode 100644 src/windows/README create mode 100644 src/windows/build.bat create mode 100644 src/windows/c/crypto_scrypt-sse.c create mode 100644 src/windows/c/mman.c create mode 100644 src/windows/c/scrypt_jni.c create mode 100644 src/windows/c/sha256.c create mode 100644 src/windows/include/config.h create mode 100644 src/windows/include/crypto_scrypt.h create mode 100644 src/windows/include/inttypes.h create mode 100644 src/windows/include/memlimit.h create mode 100644 src/windows/include/scrypt_jni.h create mode 100644 src/windows/include/scrypt_platform.h create mode 100644 src/windows/include/sha256.h create mode 100644 src/windows/include/stdint.h create mode 100644 src/windows/include/sys/mman.h create mode 100644 src/windows/include/sysendian.h create mode 100644 src/windows/include/unistd.h diff --git a/src/windows/README b/src/windows/README new file mode 100644 index 0000000..df17e7a --- /dev/null +++ b/src/windows/README @@ -0,0 +1,26 @@ +Windows Native Library for Java Implementation of Scrypt +======================================================== + +This directory (/src/windows) contains files needed to build a Windows +dynamic library to be loaded by JNI mechanism employed by the [Java +implementation of Scrypt](https://github.com/wg/scrypt). + +Most of the codes are taken from +[https://github.com/barrysteyn/scrypt-windows], so all credits should +go to Barry Steyn. + +To build the dynamic loading library for Windows, JDK (1.7 or higher) +and Microsoft Windows SDK (tested with SDK 7.1) should be installed, +and JAVA_HOME should be set to the installed JDK, the Windows SDK's +Bin/ directory should be in PATH (we are calling setenv.bat from the +build script.) After you have the environment setup, simply double +click on the build.bat should do the trick. After a successful +building, you will get libscrypt32.dll and libscrypt64.dll in your +(project root)/target directory. + +The scrypt-windows project contains 3 implementations of scrypt. In +this project, I picked the one with SSE optimization. If you want to +use the others, go to +[https://github.com/barrysteyn/scrypt-windows/tree/master/scrypt-1.1.6/lib/crypto] +and pick one from crypto_scrypt-{ref,nosse,sse}.c to replace +c/crypto_scrypt-sse.c. diff --git a/src/windows/build.bat b/src/windows/build.bat new file mode 100644 index 0000000..8223e47 --- /dev/null +++ b/src/windows/build.bat @@ -0,0 +1,18 @@ +set local enableextensions + +@echo Building libscrypt.dll for x86 +call setenv /Release /x86 +mkdir ..\..\target\native\win32 +cl /O2 /EHs /MD /Iinclude /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" /c /Fo..\..\target\native\win32\ /DHAVE_CONFIG_H c\*.c +link /DLL /nologo /MACHINE:x86 /OUT:..\..\target\native\win32\libscrypt.dll ..\..\target\native\win32\*.obj +copy /Y ..\..\target\native\win32\libscrypt.dll ..\..\target\libscrypt32.dll + +@echo Building libscrypt.dll for x64 +call setenv /Release /x64 +mkdir ..\..\target\native\win64 +cl /O2 /EHs /MD /Iinclude /I"%JAVA_HOME%\include" /I"%JAVA_HOME%\include\win32" /c /Fo..\..\target\native\win64\ /DHAVE_CONFIG_H c\*.c +link /DLL /nologo /MACHINE:x64 /OUT:..\..\target\native\win64\libscrypt.dll ..\..\target\native\win64\*.obj +copy /Y ..\..\target\native\win64\libscrypt.dll ..\..\target\libscrypt64.dll + +endlocal + diff --git a/src/windows/c/crypto_scrypt-sse.c b/src/windows/c/crypto_scrypt-sse.c new file mode 100644 index 0000000..bc35d0a --- /dev/null +++ b/src/windows/c/crypto_scrypt-sse.c @@ -0,0 +1,370 @@ +/*- + * Copyright 2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#include "scrypt_platform.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "sha256.h" +#include "sysendian.h" + +#include "crypto_scrypt.h" + +static void blkcpy(void *, void *, size_t); +static void blkxor(void *, void *, size_t); +static void salsa20_8(__m128i *); +static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t); +static uint64_t integerify(void *, size_t); +static void smix(uint8_t *, size_t, uint64_t, void *, void *); + +static void +blkcpy(void * dest, void * src, size_t len) +{ + __m128i * D = dest; + __m128i * S = src; + size_t L = len / 16; + size_t i; + + for (i = 0; i < L; i++) + D[i] = S[i]; +} + +static void +blkxor(void * dest, void * src, size_t len) +{ + __m128i * D = dest; + __m128i * S = src; + size_t L = len / 16; + size_t i; + + for (i = 0; i < L; i++) + D[i] = _mm_xor_si128(D[i], S[i]); +} + +/** + * salsa20_8(B): + * Apply the salsa20/8 core to the provided block. + */ +static void +#ifdef _MSC_VER +salsa20_8(__m128i *B) +#else +salsa20_8(__m128i B[4]) +#endif +{ + __m128i X0, X1, X2, X3; + __m128i T; + size_t i; + + X0 = B[0]; + X1 = B[1]; + X2 = B[2]; + X3 = B[3]; + + for (i = 0; i < 8; i += 2) { + /* Operate on "columns". */ + T = _mm_add_epi32(X0, X3); + X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7)); + X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25)); + T = _mm_add_epi32(X1, X0); + X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); + X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); + T = _mm_add_epi32(X2, X1); + X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13)); + X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19)); + T = _mm_add_epi32(X3, X2); + X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); + X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); + + /* Rearrange data. */ + X1 = _mm_shuffle_epi32(X1, 0x93); + X2 = _mm_shuffle_epi32(X2, 0x4E); + X3 = _mm_shuffle_epi32(X3, 0x39); + + /* Operate on "rows". */ + T = _mm_add_epi32(X0, X1); + X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7)); + X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25)); + T = _mm_add_epi32(X3, X0); + X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); + X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); + T = _mm_add_epi32(X2, X3); + X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13)); + X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19)); + T = _mm_add_epi32(X1, X2); + X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); + X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); + + /* Rearrange data. */ + X1 = _mm_shuffle_epi32(X1, 0x39); + X2 = _mm_shuffle_epi32(X2, 0x4E); + X3 = _mm_shuffle_epi32(X3, 0x93); + } + + B[0] = _mm_add_epi32(B[0], X0); + B[1] = _mm_add_epi32(B[1], X1); + B[2] = _mm_add_epi32(B[2], X2); + B[3] = _mm_add_epi32(B[3], X3); +} + +/** + * blockmix_salsa8(Bin, Bout, X, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r + * bytes in length; the output Bout must also be the same size. The + * temporary space X must be 64 bytes. + */ +static void +blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r) +{ + size_t i; + + /* 1: X <-- B_{2r - 1} */ + blkcpy(X, &Bin[8 * r - 4], 64); + + /* 2: for i = 0 to 2r - 1 do */ + for (i = 0; i < r; i++) { + /* 3: X <-- H(X \xor B_i) */ + blkxor(X, &Bin[i * 8], 64); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy(&Bout[i * 4], X, 64); + + /* 3: X <-- H(X \xor B_i) */ + blkxor(X, &Bin[i * 8 + 4], 64); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy(&Bout[(r + i) * 4], X, 64); + } +} + +/** + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + */ +static uint64_t +integerify(void * B, size_t r) +{ + uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64); + + return (((uint64_t)(X[13]) << 32) + X[0]); +} + +/** + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY) +{ + __m128i * X = XY; + __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r); + __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r); + uint32_t * X32 = (void *)X; + uint64_t i, j; + size_t k; + + /* 1: X <-- B */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + X32[k * 16 + i] = + le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); + } + } + + /* 2: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 3: V_i <-- X */ + blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(X, Y, Z, r); + + /* 3: V_i <-- X */ + blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r), + Y, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(Y, X, Z, r); + } + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r); + blockmix_salsa8(X, Y, Z, r); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(Y, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r); + blockmix_salsa8(Y, X, Z, r); + } + + /* 10: B' <-- X */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], + X32[k * 16 + i]); + } + } +} + +/** + * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int +crypto_scrypt(const uint8_t * passwd, size_t passwdlen, + const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, + uint8_t * buf, size_t buflen) +{ + void * B0, * V0, * XY0; + uint8_t * B; + uint32_t * V; + uint32_t * XY; + uint32_t i; + + /* Sanity-check parameters. */ +#if SIZE_MAX > UINT32_MAX + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + goto err0; + } +#endif + if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { + errno = EFBIG; + goto err0; + } + if (((N & (N - 1)) != 0) || (N == 0)) { + errno = EINVAL; + goto err0; + } + if ((r > SIZE_MAX / 128 / p) || +#if SIZE_MAX / 256 <= UINT32_MAX + (r > (SIZE_MAX - 64) / 256) || +#endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + goto err0; + } + + /* Allocate memory. */ +#ifdef HAVE_POSIX_MEMALIGN + if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) + goto err0; + B = (uint8_t *)(B0); + if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) + goto err1; + XY = (uint32_t *)(XY0); +#ifndef MAP_ANON + if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) + goto err2; + V = (uint32_t *)(V0); +#endif +#else + if ((B0 = malloc(128 * r * p + 63)) == NULL) + goto err0; + B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); + if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) + goto err1; + XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); +#ifndef MAP_ANON + if ((V0 = malloc(128 * r * N + 63)) == NULL) + goto err2; + V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); +#endif +#endif +#ifdef MAP_ANON + if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, +#ifdef MAP_NOCORE + MAP_ANON | MAP_PRIVATE | MAP_NOCORE, +#else + MAP_ANON | MAP_PRIVATE, +#endif + -1, 0)) == MAP_FAILED) + goto err2; + V = (uint32_t *)(V0); +#endif + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[i * 128 * r], r, N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); + + /* Free memory. */ +#ifdef MAP_ANON + if (munmap(V0, 128 * r * N)) + goto err2; +#else + free(V0); +#endif + free(XY0); + free(B0); + + /* Success! */ + return (0); + +err2: + free(XY0); +err1: + free(B0); +err0: + /* Failure! */ + return (-1); +} diff --git a/src/windows/c/mman.c b/src/windows/c/mman.c new file mode 100644 index 0000000..fc23381 --- /dev/null +++ b/src/windows/c/mman.c @@ -0,0 +1,180 @@ + +#include +#include +#include + +#include "sys/mman.h" + +#ifndef FILE_MAP_EXECUTE +#define FILE_MAP_EXECUTE 0x0020 +#endif /* FILE_MAP_EXECUTE */ + +static int __map_mman_error(const DWORD err, const int deferr) +{ + if (err == 0) + return 0; + //TODO: implement + return err; +} + +static DWORD __map_mmap_prot_page(const int prot) +{ + DWORD protect = 0; + + if (prot == PROT_NONE) + return protect; + + if ((prot & PROT_EXEC) != 0) + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + } + else + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_READWRITE : PAGE_READONLY; + } + + return protect; +} + +static DWORD __map_mmap_prot_file(const int prot) +{ + DWORD desiredAccess = 0; + + if (prot == PROT_NONE) + return desiredAccess; + + if ((prot & PROT_READ) != 0) + desiredAccess |= FILE_MAP_READ; + if ((prot & PROT_WRITE) != 0) + desiredAccess |= FILE_MAP_WRITE; + if ((prot & PROT_EXEC) != 0) + desiredAccess |= FILE_MAP_EXECUTE; + + return desiredAccess; +} + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) +{ + HANDLE fm, h; + + void * map = MAP_FAILED; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4293) +#endif + + const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); + const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); + const DWORD protect = __map_mmap_prot_page(prot); + const DWORD desiredAccess = __map_mmap_prot_file(prot); + + const off_t maxSize = off + (off_t)len; + + const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); + const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + errno = 0; + + if (len == 0 + /* Unsupported flag combinations */ + || (flags & MAP_FIXED) != 0 + /* Usupported protection combinations */ + || prot == PROT_EXEC) + { + errno = EINVAL; + return MAP_FAILED; + } + + h = ((flags & MAP_ANONYMOUS) == 0) ? + (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; + + if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return MAP_FAILED; + } + + fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); + + if (fm == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); + + CloseHandle(fm); + + if (map == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + return map; +} + +int munmap(void *addr, size_t len) +{ + if (UnmapViewOfFile(addr)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mprotect(void *addr, size_t len, int prot) +{ + DWORD newProtect = __map_mmap_prot_page(prot); + DWORD oldProtect = 0; + + if (VirtualProtect(addr, len, newProtect, &oldProtect)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int msync(void *addr, size_t len, int flags) +{ + if (FlushViewOfFile(addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mlock(const void *addr, size_t len) +{ + if (VirtualLock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int munlock(const void *addr, size_t len) +{ + if (VirtualUnlock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} diff --git a/src/windows/c/scrypt_jni.c b/src/windows/c/scrypt_jni.c new file mode 100644 index 0000000..ebcfaef --- /dev/null +++ b/src/windows/c/scrypt_jni.c @@ -0,0 +1,54 @@ +// Copyright (C) 2011 - Will Glozer. All rights reserved. + +#include +#include +#include + +#include +#include "crypto_scrypt.h" +#include "scrypt_jni.h" + +JNIEXPORT jbyteArray JNICALL Java_com_lambdaworks_crypto_SCrypt_scryptN +(JNIEnv *env, jclass cls, +jbyteArray passwd, jbyteArray salt, jint N, jint r, jint p, jint dkLen) +{ + jint Plen = (*env)->GetArrayLength(env, passwd); + jint Slen = (*env)->GetArrayLength(env, salt); + jbyte *P = (*env)->GetByteArrayElements(env, passwd, NULL); + jbyte *S = (*env)->GetByteArrayElements(env, salt, NULL); + uint8_t *buf = malloc(sizeof(uint8_t) * dkLen); + jbyteArray DK = NULL; + + if (P == NULL || S == NULL || buf == NULL) goto cleanup; + + if (crypto_scrypt((uint8_t *) P, Plen, (uint8_t *) S, Slen, N, r, p, buf, dkLen)) { + jclass e = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); + char *msg; + switch (errno) { + case EINVAL: + msg = "N must be a power of 2 greater than 1"; + break; + case EFBIG: + case ENOMEM: + msg = "Insufficient memory available"; + break; + default: + msg = "Memory allocation failed"; + } + (*env)->ThrowNew(env, e, msg); + goto cleanup; + } + + DK = (*env)->NewByteArray(env, dkLen); + if (DK == NULL) goto cleanup; + + (*env)->SetByteArrayRegion(env, DK, 0, dkLen, (jbyte *) buf); + + cleanup: + + if (P) (*env)->ReleaseByteArrayElements(env, passwd, P, JNI_ABORT); + if (S) (*env)->ReleaseByteArrayElements(env, salt, S, JNI_ABORT); + if (buf) free(buf); + + return DK; +} diff --git a/src/windows/c/sha256.c b/src/windows/c/sha256.c new file mode 100644 index 0000000..50185d8 --- /dev/null +++ b/src/windows/c/sha256.c @@ -0,0 +1,412 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "scrypt_platform.h" + +#include + +#include +#include + +#include "sysendian.h" + +#include "sha256.h" + +/* + * Encode a length len/4 vector of (uint32_t) into a length len vector of + * (unsigned char) in big-endian form. Assumes len is a multiple of 4. + */ +static void +be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + be32enc(dst + i * 4, src[i]); +} + +/* + * Decode a big-endian length len vector of (unsigned char) into a length + * len/4 vector of (uint32_t). Assumes len is a multiple of 4. + */ +static void +be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) + dst[i] = be32dec(src + i * 4); +} + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ + t0 = h + S1(e) + Ch(e, f, g) + k; \ + t1 = S0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i, k) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], \ + S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], \ + S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i] + k) + +/* + * SHA256 block compression function. The 256-bit state is transformed via + * the 512-bit input block to produce a new state. + */ +static void +SHA256_Transform(uint32_t * state, const unsigned char block[64]) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + be32dec_vect(W, block, 64); + for (i = 16; i < 64; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0, 0x428a2f98); + RNDr(S, W, 1, 0x71374491); + RNDr(S, W, 2, 0xb5c0fbcf); + RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); + RNDr(S, W, 5, 0x59f111f1); + RNDr(S, W, 6, 0x923f82a4); + RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); + RNDr(S, W, 9, 0x12835b01); + RNDr(S, W, 10, 0x243185be); + RNDr(S, W, 11, 0x550c7dc3); + RNDr(S, W, 12, 0x72be5d74); + RNDr(S, W, 13, 0x80deb1fe); + RNDr(S, W, 14, 0x9bdc06a7); + RNDr(S, W, 15, 0xc19bf174); + RNDr(S, W, 16, 0xe49b69c1); + RNDr(S, W, 17, 0xefbe4786); + RNDr(S, W, 18, 0x0fc19dc6); + RNDr(S, W, 19, 0x240ca1cc); + RNDr(S, W, 20, 0x2de92c6f); + RNDr(S, W, 21, 0x4a7484aa); + RNDr(S, W, 22, 0x5cb0a9dc); + RNDr(S, W, 23, 0x76f988da); + RNDr(S, W, 24, 0x983e5152); + RNDr(S, W, 25, 0xa831c66d); + RNDr(S, W, 26, 0xb00327c8); + RNDr(S, W, 27, 0xbf597fc7); + RNDr(S, W, 28, 0xc6e00bf3); + RNDr(S, W, 29, 0xd5a79147); + RNDr(S, W, 30, 0x06ca6351); + RNDr(S, W, 31, 0x14292967); + RNDr(S, W, 32, 0x27b70a85); + RNDr(S, W, 33, 0x2e1b2138); + RNDr(S, W, 34, 0x4d2c6dfc); + RNDr(S, W, 35, 0x53380d13); + RNDr(S, W, 36, 0x650a7354); + RNDr(S, W, 37, 0x766a0abb); + RNDr(S, W, 38, 0x81c2c92e); + RNDr(S, W, 39, 0x92722c85); + RNDr(S, W, 40, 0xa2bfe8a1); + RNDr(S, W, 41, 0xa81a664b); + RNDr(S, W, 42, 0xc24b8b70); + RNDr(S, W, 43, 0xc76c51a3); + RNDr(S, W, 44, 0xd192e819); + RNDr(S, W, 45, 0xd6990624); + RNDr(S, W, 46, 0xf40e3585); + RNDr(S, W, 47, 0x106aa070); + RNDr(S, W, 48, 0x19a4c116); + RNDr(S, W, 49, 0x1e376c08); + RNDr(S, W, 50, 0x2748774c); + RNDr(S, W, 51, 0x34b0bcb5); + RNDr(S, W, 52, 0x391c0cb3); + RNDr(S, W, 53, 0x4ed8aa4a); + RNDr(S, W, 54, 0x5b9cca4f); + RNDr(S, W, 55, 0x682e6ff3); + RNDr(S, W, 56, 0x748f82ee); + RNDr(S, W, 57, 0x78a5636f); + RNDr(S, W, 58, 0x84c87814); + RNDr(S, W, 59, 0x8cc70208); + RNDr(S, W, 60, 0x90befffa); + RNDr(S, W, 61, 0xa4506ceb); + RNDr(S, W, 62, 0xbef9a3f7); + RNDr(S, W, 63, 0xc67178f2); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; + + /* Clean the stack. */ + memset(W, 0, 256); + memset(S, 0, 32); + t0 = t1 = 0; +} + +static unsigned char PAD[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* Add padding and terminating bit-count. */ +static void +SHA256_Pad(SHA256_CTX * ctx) +{ + unsigned char len[8]; + uint32_t r, plen; + + /* + * Convert length to a vector of bytes -- we do this now rather + * than later because the length will change after we pad. + */ + be32enc_vect(len, ctx->count, 8); + + /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ + r = (ctx->count[1] >> 3) & 0x3f; + plen = (r < 56) ? (56 - r) : (120 - r); + scrypt_SHA256_Update(ctx, PAD, (size_t)plen); + + /* Add the terminating bit-count */ + scrypt_SHA256_Update(ctx, len, 8); +} + +/* SHA-256 initialization. Begins a SHA-256 operation. */ +void +SHA256_Init(SHA256_CTX * ctx) +{ + + /* Zero bits processed so far */ + ctx->count[0] = ctx->count[1] = 0; + + /* Magic initialization constants */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +/* Add bytes into the hash */ +void +scrypt_SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len) +{ + uint32_t bitlen[2]; + uint32_t r; + const unsigned char *src = in; + + /* Number of bytes left in the buffer from previous updates */ + r = (ctx->count[1] >> 3) & 0x3f; + + /* Convert the length into a number of bits */ + bitlen[1] = ((uint32_t)len) << 3; + bitlen[0] = (uint32_t)(len >> 29); + + /* Update number of bits */ + if ((ctx->count[1] += bitlen[1]) < bitlen[1]) + ctx->count[0]++; + ctx->count[0] += bitlen[0]; + + /* Handle the case where we don't need to perform any transforms */ + if (len < 64 - r) { + memcpy(&ctx->buf[r], src, len); + return; + } + + /* Finish the current block */ + memcpy(&ctx->buf[r], src, 64 - r); + SHA256_Transform(ctx->state, ctx->buf); + src += 64 - r; + len -= 64 - r; + + /* Perform complete blocks */ + while (len >= 64) { + SHA256_Transform(ctx->state, src); + src += 64; + len -= 64; + } + + /* Copy left over data into buffer */ + memcpy(ctx->buf, src, len); +} + +/* + * SHA-256 finalization. Pads the input data, exports the hash value, + * and clears the context state. + */ +void +scrypt_SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx) +{ + + /* Add padding */ + SHA256_Pad(ctx); + + /* Write the hash */ + be32enc_vect(digest, ctx->state, 32); + + /* Clear the context state */ + memset((void *)ctx, 0, sizeof(*ctx)); +} + +/* Initialize an HMAC-SHA256 operation with the given key. */ +void +HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + const unsigned char * K = _K; + size_t i; + + /* If Klen > 64, the key is really SHA256(K). */ + if (Klen > 64) { + SHA256_Init(&ctx->ictx); + scrypt_SHA256_Update(&ctx->ictx, K, Klen); + scrypt_SHA256_Final(khash, &ctx->ictx); + K = khash; + Klen = 32; + } + + /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ + SHA256_Init(&ctx->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + scrypt_SHA256_Update(&ctx->ictx, pad, 64); + + /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ + SHA256_Init(&ctx->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < Klen; i++) + pad[i] ^= K[i]; + scrypt_SHA256_Update(&ctx->octx, pad, 64); + + /* Clean the stack. */ + memset(khash, 0, 32); +} + +/* Add bytes to the HMAC-SHA256 operation. */ +void +HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len) +{ + + /* Feed data to the inner SHA256 operation. */ + scrypt_SHA256_Update(&ctx->ictx, in, len); +} + +/* Finish an HMAC-SHA256 operation. */ +void +HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx) +{ + unsigned char ihash[32]; + + /* Finish the inner SHA256 operation. */ + scrypt_SHA256_Final(ihash, &ctx->ictx); + + /* Feed the inner hash to the outer SHA256 operation. */ + scrypt_SHA256_Update(&ctx->octx, ihash, 32); + + /* Finish the outer SHA256 operation. */ + scrypt_SHA256_Final(digest, &ctx->octx); + + /* Clean the stack. */ + memset(ihash, 0, 32); +} + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, + size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) +{ + HMAC_SHA256_CTX PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + + /* Compute HMAC state after processing P and S. */ + HMAC_SHA256_Init(&PShctx, passwd, passwdlen); + HMAC_SHA256_Update(&PShctx, salt, saltlen); + + /* Iterate through the blocks. */ + for (i = 0; i * 32 < dkLen; i++) { + /* Generate INT(i + 1). */ + be32enc(ivec, (uint32_t)(i + 1)); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); + HMAC_SHA256_Update(&hctx, ivec, 4); + HMAC_SHA256_Final(U, &hctx); + + /* T_i = U_1 ... */ + memcpy(T, U, 32); + + for (j = 2; j <= c; j++) { + /* Compute U_j. */ + HMAC_SHA256_Init(&hctx, passwd, passwdlen); + HMAC_SHA256_Update(&hctx, U, 32); + HMAC_SHA256_Final(U, &hctx); + + /* ... xor U_j ... */ + for (k = 0; k < 32; k++) + T[k] ^= U[k]; + } + + /* Copy as many bytes as necessary into buf. */ + clen = dkLen - i * 32; + if (clen > 32) + clen = 32; + memcpy(&buf[i * 32], T, clen); + } + + /* Clean PShctx, since we never called _Final on it. */ + memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); +} diff --git a/src/windows/include/config.h b/src/windows/include/config.h new file mode 100644 index 0000000..9ffc851 --- /dev/null +++ b/src/windows/include/config.h @@ -0,0 +1,99 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `clock_gettime' function. */ +/* #undef HAVE_CLOCK_GETTIME */ + +/* Define to 1 if you have the declaration of `be64enc', and to 0 if you + don't. */ +#define HAVE_DECL_BE64ENC 0 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_ERR_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `rt' library (-lrt). */ +/* #undef HAVE_LIBRT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `posix_memalign' function. */ +/* #undef HAVE_POSIX_MEMALIGN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if the system has the type `struct sysinfo'. */ +/* #undef HAVE_STRUCT_SYSINFO */ + +/* Define to 1 if `mem_unit' is member of `struct sysinfo'. */ +/* #undef HAVE_STRUCT_SYSINFO_MEM_UNIT */ + +/* Define to 1 if `totalram' is member of `struct sysinfo'. */ +/* #undef HAVE_STRUCT_SYSINFO_TOTALRAM */ + +/* Define to 1 if the OS has a hw.usermem sysctl */ +/* #undef HAVE_SYSCTL_HW_USERMEM */ + +/* Define to 1 if you have the `sysinfo' function. */ +/* #undef HAVE_SYSINFO */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_ENDIAN_H */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSINFO_H */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_SYS_TYPES_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "scrypt" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "scrypt" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "scrypt 1.1.6" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "scrypt" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.1.6" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "1.1.6" + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ diff --git a/src/windows/include/crypto_scrypt.h b/src/windows/include/crypto_scrypt.h new file mode 100644 index 0000000..f72e1f4 --- /dev/null +++ b/src/windows/include/crypto_scrypt.h @@ -0,0 +1,46 @@ +/*- + * Copyright 2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef _CRYPTO_SCRYPT_H_ +#define _CRYPTO_SCRYPT_H_ + +#include + +/** + * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, + uint32_t, uint32_t, uint8_t *, size_t); + +#endif /* !_CRYPTO_SCRYPT_H_ */ diff --git a/src/windows/include/inttypes.h b/src/windows/include/inttypes.h new file mode 100644 index 0000000..4b3828a --- /dev/null +++ b/src/windows/include/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/src/windows/include/memlimit.h b/src/windows/include/memlimit.h new file mode 100644 index 0000000..d3b4891 --- /dev/null +++ b/src/windows/include/memlimit.h @@ -0,0 +1,42 @@ +/*- + * Copyright 2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef _MEMLIMIT_H_ +#define _MEMLIMIT_H_ + +#include + +/** + * memtouse(maxmem, maxmemfrac, memlimit): + * Examine the system and return via memlimit the amount of RAM which should + * be used -- the specified fraction of the available RAM, but no more than + * maxmem, and no less than 1MiB. + */ +int memtouse(size_t, double, size_t *); + +#endif /* !_MEMLIMIT_H_ */ diff --git a/src/windows/include/scrypt_jni.h b/src/windows/include/scrypt_jni.h new file mode 100644 index 0000000..c73d24f --- /dev/null +++ b/src/windows/include/scrypt_jni.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_lambdaworks_crypto_SCrypt */ + +#ifndef _Included_com_lambdaworks_crypto_SCrypt +#define _Included_com_lambdaworks_crypto_SCrypt +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_lambdaworks_crypto_SCrypt + * Method: scryptN + * Signature: ([B[BIIII)[B + */ +JNIEXPORT jbyteArray JNICALL Java_com_lambdaworks_crypto_SCrypt_scryptN + (JNIEnv *, jclass, jbyteArray, jbyteArray, jint, jint, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/windows/include/scrypt_platform.h b/src/windows/include/scrypt_platform.h new file mode 100644 index 0000000..5cec236 --- /dev/null +++ b/src/windows/include/scrypt_platform.h @@ -0,0 +1,12 @@ +#ifndef _SCRYPT_PLATFORM_H_ +#define _SCRYPT_PLATFORM_H_ + +#if defined(CONFIG_H_FILE) +#include CONFIG_H_FILE +#elif defined(HAVE_CONFIG_H) +#include "config.h" +#else +#error Need either CONFIG_H_FILE or HAVE_CONFIG_H defined. +#endif + +#endif /* !_SCRYPT_PLATFORM_H_ */ diff --git a/src/windows/include/sha256.h b/src/windows/include/sha256.h new file mode 100644 index 0000000..5afe3da --- /dev/null +++ b/src/windows/include/sha256.h @@ -0,0 +1,62 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $ + */ + +#ifndef _SHA256_H_ +#define _SHA256_H_ + +#include + +#include + +typedef struct SHA256Context { + uint32_t state[8]; + uint32_t count[2]; + unsigned char buf[64]; +} SHA256_CTX; + +typedef struct HMAC_SHA256Context { + SHA256_CTX ictx; + SHA256_CTX octx; +} HMAC_SHA256_CTX; + +void SHA256_Init(SHA256_CTX *); +void scrypt_SHA256_Update(SHA256_CTX *, const void *, size_t); +void scrypt_SHA256_Final(unsigned char [32], SHA256_CTX *); +void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); +void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); +void HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *); + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#endif /* !_SHA256_H_ */ diff --git a/src/windows/include/stdint.h b/src/windows/include/stdint.h new file mode 100644 index 0000000..d02608a --- /dev/null +++ b/src/windows/include/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/src/windows/include/sys/mman.h b/src/windows/include/sys/mman.h new file mode 100644 index 0000000..5c22df6 --- /dev/null +++ b/src/windows/include/sys/mman.h @@ -0,0 +1,57 @@ +/* + * sys/mman.h + * mman-win32 + */ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +/* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#else +#include "inttypes.h" +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +/* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); +int munmap(void *addr, size_t len); +int mprotect(void *addr, size_t len, int prot); +int msync(void *addr, size_t len, int flags); +int mlock(const void *addr, size_t len); +int munlock(const void *addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#endif /* _SYS_MMAN_H_ */ diff --git a/src/windows/include/sysendian.h b/src/windows/include/sysendian.h new file mode 100644 index 0000000..3cf3b6c --- /dev/null +++ b/src/windows/include/sysendian.h @@ -0,0 +1,146 @@ +/*- + * Copyright 2007-2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef _SYSENDIAN_H_ +#define _SYSENDIAN_H_ + +#include "scrypt_platform.h" + +/* If we don't have be64enc, the we have isn't usable. */ +#if !HAVE_DECL_BE64ENC +#undef HAVE_SYS_ENDIAN_H +#endif + +#ifdef _MSC_VER +#define INLINE __inline +#else +#define INLINE inline +#endif + +#ifdef HAVE_SYS_ENDIAN_H + +#include + +#else + +#include + +static INLINE uint32_t +be32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); +} + +static INLINE void +be32enc(void *pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +static INLINE uint64_t +be64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + + ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + + ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + + ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); +} + +static INLINE void +be64enc(void *pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[7] = x & 0xff; + p[6] = (x >> 8) & 0xff; + p[5] = (x >> 16) & 0xff; + p[4] = (x >> 24) & 0xff; + p[3] = (x >> 32) & 0xff; + p[2] = (x >> 40) & 0xff; + p[1] = (x >> 48) & 0xff; + p[0] = (x >> 56) & 0xff; +} + +static INLINE uint32_t +le32dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); +} + +static INLINE void +le32enc(void *pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + +static INLINE uint64_t +le64dec(const void *pp) +{ + const uint8_t *p = (uint8_t const *)pp; + + return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + + ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + + ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + + ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); +} + +static INLINE void +le64enc(void *pp, uint64_t x) +{ + uint8_t * p = (uint8_t *)pp; + + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; + p[4] = (x >> 32) & 0xff; + p[5] = (x >> 40) & 0xff; + p[6] = (x >> 48) & 0xff; + p[7] = (x >> 56) & 0xff; +} +#endif /* !HAVE_SYS_ENDIAN_H */ + +#endif /* !_SYSENDIAN_H_ */ diff --git a/src/windows/include/unistd.h b/src/windows/include/unistd.h new file mode 100644 index 0000000..85af152 --- /dev/null +++ b/src/windows/include/unistd.h @@ -0,0 +1,48 @@ +/* + * Copied from StackOverflow: + * http://stackoverflow.com/a/826027 + */ + +#ifndef _UNISTD_H +#define _UNISTD_H 1 + +/* This file intended to serve as a drop-in replacement for + * unistd.h on Windows + * Please add functionality as neeeded + */ + +#include +#include +#include /* getopt at: https://gist.github.com/ashelly/7776712*/ +#include /* for getpid() and the exec..() family */ + +#define srandom srand +#define random rand + +/* Values for the second argument to access. + These may be OR'd together. */ +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +//#define X_OK 1 /* execute permission - unsupported in windows*/ +#define F_OK 0 /* Test for existence. */ + +#define access _access +#define ftruncate _chsize +#define unlink _unlink + +#define ssize_t int + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 +/* should be in some equivalent to */ +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#endif /* unistd.h */ From b19dc3cef2921a5fb50537b19e080c01e1e10206 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Fri, 19 Dec 2014 17:25:24 +0900 Subject: [PATCH 02/13] Modifications to JarLibraryLoader and Platform to allow Windows native library being loaded. Signed-off-by: Haochen Xie --- .../java/com/lambdaworks/jni/JarLibraryLoader.java | 13 ++++++++++--- src/main/java/com/lambdaworks/jni/Platform.java | 3 ++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java b/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java index fd9d3ab..49ed47f 100644 --- a/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java +++ b/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java @@ -62,7 +62,11 @@ public boolean load(String name, boolean verify) { JarEntry entry = jar.getJarEntry(path); if (entry == null) continue; - File lib = extract(name, jar.getInputStream(entry)); + String ext = path.contains(".") + ? path.substring(path.lastIndexOf(".")) + : "lib"; + + File lib = extract(name, ext, jar.getInputStream(entry)); System.load(lib.getAbsolutePath()); lib.delete(); @@ -89,11 +93,11 @@ public boolean load(String name, boolean verify) { * * @throws IOException when an IO error occurs. */ - private static File extract(String name, InputStream is) throws IOException { + private static File extract(String name, String ext, InputStream is) throws IOException { byte[] buf = new byte[4096]; int len; - File lib = File.createTempFile(name, "lib"); + File lib = File.createTempFile(name, ext); FileOutputStream os = new FileOutputStream(lib); try { @@ -138,6 +142,9 @@ private List libCandidates(Platform platform, String name) { case freebsd: candidates.add(sb + ".so"); break; + case windows: + candidates.add(sb + ".dll"); + break; } return candidates; diff --git a/src/main/java/com/lambdaworks/jni/Platform.java b/src/main/java/com/lambdaworks/jni/Platform.java index 953d593..bcbe553 100644 --- a/src/main/java/com/lambdaworks/jni/Platform.java +++ b/src/main/java/com/lambdaworks/jni/Platform.java @@ -29,7 +29,8 @@ public enum Arch { public enum OS { darwin ("darwin|mac os x"), freebsd("freebsd"), - linux ("linux"); + linux ("linux"), + windows ("windows .*"); Pattern pattern; From 2735516fec8e18abf6d6e62c99679a22e9b49586 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Fri, 19 Dec 2014 17:26:56 +0900 Subject: [PATCH 03/13] Adding prebuilt Windows native libraries (x86 and x64). Signed-off-by: Haochen Xie --- .../resources/lib/x86/windows/libscrypt.dll | Bin 0 -> 17920 bytes .../resources/lib/x86_64/windows/libscrypt.dll | Bin 0 -> 21504 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/lib/x86/windows/libscrypt.dll create mode 100644 src/main/resources/lib/x86_64/windows/libscrypt.dll diff --git a/src/main/resources/lib/x86/windows/libscrypt.dll b/src/main/resources/lib/x86/windows/libscrypt.dll new file mode 100644 index 0000000000000000000000000000000000000000..e4fd78b86b4a36589555f6f73775c59e75d093ba GIT binary patch literal 17920 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/lib/x86_64/windows/libscrypt.dll b/src/main/resources/lib/x86_64/windows/libscrypt.dll new file mode 100644 index 0000000000000000000000000000000000000000..653210ca57a437db542477e72f68df7cda51cda1 GIT binary patch literal 21504 zcmeHv3v^V~x&KKf6NWsP02v4fGBSh2hGJxBB_cHk&cGRS1|kWFMGY||5Dm$gOcYyN zz{%8^ZswLMZE3|`?bTk}Yj3%&542WhlE5T@5Z*zo#%BkD5)=s!_56R|K4&Hg_*|E@ z{%hUUS?grKzWwcQfBUz;{q24BiTnHO1cM+5DR@*>5H=&EUm^ed<$t13u*Yj|%UcRry!P9T)`R{09b;WYx z6_>o&DF{n{ViX+PA1;mO^$6pw>B(tYCr42wl8EJ-s@?p+D7E$BPAFQGY%c)R^q8 zTMLvNDg=S!Vl@hh-+Vm%euaWCvtROG(MzBK z*>_y7GS^*YzRGLQN969T&4dc`RrlMiNZx0a%vVYFtSZS|C*~ubVMp$JRie4Blk#3c z>QEJa=5bA28d+_l!uBfjXFE_9sWR8^8HGPRgR0CYy70V-+?^o#3?y3dNGcwTq7FQJ zkh>j~cUGA_?>rnQ8BQdbDDK2_7`fo>IZ^;R(0caHjnfSwx?vFPL>v8SkBb6s7l_iw z=qp9xZCxx%UuPicMWR3o^n6I4C}#hgpQ$P&K85ET@;_^-GOxNj%bd#4Hw{BvTj_R|$wJrVfhAAV+o= z#S3W=6;lt-&v*OV%}tlVO31-m?fG)hYo8_u(H5k^zHpYTlJZYT$)H{C^ZS3qf9F3KiNp;#exF=aSKWm3ed3?47cr|j!4VoKR@rq_X~>}xJ``Hro2 z@m4wCJ0DB%ow-TpYhHCDDXWgNo!Mdbe~6 zylIjn?+#MfhjJ*Tz{$2M(EBtcWWQPtuC;IAoSHaCw_i0kjm8)$?2vh!;AU+vlYU*% zmU9r+6?rp-rdwjZxk4qWE?;w&?=7>-u*dwI^l-BIIptvk8Z@*~GD(l6JPgwFNPyDN z23j$AW6zhI#@g~lEX&o+`tnPv=pP2pm)Il}uo*p$nkiths zQ;ovb+Mj|B6t>>}7!TvB+G}olncz$l0^07Cdx6sTQ(So`<)CEGcd=GCJ1ggHmGh#M zk?RW0#CYFo&z1MYWHn5AR=59s?-&=0y4WkwH=vf18V4{3+52v`%f(C=$#qCFD zP9p9KeP4BlY9@tc^h9PKxkLBc!}6XFWOW-we+EaeF)sYjbRvA$0I@w}=!nG;-{f-BNxRSaRp*5Wq*c^guL z6hjl&J+Ylc`pj#U(dh*K`uJ<}UCV!L!@h-e67ZT3&&W1Hx?f&rPPU>3>> zW?`|ymf9E5d|V>48vAm$|A@KiUFb!(H_C9@*Oa*#|8lrjUm`4npg`FT)*nh3KQ(Oyh=2868btLZ)gJ0oa) z;p{IWcB$Lr0+{`74*9L_>D}fBt{}DeT0P=zWs4IQNC^Tk3UCVZQ) z%J^8G-f4dD-;p7)_ayV5-xMS73=%_%{RY*te;Uo-9-48BWPjM)^bp9{E+w@51{eXC z@7=I3vP!l5iIbfnvL&2sHpno$Ziu`$$k8tQy7-)x**3>%qA8X_bH_`e*#>l@MP?mX z(Q>1h(V660Z$y^FdFv(m}Kwe}8#B5S1@`AV<`hJx6E z2WPT8=C)J)rS`&tXSgo!DIm-OxcA$O`FhB9x!F#IL6`$B!z&5|vc@)_RaMc@E33O3 zyNG-dkptb@Kq*YIFTYR*E&x%Oboq1LY->W6*ftx9U26A`k)gryhZ{$@*lyM0y_VMG zU8?0SL>%GnYk2PM@!SQ7bdOdoGZ03F4D_ozL$zGZQ?wKEwW;!&Rzj3mCf+XICf-_h z`)z$_+_{rH2cWQq@QA)?FvNr~h=?hZI1P>SPp_Z3Zty~9qoB)@D0%gu%O zV|Mm*r&A6&_+}>zHB{$60&2B;^y!wQEyzaxS&(=QzTL@SfWRt2=__Z4rjA!FYrade z(+{@T-1Hnf;F-<~yGPY*FN0Yhwmf>rpK-Ds-pF=$rrj#%uyY;}F$y9cM$^ zobJ1wj&=!{+AFg*QgSXb1&R8nT8>O5Rrdgljl)#SithlmovP(igu$HdX->A&=?Jq! zs7P=D{VbHoWb;6EHO2i$yiu98bZ4oSDAG}Z^i0B#<55hj5v*Me;lT?W_*(Ndz3Uc$ z{5{q38HDhMy@MQK?w-&fps6n8QZpVd3~{m&+W`&?AFn0)Q# zx~S_G842IRWp+?zJCuquqWX}Qm5y%0jw3hN#Fs2l{dt%ZYbBhX#p1aYPuSbgO~6xT zG1YPqk~+}g9zJ3jglQT&GV6SnzebUYwcG(x5Yn2c1ToEM9!$eD2qVMA4$-tkYBLqH ztw`mPL9}8Sj_t#;0O|aY(%`L-LzXmXMJ>)(SeI&focf+X7fP#;>2 z9Wqy`=Ddh65b$X>vmMZ`fKpmp$D$1~0#Bh(BS8m2qOQ{@PJ0IfRjOsZgBk>&Hfm0V zueG?}OvU~{o1b2qpYUrJB-V*g4ZMgo#|ugK%;=nnzyUkw%vWHb@u$>2RSDf{pQ7Y# zSMv5Md9TVyeOC$1OqJP5Iq%gM$qVJn&j9~ZG(T5(9)IL>So5;DKSx=|6S4Obu@kd` zO42c+{UDLolZc&6#6ALDGN=16k#{N)`#2Hn1)ZUX_?=GVok_&b@|dh{pGj0^e+exK z=u&>@2O0hRXI7FTu~{ZoG)-b984_z}k;u_BF%mIH!kLnzjWtV-cD6kd84_t5M9E0Z z;AoQ!?X2i}$xvjM*kKlt4C%a53$GL`DwG_ZA`457!y=ppy(%(zU6JTfuw61N&Xo+W zifoUF+L30h@?y!+A+l!Cv8S)1)~Lu@40{YElSD&@leLJEZipGCO2HDDm1Iedu+!1P zwnIeTV&oVEb)XeAH!I(1XqJMr6xr8;t=Vp~pZsfy-JT_}**R=BbTFCy*n|m{&1Ppv zG_io59E4-o>};|u6t}b4W8_G;6;YtSMItMtU=^~8Y@Y<{mqklimMe118rhy62@i5b zj-qHg`r~K=y=dDJX-gH^Ne89}T0pJ=(32xEYkIF?yJ-8^$=(dDH*L83r!z(NipaJa zUX8S8M#5=SeQTsGnZk%In%)yiNn<+m%5*<6x2itBICH9UT zjt<1yQqh%A$}mG4#Ge*gpS1gY_*s$dgu|dQc80QtI@+8hdn+1{(svJ!;(BI#4t zw&Q@9e%N+Uv>ibOw1b+w9nlui+F`qRE6^h~Lh3{tz^7uDpmO4T-N~URZxPv9ksWXv zx)Pkz&pQs<&WpDFI^P4tHzL|v($8q}@1#+JdRleyp-5sK1#20scS9$`o_OGfha|So zX@Dj*iD`5I4`=#5$#w`(WBb9g*|7$S@pbh4kiY>P_iF->#;2SWte36sQ^;7H+C z@GmC*uRt+VHvDl=C+nqY-^X4||4@TCW&waq9TsiP={>}_Khmj1&eXOKJWC-GaIRr| ze9~gyFeiJ9?du10@B+wfhX8MmdCnX16XJEa?*`lQZ zz%}W-qfaHf9ES+rHo%AQPIAYwu4x3;rw{C0(>iy;_^rg9W4z@@84G~%eh3F90CH_i zZ7`NVI6D-_xMMFcF4_)2pAekp&p@n0@nFA%*mI0~Z+p3(01lX68jLTEWBjxKd42U4 zVH_y5?dLf8niz-7%L(BuN*Mpo)Yl#X#yJWTFn1gT!U@d)IY<0K0tBEQ2Rds9(7zDl zHKY=baqr1TB9|WH9^%h29;trh9bo+P0X_iTm&#(j9u;9QTuuH}pb|@1FCi@Ne z!XEK8j!ZhulCNRU3FGe735eHCI{NL4A)bC%geA8ffh8xi@%7EPyD5(FKQ?)91i}ZJ zaL&wjo=exYs4HJ^!ZfZP1WS*zE;ub?Y5Y!`fi`7`=7?Q<}rVzQT?J-tP5rbg$TU%~Kbm zn|u@pR<-vq<;iRLCKlYiAp!2TiH1!8_dxTFp#evja2iR?M-jObq1$aTKjfx34$(-$ z%9Ed>S^0>;y^)x6`yE|%%a#j$6dmat9=&yn8XX4nNcEx3rFDbS+lf>L`f3jkdyC1OOq{KaN2Yd$j;J_|{9BBR= zkn0eKYB;(P0^2VUbB^udnbS%x#5S352Us5FPRKXMc9^(xY?n5qRbJqG!)R;BvmN2{ z<;#3-edBY07K2t;dB@&3w*QuP=RFsBCjT33x5cqNxxIPKCC2tn(g(-3e^UKJ{eaEK zgfEHv$(lR%zzrvO1Gs>C-0^nohvN-}4#0Vz@9pj&_8i-f$F}_LB5cF;1~hCRlVeXt z`)gwxbB6CO#}`$NCcE9w?}pXp)*5!32JtKXZG*d$j4f8meJ~J?eIzl*wucopU+9!@ zRBM>lEciEayxp%6bB^u*xTz+3sj=Nf+&Q*K#U4U*z`l|L8ww$e)20E~);tt#S7|#4 zzaCrnU9=y$aBJy)Cys4<>aXF@T)Lg5I~K>b|2soYeIB;Cy@u)jn%=hKpuv3{W*!3% zkDYx;D&g?rw|6bhg#qW9}#(C)TKlCsW`$- zHP>F=58fQxI0mzwhQI)>Z7VPt7HgPJ4!FlhCR-7K#wE*uNh+soH)(6Xk*E7PF^=1&*0Q09p@<90Cq_`ceh2Lb>seopbs5N#bON&M;`>C)&ulhI6ku;QHB*b|{0UxY8-)XD3)3 zOf+}M>z=oL<6}~Rpoat|Ibo28Q5(FnG?hF!} zqx_?~$;+MW1nB#lax&iC15wVaMyb8eJ3(>U-X+%k40#qc!D0Tv13&Y^`*!vn=>c)N z`PQc?d~jQ{e#k-kMEXGDY6e~|H3z|V*1CT?G%|P_9=E} zV)`c{Bmb3JA*b24FF3}or^&isd{krmjI4z=0)TyvK9$n4SGF~QS3idZbA@~Mw!Q3i zVo3)YqODa-e@((W-<0^t*mnJ7j68C}47U~9*_eBbZox*IlA~+;ouhED5WK)oVi|VL z&ce!)hqP7m3MFb)N`Hf^FIA#5KWx9r4g)w=a&a7cbog9%PJMYD;NE{b=z#aZ5sBk4 zsXX30z!hsyMrk#Sdr4l+>%`=y5ys{DSN|U`R8t_`fz~A-7d~e<$ zM~;mR&bEuwBMk<1wl!&?bxR?=-eLRl&dMR>np|aiv|&)}1_;t!sjw)$i_4GYBPoX# z=Hf+EZ2h}BUhDa<2T0qji85a%& z-`Q#P#?31c%ZuR6VeCqhdxylru}5)d4;S9>ies~h_hv`zr<8>k9l11ApW+ody|Ycc zBB${%@lk+~{QlRu7~OY~*f=S$*g)nC0?$e&WJJ1iq`+k)*Q_KqFC|bkh@?bmYN9u@ zjDeyQHqR6&O4rNM`pO0eicD-?Mxe;7mksGF%M27{uz6X5qTzbku)eaPfubxnFFQ~) zQZF0PS7r$mWwUuXfuhUwveA8IqXI=aY~C2?wP+ld^Kzoeg5n)}1GB~kipEHxnagoe ziUyM|(pk%nCPP7q%XEm4eysi9LgT&UVZ4{5H@+Cn$W2i(d+l=LBT+Hu zzYhDxMa40rUg=sKJAjK=a>(6_SJ<&zFn~&^vNzOVl{bG^|H;8JYjhB2K1X9dM`J#R zGslb4=kaX8gPUZ|-FOb+c>~Ws@tlax(HftlH9kjcd=77%rhxyn_bNH$eBO=ggn8k9 z?;kPSEYHhoGhSn+nDUe4=?CkNi+?X9ZG;v)4_)G}U~D8w|KhFsPY(WjfXaglo>y2i zf-MT}83q?b6}A__ZiT&y;1Jz43@&&>VdoG)$ORB`xz@oNuDv-PuDv;4uDv-cx%TGV z&$aj9YP7%=_+S%aq(kb1NPST9y87;aLH@CjzlG$_Ao*XfKd!JJ;rdr2n!XKEkU(z8 z2Ia8@&$9>Df*)(+_vtYcgFKDNID>9{H>9c$Qr|@Oao$PS^pEe6<>2}P?KVJD!3LBl z!LnbGPbqmH;0^J2o_CQ&%X6`h<;VxHXxqr5DP++ksxuD=-xpgCdd;Bi zYV4LnKO;u`rT)IyU}DYOBgsDe!$k3o{Js$`)(}xgcNM+`)Bzp+P2V3=08}*q4w=j=hi8 zgFkBWsa7mJ&eeR?$vZFm)RcQNusT|Cy+q0kbl2hn6p?UT%PShh1a;9gSZW8zCz3{dwy z;Eb}+FGyx6H+CCcKS}6y%Rg{YjZ?~@jWdWwWT)cl&HEhn7WV1ahr00+DR|U8iB$2xq#*KurQqb8XO%FFDtIZsKqG3lowLw|uha)1E7Z(pPx?Y?RPe-%WpdqBqkJRO3uBe+*X z>S^76HT`;budxpr2YXlw;&5-y=l9Fg79|oU3={`P!83Nmbtc^2>BtD80 zFOoAMVFY#hBn|P4f->X)WZf)XKB!0~}bAf_2p%?L~ZSWKu)VCg}e^ha^r z^7B)FDGsCMC!r{A>b{cz)uS6e0@O@23qT>u-4=WDFnzgkiqOQ_>L&Nf&q0&Bjm)YS z72;sR`sjuy$Ib0=YOtRv-FXVP&mBh+_qS)7pKBURmdE95Ntv17G*&{KXOb=`!x_&Y z%~1wj5#|)6SIU@!(B(UCz5g#Rb(i-Fg>h@F+h*NT>vsF-T3A@Jz|%y2MU}Q_vdsS8 z0~XMQi~zcDg)#=Y^P+G=t#0$2Z82(ywgCC?b8}@CA0M3Mi>xd1Popwj1v_n(G(YeU ztQ-oy6`>_m!NqG@S{0@*wM<)jW#rRREVIyZVhp$8_cU|Yw30VawwUkr_&&($WI5Q( zDXd-ey?sVJEu`Q(An$OI6`I@?#VNg=ieZmj(Wcn;xGGw1WZ79Vo0Y|6lWZt5ofZvd zZ-)6f(ctUqkvAxYHpQ{s#c-#()w=j7?n(;$+afm;u?<7Po>&mumdy}|HaPu1iGdg2 z&;OgAd3KZ_G!B&`k*uoTh^jUwf7BvJ+Ov*2VK;WF6Pob_p*rCi`rMNCa@H5f9I2K^ zkU`gN=>n@t9#hb`avTq;DZq_jV`x@Vw@vohgxF}lOl1}!h@IwUIMab3b_{>`omeYv z!0@e(99(3=H#xYWyfO#hfq(>h|k<2n5N0Dk7j=H#u%CEcrl5@{o%?r-KOuN}9bUB{IWZ(NH*YxA{ z-K)7#FXbK=40yg2)tK-+trA~ zUIh%%;7~VfeUZpkM#5#FhG@fDNT&~&`?!>?eS(6Cq50~7Rv)%J99v>3 z9ZO(?%FZe5&A$AyD`mi1ldP-p%{Ae8hz)I8?S|b|4Zr& zgfgietP>|1R{F@|DNw;mYF`fJy?`WIExddzG2)TGAmKtI=@8a~g!w*YRG zB@)N68&KHTtI!y}qVcB33q*CFUxhHLq4C;8gIhq{+j&{LZ3jDy4TIH-<0#_?erBMc{u=E=mr&*{)S~5wzyKtapk^#!_C<6* z9b1MaWS1AkMCgICAq7McuyKt_b~@?-$jHK@D4$}56w8%E#uPB6xRvg(0s!=x3a+*; zakR%yK*H|v^f5+&>IaP-L>tnRzA(CGyp6J$@j1@LIMG5W?VdaebCDZ0ewHl=gHwcX z)OZFl4Ryx9BTCIKN97mvIKEhT4&n!m%faRaJ`d(X1V_7S`8{iRV_cII@&iKWFteFM`7fSCWBJ5$NZcs^AlvMmRh2PIM6>n zl1Qif=az?%*Zt!c03spwIwsIM*qdFPx-db_GN0i&ll7cJUNe_c_%MR&8DldorY&=w zG)B`@i-}Vk*Ptrp6snffkO~T0h8(TIax^FdT7bi1{5_rm)St@O;$VLiO#JZa;S28X z$@*w!|@lY*Ih)S%}=uNT2^&@l~&kFR+8|Tzo;pOhLCj_6ls(I>Kq2dbmLkoAj_s4{y}N@9N=rJshovX?l20m*WXN{EHqo>tRd} z<6ZrYo_T=jSeMmTmV1%#E-$aOUIRL}UbP1QMWftXT~}+Z0+Y(6@rLdM)2nOB zYnNT^s;Q}5R$e34FKb+ZMx84wDm_#oPN{{SC7PUB`f8UmJSk(Q&R_)fz~=)5N^N|#{d4fVq}^y z^3-4<>zy9IL9+` z$%tZ0e$v7WVWBro7_~H07*(1fjGCG*jGAxhLalJpXoE0%YKo9D6KnG2X~N}GhYOcK zG`c6JYeYwOc$jDClC0uUQ!)j+_Zq>zG+(e!y;`s*wqRg5W7Z+L$aDTT=(*C1sn0Y#cskmm-`xNXVX&s$M@AH2DvXh!tF14MkFjm!9!qENJ zxT2hFmmu^el~vZ)*VYL_Npjh;N^eVZ zT`h0?baENbebi8<=gb#o)zmdq%9;{xF}TY;3#%*domT}JDg{&WoJy}!-r#lC*VjSD zpfHOs4pazAPj&4wQ4rouSx~!TK)nwHCs#mm9hXViAxM>^ka#+rQc_b{=@E9NltO*g zwODV8>+32i8yW;*TN2uw)mUGT1tgyN7Fy60wKTD&=t>g)no?5f{lem8gR4Q(^;cY9 z*#M@(l_~SRH4Cfjy^ZBH3u^DJuEk0=j`9@fx6w1Zv9^L1EoZH_9%#s+l3C>*Z)1Js ztU9O||Lf{4L8@+`RkUqZluPCprK&?g^ z8R0ji&C=?MyLg5m?C951jgbqIMEm9H{YUm{s#|hjgST=;Y4wUqv4MtwVnUH~{#>Wx zn4)3yLi-Z`-(-J*{o!^P1Qb4n^wW4Y;pxJEaR?(6gqrF*8Y=4V^LRP48?mmJRn)C0 zt0`Y`$I|k9>+0`n03cCZS5`8M!ZM8-Hudv&>hGtKzcv(pmAN;Ew0#vxn=;vEQIfZt?CyubfMepCR@t;nbFQ9KIbk0Epw z2tpI$#R!*Phj{|u(u45F@Q2nTzrSxpJ`(=9jnIaC3ZKNY8S$qOro-pTKwa{^uEIk; zY9YchJSN29uM6Ap5Y0}66X45aBc6+}96rr7#OZ$rK90wW_!9^}D1vN=e}eF7_%CY_ zr?3SN@oz==2_BM}!m03AC>|!i1@m+>;#P#S@DRO(uoq7k;^b2;z>|+S`BUT@QJlhG i=yCFan)UcsLJR&5ARu@i&-tD8cV9{UFM|JL8u)+M9iP Date: Fri, 19 Dec 2014 17:33:32 +0900 Subject: [PATCH 04/13] Add a jjs runnable JavaScript test script to ease testing whether native library is loaded on a specific platform. Signed-off-by: Haochen Xie --- src/test/js/scryptSpeed.js | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/test/js/scryptSpeed.js diff --git a/src/test/js/scryptSpeed.js b/src/test/js/scryptSpeed.js new file mode 100644 index 0000000..f00ade4 --- /dev/null +++ b/src/test/js/scryptSpeed.js @@ -0,0 +1,45 @@ +/** + * Example command for running this testing utility: + * + *
+ *   jjs -cp ~/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar:target/scrypt-1.4.0.jar scryptTimer.js
+ * 
+ * + * If you don't have commons-codec, use the following command to download with Maven: + * + *
+ *   mvn dependency:get -Dartifact=commons-codec:commons-codec:1.10
+ * 
+ * + */ + +var SCrypt = com.lambdaworks.crypto.SCrypt; +var System = java.lang.System; +var Hex = org.apache.commons.codec.binary.Hex; + +var f = Hex.class.getClassLoader().loadClass("com.lambdaworks.crypto.SCrypt").getDeclaredField("native_library_loaded"); +f.setAccessible(true); +var native = f.get(null); +System.out.println("Using " + (native ? "Native" : "Java") + " scrypt implementation." ); + +var startTs = System.currentTimeMillis(); + +var P, S, N, r, p, dkLen; +var expected, actual; + +P = "pleaseletmein".getBytes("UTF-8"); +S = "SodiumChloride".getBytes("UTF-8"); +N = 1048576; +r = 8; +p = 1; +dkLen = 64; +expected = "2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4"; + +actual = SCrypt.scrypt(P, S, N, r, p, dkLen); +actual = Hex.encodeHexString(actual); + +var endTs = System.currentTimeMillis(); + +System.out.println("expect: " + expected); +System.out.println("actual: " + actual); +System.out.println("Time: " + (endTs - startTs) / 1000 + " sec"); From c817acf39acf4f441a6c2a2513eb8d4f9debee00 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Wed, 21 Jan 2015 15:12:16 +0900 Subject: [PATCH 05/13] Fix a bug that prevent native library from loading if any spaces exists on the library's jar path. Signed-off-by: Haochen Xie --- src/main/java/com/lambdaworks/jni/JarLibraryLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java b/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java index 49ed47f..4dc1ff1 100644 --- a/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java +++ b/src/main/java/com/lambdaworks/jni/JarLibraryLoader.java @@ -56,7 +56,7 @@ public boolean load(String name, boolean verify) { try { Platform platform = Platform.detect(); - JarFile jar = new JarFile(codeSource.getLocation().getPath(), verify); + JarFile jar = new JarFile(new File(codeSource.getLocation().toURI()), verify); try { for (String path : libCandidates(platform, name)) { JarEntry entry = jar.getJarEntry(path); From 543b56c77bc0b794dc61e264f1b241ab7fc3c75d Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Wed, 15 Jul 2015 21:30:46 +0900 Subject: [PATCH 06/13] Use a newer version of maven-jarsigner-plugin to make it possible to disable signing the resulting jar though some maven property. Signed-off-by: Haochen Xie --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0674a53..447cb5b 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ org.apache.maven.plugins maven-jarsigner-plugin - 1.2 + 1.3.2 sign From 88da44d565c1bf6844c71e240cc4069e0b8f3b9f Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 16 Jul 2015 19:48:57 +0900 Subject: [PATCH 07/13] add src/android/jni as android NDK workspace Signed-off-by: Haochen Xie --- src/android/.gitignore | 2 ++ src/android/jni/Android.mk | 16 ++++++++++++++++ src/android/jni/Application.mk | 1 + src/android/jni/c | 1 + src/android/jni/include | 1 + 5 files changed, 21 insertions(+) create mode 100644 src/android/.gitignore create mode 100644 src/android/jni/Android.mk create mode 100644 src/android/jni/Application.mk create mode 120000 src/android/jni/c create mode 120000 src/android/jni/include diff --git a/src/android/.gitignore b/src/android/.gitignore new file mode 100644 index 0000000..e0c35b9 --- /dev/null +++ b/src/android/.gitignore @@ -0,0 +1,2 @@ +obj/ +libs/ diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk new file mode 100644 index 0000000..11f199e --- /dev/null +++ b/src/android/jni/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH := $(call my-dir) + +SSE2 := +TARGET_PLATFORM := android-19 + +include $(CLEAR_VARS) +LOCAL_MODULE := scrypt + +LOCAL_SRC_FILES := $(wildcard c/*.c) +LOCAL_SRC_FILES := $(filter-out $(if $(SSE2),%-nosse.c,%-sse.c),$(LOCAL_SRC_FILES)) +LOCAL_C_INCLUDES := $(LOCAL_PATH)/include + +LOCAL_CFLAGS += -DHAVE_CONFIG_H +LOCAL_LDFLAGS += -lc + +include $(BUILD_SHARED_LIBRARY) diff --git a/src/android/jni/Application.mk b/src/android/jni/Application.mk new file mode 100644 index 0000000..a252a72 --- /dev/null +++ b/src/android/jni/Application.mk @@ -0,0 +1 @@ +APP_ABI := all diff --git a/src/android/jni/c b/src/android/jni/c new file mode 120000 index 0000000..81f43dd --- /dev/null +++ b/src/android/jni/c @@ -0,0 +1 @@ +../../main/c \ No newline at end of file diff --git a/src/android/jni/include b/src/android/jni/include new file mode 120000 index 0000000..1905ab5 --- /dev/null +++ b/src/android/jni/include @@ -0,0 +1 @@ +../../main/include \ No newline at end of file From dbec9f9fdbf0cbe7fe6f93804d519806b0ce6de4 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 16 Jul 2015 20:17:37 +0900 Subject: [PATCH 08/13] Add information on building android native libraries Signed-off-by: Haochen Xie --- README | 5 ++++ src/android/README.md | 56 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/android/README.md diff --git a/README b/README index 873c303..638aa38 100644 --- a/README +++ b/README @@ -82,3 +82,8 @@ Building Native Implementation A precompiled native library for Android 2.3 running on ARM is located in src/android/resources/lib/arm5/libscrypt.so. If placed in an .apk file's lib/armeabi directory it will be automatically loaded. + +Extra Notes on Android Native Implementation + + To build your own android native libraries with NDK, read the + instructions in src/android/README.md diff --git a/src/android/README.md b/src/android/README.md new file mode 100644 index 0000000..54b4d47 --- /dev/null +++ b/src/android/README.md @@ -0,0 +1,56 @@ +To build and use native library on android, do the following: + +### Build + +1. download and install Android NDK [1] + +1. check (and potentially edit) the target platform defined in + src/android/jni/Android.mk as TARGET_PLATFORM [2] + +1. check (and potentially edit) the target architectures defined in + src/android/jni/Application.mk as APP_ABI [3] + +1. make sure your current directory is src/android + +1. run `ndk-build` + +1. if you want to clean the build, run `ndk-build clean` + +1. the result native libraries for the platforms/architectures you + chose would be resulted in src/android/libs + +### Useage + +1. since the android build tool chain will reject to include a jar + file with native library that no android platform supports and the + official scrypt build include such libraries, you need to strip + those libraries (and potentially the signature) from the scrypt jar + you are going to use in the android project. + +1. in the android project (following eclipse adt directory structure + conventions) you want to use scrypt with native libraries, make + sure there's a folder called libs under the project root. + +1. copy the striped scrypt jar file to the libs folder of your android + project. + +1. copy the subfolders of src/android/libs you just built to the libs + folder of your android project. + +1. build and package your android application and it should be using + one of the native scrypt libraries matching the device's + architecture. + +Hint: you can always make sure you're calling the native version of +scrypt instead of the java version by specifically use +`com.lambdaworks.crypto.SCrypt.scryptN(..)` +instead of +`com.lambdaworks.crypto.SCrypt.scrypt(..)` + +[1]: https://developer.android.com/tools/sdk/ndk/index.html +[2]: https://developer.android.com/ndk/guides/android_mk.html +[3]: https://developer.android.com/ndk/guides/application_mk.html + +- - - + +Haochen Xie From 6dbc37f4938ab83ca1b15badcc160f0339856602 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 16 Jul 2015 20:58:59 +0900 Subject: [PATCH 09/13] Add prebuilt android native libraries for Android 2.3 Signed-off-by: Haochen Xie --- README | 7 ++++--- src/android/jni/Android.mk | 4 ++-- src/android/resources/lib/arm5/libscrypt.so | Bin 17822 -> 0 bytes .../resources/lib/arm64-v8a/libscrypt.so | Bin 0 -> 22040 bytes .../resources/lib/armeabi-v7a/libscrypt.so | Bin 0 -> 21772 bytes src/android/resources/lib/armeabi/libscrypt.so | Bin 0 -> 21760 bytes src/android/resources/lib/mips/libscrypt.so | Bin 0 -> 71492 bytes src/android/resources/lib/mips64/libscrypt.so | Bin 0 -> 27088 bytes src/android/resources/lib/x86/libscrypt.so | Bin 0 -> 21692 bytes src/android/resources/lib/x86_64/libscrypt.so | Bin 0 -> 22280 bytes 10 files changed, 6 insertions(+), 5 deletions(-) delete mode 100755 src/android/resources/lib/arm5/libscrypt.so create mode 100755 src/android/resources/lib/arm64-v8a/libscrypt.so create mode 100755 src/android/resources/lib/armeabi-v7a/libscrypt.so create mode 100755 src/android/resources/lib/armeabi/libscrypt.so create mode 100755 src/android/resources/lib/mips/libscrypt.so create mode 100755 src/android/resources/lib/mips64/libscrypt.so create mode 100755 src/android/resources/lib/x86/libscrypt.so create mode 100755 src/android/resources/lib/x86_64/libscrypt.so diff --git a/README b/README index 638aa38..8f3d96e 100644 --- a/README +++ b/README @@ -79,9 +79,10 @@ Building Native Implementation JAVA_HOME - base directory of a Java 6+ JDK NDK_ROOT - base directory of Android NDK - A precompiled native library for Android 2.3 running on ARM is located in - src/android/resources/lib/arm5/libscrypt.so. If placed in an .apk file's - lib/armeabi directory it will be automatically loaded. + A set of precompiled native libraries for Android 2.3 for several + architecture is located in src/android/resources/lib/. If placed in + an .apk file's lib/ directory the proper native library will be + automatically loaded. Extra Notes on Android Native Implementation diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk index 11f199e..bf787c5 100644 --- a/src/android/jni/Android.mk +++ b/src/android/jni/Android.mk @@ -1,12 +1,12 @@ LOCAL_PATH := $(call my-dir) SSE2 := -TARGET_PLATFORM := android-19 +TARGET_PLATFORM := android-9 include $(CLEAR_VARS) LOCAL_MODULE := scrypt -LOCAL_SRC_FILES := $(wildcard c/*.c) +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/c/*.c) LOCAL_SRC_FILES := $(filter-out $(if $(SSE2),%-nosse.c,%-sse.c),$(LOCAL_SRC_FILES)) LOCAL_C_INCLUDES := $(LOCAL_PATH)/include diff --git a/src/android/resources/lib/arm5/libscrypt.so b/src/android/resources/lib/arm5/libscrypt.so deleted file mode 100755 index ec4b4341daa57589790446c9741b200cbcc85b2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17822 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 ZlOX>(;Qg5ZS&RQb;QR|hX)lV>`WHyHONsyh diff --git a/src/android/resources/lib/arm64-v8a/libscrypt.so b/src/android/resources/lib/arm64-v8a/libscrypt.so new file mode 100755 index 0000000000000000000000000000000000000000..897e29fb94c1262eea463f33415984611822c0e4 GIT binary patch literal 22040 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 PMs0s*G!ge2pGN*~IQ)VK literal 0 HcmV?d00001 diff --git a/src/android/resources/lib/armeabi-v7a/libscrypt.so b/src/android/resources/lib/armeabi-v7a/libscrypt.so new file mode 100755 index 0000000000000000000000000000000000000000..958a05482ebf9e7c43a9b20cb963619eca256a71 GIT binary patch literal 21772 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 No`c@WxBwp4`#)npB}o7P literal 0 HcmV?d00001 diff --git a/src/android/resources/lib/armeabi/libscrypt.so b/src/android/resources/lib/armeabi/libscrypt.so new file mode 100755 index 0000000000000000000000000000000000000000..06f4a7394dc4e1f140a678d7667dd66c0f90e499 GIT binary patch literal 21760 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 literal 0 HcmV?d00001 diff --git a/src/android/resources/lib/x86/libscrypt.so b/src/android/resources/lib/x86/libscrypt.so new file mode 100755 index 0000000000000000000000000000000000000000..75368f707dda211919f2aa5cfbd6a49050368e0f GIT binary patch literal 21692 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 P*W1^|0+BbyHNgKLNolVh literal 0 HcmV?d00001 From 75feee4a0275a5eb9e571ed2ef50449133e93eb5 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 16 Jul 2015 21:00:09 +0900 Subject: [PATCH 10/13] correct a note in src/android/README.md Signed-off-by: Haochen Xie --- src/android/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/README.md b/src/android/README.md index 54b4d47..3cd1b11 100644 --- a/src/android/README.md +++ b/src/android/README.md @@ -10,7 +10,7 @@ To build and use native library on android, do the following: 1. check (and potentially edit) the target architectures defined in src/android/jni/Application.mk as APP_ABI [3] -1. make sure your current directory is src/android +1. make sure your current directory is src/android/jni 1. run `ndk-build` From 33c8991edfa529a80159ac171093e25c31ea1a0c Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 17 Dec 2015 21:34:34 +0900 Subject: [PATCH 11/13] add debugging code for android --- src/android/jni/Android.mk | 4 +-- src/main/c/scrypt_jni.c | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk index bf787c5..44db577 100644 --- a/src/android/jni/Android.mk +++ b/src/android/jni/Android.mk @@ -10,7 +10,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/c/*.c) LOCAL_SRC_FILES := $(filter-out $(if $(SSE2),%-nosse.c,%-sse.c),$(LOCAL_SRC_FILES)) LOCAL_C_INCLUDES := $(LOCAL_PATH)/include -LOCAL_CFLAGS += -DHAVE_CONFIG_H -LOCAL_LDFLAGS += -lc +LOCAL_CFLAGS += -DANDROID -DHAVE_CONFIG_H -DANDROID_TARGET_ARCH="$(TARGET_ARCH)" +LOCAL_LDFLAGS += -lc -llog include $(BUILD_SHARED_LIBRARY) diff --git a/src/main/c/scrypt_jni.c b/src/main/c/scrypt_jni.c index e8e54b9..10fc966 100644 --- a/src/main/c/scrypt_jni.c +++ b/src/main/c/scrypt_jni.c @@ -7,9 +7,31 @@ #include #include "crypto_scrypt.h" +#ifdef ANDROID + +#include +#include + +#define ANDROID_LOG_TAG "ScryptLog" +#define ALOG(msg, ...) __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_LOG_TAG, msg, ##__VA_ARGS__) + +#define STR1(x) #x +#define STR(x) STR1(x) + +void log_basic_info(); +void log_params(JNIEnv *env, jbyteArray passwd, jbyteArray salt, jint N, jint r, jint p, jint dkLen); + +#endif + jbyteArray JNICALL scryptN(JNIEnv *env, jclass cls, jbyteArray passwd, jbyteArray salt, jint N, jint r, jint p, jint dkLen) { + +#ifdef ANDROID + log_basic_info(); + log_params(env, passwd, salt, N, r, p, dkLen); +#endif + jint Plen = (*env)->GetArrayLength(env, passwd); jint Slen = (*env)->GetArrayLength(env, salt); jbyte *P = (*env)->GetByteArrayElements(env, passwd, NULL); @@ -51,6 +73,38 @@ jbyteArray JNICALL scryptN(JNIEnv *env, jclass cls, jbyteArray passwd, jbyteArra return DK; } +#ifdef ANDROID + +char *get_byte_array_summary(JNIEnv *env, jbyteArray jarray) { + int len = (*env)->GetArrayLength(env, jarray); + jbyte *bytes = (*env)->GetByteArrayElements(env, jarray, NULL); + + static char buff[10240]; + int i; + for (i = 0; i < len; ++i) { + buff[i] = bytes[i] % 32 + 'a'; + } + buff[i] = '\0'; + + if (bytes) (*env)->ReleaseByteArrayElements(env, jarray, bytes, JNI_ABORT); + + return buff; +} + +void log_params(JNIEnv *env, jbyteArray passwd, jbyteArray salt, jint N, jint r, jint p, jint dkLen) { + ALOG("Parameters for native scrypt run:"); + ALOG("passwd (summary): %s", get_byte_array_summary(env, passwd)); + ALOG("salt (summary): %s", get_byte_array_summary(env, salt)); + ALOG("N, r, p, dkLen: %d, %d, %d, %d", (int32_t) N, (int32_t) r, (int32_t) p, (int32_t) dkLen); +} + +void log_basic_info() { + ALOG("Basic info for native scrypt run:"); + ALOG("Native library targeting arch: %s", STR(ANDROID_TARGET_ARCH)); +} + +#endif + static const JNINativeMethod methods[] = { { "scryptN", "([B[BIIII)[B", (void *) scryptN } }; From 2880e02f916adde9a4e09936bff6fc735334b225 Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 17 Dec 2015 21:37:07 +0900 Subject: [PATCH 12/13] restrict android ndk build target archs - arm 64 native scrypt lib seems to be the cause for incorrect computation of the scrypt KDF --- src/android/jni/Application.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/jni/Application.mk b/src/android/jni/Application.mk index a252a72..0ed9978 100644 --- a/src/android/jni/Application.mk +++ b/src/android/jni/Application.mk @@ -1 +1 @@ -APP_ABI := all +APP_ABI := armeabi armeabi-v7a x86 x86_64 mips From 371d55c1c4fc8b69912278479e1c0f8d26644c9c Mon Sep 17 00:00:00 2001 From: Haochen Xie Date: Thu, 17 Dec 2015 21:40:10 +0900 Subject: [PATCH 13/13] update prebuilt android native libraries --- .../resources/lib/arm64-v8a/libscrypt.so | Bin 22040 -> 0 bytes .../resources/lib/armeabi-v7a/libscrypt.so | Bin 21772 -> 21772 bytes .../resources/lib/armeabi/libscrypt.so | Bin 21760 -> 21760 bytes src/android/resources/lib/mips/libscrypt.so | Bin 71492 -> 71604 bytes src/android/resources/lib/mips64/libscrypt.so | Bin 27088 -> 0 bytes src/android/resources/lib/x86/libscrypt.so | Bin 21692 -> 21692 bytes src/android/resources/lib/x86_64/libscrypt.so | Bin 22280 -> 26376 bytes 7 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 src/android/resources/lib/arm64-v8a/libscrypt.so delete mode 100755 src/android/resources/lib/mips64/libscrypt.so diff --git a/src/android/resources/lib/arm64-v8a/libscrypt.so b/src/android/resources/lib/arm64-v8a/libscrypt.so deleted file mode 100755 index 897e29fb94c1262eea463f33415984611822c0e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22040 zcmeHvd3Y36*7vQd-slRQKnDoROS;)@F+l`OMjfgFU3U5|i|+WTj(IJKZ#ZSRN1w?-YG7Hbmd1^z^}j)91c z>ODn$5NNK=2t5!6BMd<3hwyI*gAn>7SP}l&>rP|q31*900gZ>|u(z6~d7(av2m(T1 zgjj?agam|mg#XngU{soZMVA#=PqtB&r$(>CO>dO9xgr#wnlWFYtBI(H=7IXx{UW() zV~EZhh>4E_$E;bJ1R}YTQr^h^NQ1+*ktQ717KA(1^PWOCviKA#h51mcE5kkYzl?;5 zYkwqCP;jSuGLU~KI@Ncle*Q`+Z)7PCMk;Pq!T5wquT79)OwO}f2Z;TexRSEM|Ubu6LF_;ZTNxmBYvR#PNlq&?Ykd0xE4nu z7D60{zwYu)`hj{1Q2tK+d|RO#*&ua3HT%FaGjo=EGUqN>;#s`l`8+l0S(dka!7?NY zmw9p)W#-IZlsWGik2m)=%3RNa#Vp7B+|p$QnT1Ns@;!?e7v!+~e9uxg%k^;jc;OwO2=IdjSM0#7c>&&w~&TSigN(&yOJ8O}7d zg3M`4(4lC;PnPDQo41iB(D1=%@Cg#{EBF3Zii`))Onug1BH=_WG|>>l(byReXk z>80Uz-DhU1sk|k*%DoyRQtDNPOV#*PybJ1tYIZ@h0~&q4YPYv_E5B5wS9YUo`r0`Y zg2u(6eia%@x>BX{pm)g}Z6rF6Xb~Q!O$?j^`g(y1N!tU4Q6-TNMz?}6uJtY*E{bRq4Pdt}s6aJtDCGRZq zN+Nkm`W(_bqtbsu`e;=83#6N)(#=To6P3CZ{x+nCM5Qkx?TSkO73u7#^xu#!iAsNq z^v+1S60Qlx(vsv}upX92qRnA*$HRY|b?q(LbjK#<1-;ly(226Z z-`3xI=lZQw7u9nwZ<3v;`yFnexCG-H%_oQsHbA`e)COyGpTFXI$RBVmk-KqqqkBp2-B!ZD3bc zpuef;Z^8p7UmjzDxsd5sPqM&wvsr+#+J`)lf5##QnXth5 z90r+!UbZ9SN)ZcqAot6KEYSKamGwQ;xq?ByxaVpgYFW(!CCG0sXOJuCGo?^H>T`j& zg!erZM4r8@G9!rlTHLd;s*GCPAA(+0@=|CbV;ykE=UkmFK}Vg?Q5SSH4LX`$4gK|# zekX^+Tf=GGnY^aw8uu{njE)(~NuM8;nE&Qb79#!Dbo)zQ*HO*boV~T|jFB13GnuiY zWe}UQ270~qqlK81W%4Mx28=^&zl9_9a=Uvkr6#^--GID8{`_P5aOW!@WmM zXCd7L>{&6^oi64t;`xqjjN?nbPshGEHYW>pdCy=2QYN)vMJ>b@_PC zU*_WcU-GPD0qQBjyp*CIYBL9QP~VG7I6qLcPTARMXTh z^||e4cx$sOy3hSOrW$YcxfShEpIZ=8MdqI<4Ctufd4Gby`46F=O}y`+Ylv&nC#sX$ z^QmoRAwG(_O0@c+$6xaC9d{x2L4Q05*#;?OW9(!W&qBFoDO8MfjztPN8F$iSV4>{Z zQpg9or!QhEXJ(aV16q5evYh3c=w zIH>+gjDhN}ME|M&O7wj>`tBR@1M@fH4)f=@!~7+6o4>J9^EV-C{(clSe?Lb1>ij*8 zKIrDp?bI`Uc{*dEUA~`nrt1*1r#jP3ltvsw>7RF|$59$_Jf$-`(-SC-cn}Nqp|vi} zc;>=hef}@myzLh{q|n884EaqTvrtpfigyz^)`2!Re*L~NpX|n8kC^hwX0Yp1LVpLY zHQVuBp|1Mo-7NHtAk+jKS?F6q?_gN#+7@wv_AgOaI}7cb%H}jLat4~7mEOII{2eds ze2r{aP~aUWra(`1>`W%pU3?h*2&S_+Z|K;SYQ(HI{4!^%d$ow?I!;j9)cEQf;G2*8 zPSn>gr~mA0FX{(2-DJHwZiKfseZWGruGglsgS9_Tm~Fq#{Px!8UuM_2ULn|{;9lfY zxl@sHEDhzd`_CSUa%}>0G!<}UtIuXLpF1cR9BDeAdjvOkyN>yKpGUplp)UIihS!3h zu}~xGNz}1le+#-#Vsn~=evV)x#*K8-=NR|LQm9$zQ_~{E*9=3Q=Y{??kH)Zy&LlQ2 ztNFP`L1}~4w9MuLW{f-Q;)=#*;;n+deX+c;=~>hv^gY#7k2EmR^bX=Q*n`Koz;b~r z|Izid#-8AlBz9&9?0Y#5O*n|{kebv$4GI_SY8XmhqR(6UzwwN^oQ87psk4|7$-Fcz+6m`FYpa0z;mz&e`H zUh_LrD0u%H0}>hE(S+E>Fpu}Kac?{b8QurE3j=E~*0W7TQfL|*c&ZiaQx4kd!FrTm z0KXIKiiCB=#!1s%sM}{_(_4Qlg^HN2qqUy*`(W2v1;PI^#o*mUahl-gcA1h_ZMRf=v#B`2<+Bu7BWFbuZ~~`Gw)_sY>@xOt#1sVxvzv?(!5V3 zIjHkqIh2iCi@;MJ^o?{mN8rncFz5s3Jdq9RkT7R9_@g;tv<2A&u{JkDM_aHaU0eab zfbfBJ;|SJ3pV~$u>(|k=IwIT3L^kf?3MsS@akJ15{C$*mZ154f+CcrKsK0f#1RYL5 znSn|hWhUlt#hBphhN!)3ysrE+v}Z>;{peiQ6^Ka8agG@DKe z*cp6gA1n7LWw^CYieKPfdvy>yxC8f@{n(Xyo|QA`eJ$b;%^Bl5XucG^Rp-l=z{d4Q zARXmUzXbiH`62zbW4i?Ov5 z?p-gi*ML+1QQ(aF6Fs+?7^@~fUvD<sWz{YIQB+Vc@bmerv649PuRr!walr+amMR0{heh zcr^j9t>DW+pLoof9e!X5(^sW=pHWyVY7o+f1vNZnqZF;8MnxJEs72bwH7wM>68?jg>=&gQYZtlkFm?m?O6M< z&caW0K-WW=&|Qxu;_qMBI|=Ktv-;vYlk>^%|N8wY`Q-cm^~lux?+Vkg7L&hYRQw%= zz6dL_I-Se2Iz8~kxD~d}2u25VIH5mF;R8^aY?Se!jN{{4M@s@SD^; z5Ay6$e3bXq&2Yc&_T|qQ-)!)7r=J7;?ZTsEeE@0>afpWahR)3 zOd0xuY4(s8;${nba8*egpk$_%6KF3SXd(_qjR70-MoZ zok}a_BD9S(KFIWQ&`G9L{*Sm{3p(AeL3{$~_f$TQ5aBBUJ)Fj$flpL(^FDe$vI#$H|l~+0zr&B^KtgH#Ire>i`mmzct+10!=A>N=J4Qiv3P%u+IOlqCq)Wn zq0b+pZYAGm^>^Z)=HUa4*3{d775Cv%cIGJgjPL=5uuAXM6|8y_>J*?0x!4!TLEp-7 z-x>=)5p|*uI;`&nczC60}Q zedt|?`kP}RWAvSDQ4r6@S64{bYry&{WS*-9uMK_r7X9pnxd@jU&YXwO+Fp| z(2wEp@9u?z^MPJ44!)XQ_5B`E z{XF<|$#L-2R-)W9$j^ZfNPb_1>i5}^Cf_e^)w>zT;kS_w_zif--y=Ve{Jla1@&n2L zBj1mFJ@Wg=2P{OHl?defO~$&N4WCi-{ajdUN)fUU#xUu|kWbi|p-t?}uvzTPBud+u zzXWk6({~7uCdZO(==JD5u|`93vcYgq@~%0lv6Z@{rrlnZ!eoT(QM>-3ZC-{#soe1ATT#0>29j6mVzP!dgis!`k5pR1ZF}>ND zP-5L+Dzlof=QugH#JU%4_#ZE`zRY@?cVj=(KKiJ9Y5XzS&J41i(~FaNqvI0xEJyZ` z0%%jb#2FCu;tuQsUU=>e_ay9>u0vfT5{j*>ndlgfHZJ$rU^N~7jrZ*6I{6A`G_T=I zBJ#{%|8xWPSefvC-O_?`__nx88d1 zgiqua%*lS#J&89sXs;A|wqjeA6u1|4=RLg5eJ?MFORx`m+_BeNg?-fHC~xFr9rc`G zKGFXr>v*%@nuEFi5c|a=p72}IU-M4Puj!uCvYwAMADVCma*B};VJt4Ji)hc`VkU7P z>g@wLr9&RWe_Y~*uM?=pp6&1-ze#csOPOFE!pAvQCzM&=H*dD?;dyfo>nX3xEwh4d z-hsJpAAL;T{lsSLwF!T~9&?O*jn~UZ84n*vz}~b4GBS$oJTG2D*<|QP$()Vu;G5VF zpYpEvYc9q-1pRF5zrnhL@8$T`yw$pnv&iRp&g{b6f@c0p-Ue&K=#S-=C$?J8P52D^ z-aX}Wyda}(j3GvJVP0F_kpd0SpB;ZHcb`LjU(=p2WM7D7(^-tUh415-1id>=BkAW7)OkF;XQgj(TkHXU&8Fo z?srjV66=L}V^QX}-s6ygfPL~0F`h@vFI(&QevbK=({)^|yleDn`6I|>62_GF#LJNP zSsD4}GPD7?D&v4`L=$k({=O6#hH==l%H4j*=R@pko47urXVy+{JKBsv{Z78GL+HOo zk@;}cxejG|;@!Y7$h{r&n=|@^O!7uKMOKG+ozezmBewk(?;0SNDzs7e{zmsRkWCEc zyPfqD?W=ZqTM|}V8_>?zm@hlu+i?IgCwcrOceQmF+G@buf^NhcDpU5Z=8TFJe;e7yX26$t{*7^v}gV5cQx69qhkj;n82)XqZ zk3ROcw<=+!m4m!dUfhp%{sye4V?JR64|q#}31AL79%Bx2aSoC@%3>S_c|Gs} z8s^_9lDww?BQD6kU6DC2<2{RmFy4Gh3Q(DmXe0Qk&wWL~j9$)ReZ=Aw?|J7Xl#-1V z7o!a)@SX&m!%m_Ny_}z0Y6T5AF^H$fpOM=}*UKZJ1B8#$7$>!%;iG}$#M79I;-u~F zwvS=gfsMsXCwuNY?41Hk)S->(Xk!Fq{z;FQtS2}F+K6BTG|WG2--OfhdEn%OpS}e7 zkj#y;fipz#(HOypo;QdiQr5cr6bG;lRVS7(@!MqY0=K=vqWCb<(n&cjX-Hek6$1bmNUxKY24SQB+GOR@o!iF1mOUdVTV%z7igNHY{-LUa7 zu($1y`OwZC-c|)4f`X40Rpzh>XoFKQ0-Ayml6eU*k`9>@KB{0x2pjhTi-Zrd=XjP3 zl%!U`wrlvXh$Y3ly!F5Y)(Hh4E>-5kqVNHlnean0_W&b9A#=iqhKQr9WK<`H6}=>}caHv_bfJ3-u3& zU3&{{xg2ZV!K+f>By84E<9ps3)J^N)F36>ri*>x+W4#sYJlZhIZ$ciRnWsV~Wst|t zpRTu_9{&;MUsU8_;>_Y{%oX9I`I;0sjrwfMnMY#2b6~4>07E4I9JE1pq#ffRnG-&mza!s=6S+_sWNw5n5i71` zdi3Qt-VhZDhlCk<3XJi(spakgth1nMYv0U9eSkTu%k(F13vYMdn5YA0%_~ z;f?|`!Ojitwy+df2zzDkc;8!x`pIS)Aa5D%kjyW@Udgam4`WRS-38PhspLQHZeTv){Oqh5Bm8l3?LY}WaM|L$Fh zJ`y&{Aa5hELNeb2dxgbF!3XGO*bVqsC*<9#%n2W4uLvK&w1SV*sDB>pIdCryTe!~M zB02+R*rW9Ss`OsOIC9a?HrTBy$ev_=96lq2s^9}OGp&&gz{WA?0Lh&2LH3I90Zc3S z!1_+|2R>rOmeDKS&9P1eA46B}^roSYC(+JP$o_cLdamIEbh8KZy&Kq|wVm)DjSpJa z2_L{a@Ikho6L-!kb_cCa1s~1d?z#;h8qR6`*6=|%*YH7WI>|m7AG8K2_~_>h5Z1Yo zWp4Nzz(-F7AD;T%3O+7C)@v~q!Uy48!$%2ZjOT+ce9+oXGLOaw@EyU&Kxcq3UVLP| z`z<_kv_STRkK*0c-ZhYQG(Je?8b0@0S- zB{~&+aPw-q@UaK-mN6ERIj!d!K0sISL9!-%(0U$?4_em=A8}Zhc0k_re6wodOYZYS zBlwuSWB+aVI1afJ&T0MD@BvyEK4?uRnMdP;)^oxKJ)>Px@DU^CJyz^)9T~yLq>tY2 z!UwJ8gb%_wt>+p(Xg$~PL2Eh5JQ^S5BhmT+KL+?9oD1Ty;jg$`?pE=Ua^N<6(0WcX zUm1lDTF*6nl&Lt6#s{#i-~%=uI468q#Hx+JM{)!oX&LW!;iCkyCw!31cSWrqpm*V; zO2v6JK4?8Be89#7AB1yG91{O4ckn(HACDcp4Ii-GUF*4q53=VPKFHRS?4$8Pwq3!; z{Z7TUdw#zTww>@1S@@?a}z4^;}s$9&iQ-6PT9{8a3TrZ9ge&s%&rs8Alzu$(B zmFjxFH){O=tqUJ}RGCNP1K3vZL4F(AcRJ6s@|e%vIwgXS;f=S}k6n;A;e&AA5QPuW zyYO*bm3cHifNKRG)h7WpHBbk>*tsi91HGGh*C)r2igKWEk54L~MHmALO%4c@sWJ=BuLc0eTlcR;n_O#s_e% z;Dh|Pc?!-2v2_~O54h*7Rtsgrfd%_3F{8-fb0eTlc>Q$Uaj5 z8{oqcK6;AWD+j!*;bT!79gz1tW>lU(NapRJ&&Tt}TF4k@QM>#r&4%{BSj6DAUwh}`86=1{${}ld2ARwZX2LmeZ*D+d4P^W#+MwqT^4$m@ zQ}9eed&bxYmFIFM$7!@d{#AP^;oKlj4!@y1pVMA-L%(;i?<&Y`C|?74qaO1ZJcFEq z%=bdhyO9@{R41Q+oKND}fu2DYjX$mIRhOa7MR+E~9*jJhGddz^186$fk61D9SL@xa ztDS)nc>d6@J*ePgGS*F@4qzulsq4M`s8Ef0ypH-<)B}v z*I|GiX-8X>ZbcukKLtAWG+wN5x0E{rQ-F`*U%u~M)qkBe5B*xr8O^2G&oAICj-}&{ zL5`fffyJ8Va~5Tvy7cif>+#Va%ByhJ*#$WW&{@nG_R39;N#M^$J1)dkkoDxj8{FqN zI0LIOk0VYW_R@12$$KTk`wKjC&NP)k=4M6am&PBJXFML+--=7BmseqbAN84OPa5?* zjM!_x!1V+^j3Vvt=bBjn??se%2#YK%(1!Pwc|6Vmpfq6(0j~Yp`!veZE77*gm_XPBL5DU;dzp%ianY8rZX49Fo-0M#@(iuVRO!3Wu3}*!K zo_d%RkZfs>1o3W{ z@(X$HOa;!6{tuKXLYb*JlW-KYbA6?kT{y=_XU(qhe0k)261^wxTXS~Uira_~OQ zfb$E(5r*LmLvRC2ZF+;H(m95fek_#vXZExJdfRI(m4SA?oTav|W~sqamfErvWjC?Z zui|kIGS=tj8UJuGW1rA_XuHJxuj33f-J`4@XUfiQLprO3`QN}fF1+KN2%L7Lt}atM=jDakmCll+KoRPs>VkH>vH!hJ|j8MM=~ zXV7j-U(i<$+GXht+OWaDwv5yzESZbY%aD@1+mNs%7l9vCY3XAalUzLbphX(|t|i_u zD!G2}Z!A3WuHp>NS%jgu-+}OJ+;2qi;hxS3O+lb@K{|x&!S7kpz;8!8Z14d~Guo*~ z*n!|faN!J34uTzlAq-F9ExHuJ!j=mb`*Pk=nxeOqE!SK46b>}bQo4#=FXP#bY`puV z_n(9_!dTIZJc59rL(o?jjb))=Kb*gXEE(iS7_|3LF}T864cROB%i{5^hlQo`kSzxp zmY5?lEHN0IMFKHlZ}mPGPP7P3?t1LSCpHsG7c19WD%6S%kr+fax3r0;47 zFZ69q2zJDd`3+{`yzodi=Odhtr}xpMt91s{Yx14tQD?}(4vtS_XC_W$R}S4wZ~O<& zIUX`F|8M{LLgRwrWCsS;c=+0fj^KL^Ce%jG;PbwRns6q=16{|NU;hy^yJ9DMOM%YQ z!R9u>hImSl5Bwal+#w$r@*G7z@A9rO??-_!+Wi z;kc9@F>H>oC@ZBHXY{fcW+9L3$i^C)z0j6&mq>Y@6zC7~JPKbV&z>?3cvbj%f1hsw z^ibjJ`+dG&npD04-{-5ww*d;@;P3PO-Vos{8A4;Ae)1h2Wem2Iuk>sVwzOmouTL76Ud=tLU z_e;o&_$q#+@x`ls8JbcJS#gj<7Gx0V!?+asMvHU^=d^3C?d1HkpkH)JjOTrb|a~p6wj@X_+{4S){M7 zg`XBKGAMqU9di@yH*|fUg|qDBKgHwx7oB;ecqQzmA9azvYlc0Gw2@HLna26!b-uGd zL7831{|D?#wfw?vRlh+IZ6n-;aF37UrjKBgl^>8$Q00^OsRVM`902yQ~Szy8R(DZlNxcJ_8Qh6koai7V!z` zY+=8e7M$<1^7N8{s(*pictop>z2`@T8)R zY+=BuOdr-+HlW~q)mj_P^mi}y=6Ab&sfK*84K%i*mI zSB5SBnZjkZ>^z&twzS~cJg==_u5GMso;MF4wR>&L=6jad?nSw2OA4QvJ9k0Og1jZm zZ1^m`!26ud^9y`=@5x@Ahx{2TiN3q{EL%{p#73Xx=jBoxbS*^Tq*x% zTz5U`B2I3g@Bro0H{y%y!{LpHQyRkIPY^$TG8~TM7`xCI4zEG1I|n-A1Bg2jkNR6U zJcehi0`XMDl{ieg5%FOh)~rSR`t@+wB!G_ChS+u^9G-=kuJ}mAxaZwWw|p=+FeXu< zJc$2;5I#K`4u6O`nA1|pP2Ln=Vcpz&ORueQ+hSj_yxQ}%nC&9J+x%&x^V}btfBek( zr~h((@wwB&oFei63?b_{+SDohv(h)4wiqXE=Qo)vdTcdp)4!s7Rp1Za&aE(`IL*cD z2-5E{mL3ZKCxTNyHCaC`X}Vs%NB{6>{q(!_GaQ>!w%o7JxJy5C)TSR*q)ys8VcYmu z#=UyqYhz!(cl#LOPaIWmm}ZztJv2OwjVE-|FvBpN`f8YI$Z-DobLSUYtBj?isd&uk z<7dNRB9Ntd^r^S}ONw;0dGJnz7Rf^H!TUJK0M7iYym2#EB z8q_KJ;#=i1zNOCQ(P_-)q7uk?Pk*QSJuey_!Cj};~;Qt7TTO3O5^3e>YM z6b|bYO5`8)XFur6LH7~KX~}YKim4FOwwpGaxAb^anTG0|{k5Wse z5D_x<<6qamX5e2l@UI#8e>4Ly?aI}t##;LGZs`l%(wEh=X5a5q8RJyC7WG$ewBKK& zC5bNV7c18QHP(KwhkOLOw0bm~y-}@SAIWBtdZYc8&f~DnbeSU&lhpFc;t5)UN>|+! zwq|CefXc?S@z8ofm-hQ;_}ERkI@N|WI`(UnOB=`XNK*OzG`iK=(_%H7eHRYXPeC!Y zdko8olGetlmHWRPUseb5e=62~C+~;)?fapOf08~WE$v6PQByL0a+hsfQmSq2n0v>K zNf~>;ZPZe4o;PoCo~JPHF2<4y=NB&XF2g2u(tJ*lQ@+0vwFH1sE4-wV7 zrHhxbB>bip{(B2@J^0Ri?-5^*qOt@T*)4w0q*B zYEgmGj3<9V4ojL>fGQ&u;Anto}& zv8Uy0xY6PZY6jtig2u1uG2xl$8o!3au2@rSl%cCzlG#C{zG(a!jcIO`h8udxD8{PH47J1Q^W{0$RJTjyCwci!fVjVrGL|xjvYorHo zL;Pb^!r}DDjTWC!=~|@qpLpm>L!f(YetzipCaEl4-P?Zzv}pd$NlG!M#S#fO>eAZR zNKfL1Y`#`Zv+LULQFbq{^;_eghnv_ae$DRtW<*M8^Q@KcUSAsvYwO6GnaIGU>2D-;OaHWbUP4ARKbxgC zI4i=TMjCt9I;asUa6@%z{nLJba8`Fll|ijtV`s16j%Z`LD3KeDe|R^##vdJPZATY< PMs0s*G!ge2pGN*~IQ)VK diff --git a/src/android/resources/lib/armeabi-v7a/libscrypt.so b/src/android/resources/lib/armeabi-v7a/libscrypt.so index 958a05482ebf9e7c43a9b20cb963619eca256a71..3f973a3c18348138ed7a86e0adb21748e6317006 100755 GIT binary patch delta 4627 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 diff --git a/src/android/resources/lib/armeabi/libscrypt.so b/src/android/resources/lib/armeabi/libscrypt.so index 06f4a7394dc4e1f140a678d7667dd66c0f90e499..e4309fafd00f74ed463040450282efbbd6499809 100755 GIT binary patch delta 5108 zcmbW5dsJ0b9>@2&FWwJ95#tC4E-DBbh!0c{f~zPJqUfmU44|l&Mv(<%TDH!qsL|0T za@!0qCsz+c$+}9Gt+JezwbUAg7PYKgtt-l?WzMy6-Cx?6rRP`}_R% zd!K#xc_;@2<$%!KG-uL$#>mVJDUvY(vb7ZU2d|w(;AARe7A@ZZ-HrU+$S3nu5MDYx zG4oOpV?J}D7MTeJ$QBJWR_j}BLS7S370NSnXE7Fx5>YIWO@^MD${00E{19{um=f^< z=v97D$TJL1=GTRZ@@FxOHEWr#LYIuhpfx@S^`$5{|A6%(pE{w&dZ6Z5#+G3y#OJ`j zAH`UimVXiIOH}_yA3%w3FebAXCNVbG69{B?psI$i?4rsFzr z<3sEJiPw1U*W4g5YBi%u-F#R%-5P2er?C|HNOWXwRKzrlS1l8Z8XBmNa5jd$U@R=X?fp6;aU49&lgGa)QeH|qF@l;vxs(}70ykAYv)aUa-LiAK% zk1rE%^JMdKOS5g=n#PJ%TN>9?RMpp4ZK-H@Y{Q1C`Ymkz#&s2SRrOUH8dya|Rc&?s z#+vF1Pq4nGw$YQls;Z%8bwy3>+Kt`)7RhWu?!<Ngxdofqd^3894rquO^cDl(S3mu?k)GyXm~lW2ku3@P8fvl zv^4W3O}A;fQ`43TZ+?fSdo}IU^es(yLq}kQuUE)$FiZypu#Cr{F$VnaNwEYcNds_H zlj82uLmGs0f)v-{94Qv`JSnE>B*k^QM2d}cg%q>9Mv5hNk)pqwq`2O0nH+3@JET}k zlXJp=$@$7axbsD4pzGs-7TSfMzu0d&y|ceX{b<1FH|zXuI$zQGn{|Gj&bRA)xl#wq zbbgu6pR4opb$+(a&(QfPI$wfsVy_G^_M-Ews{S~fCdA4v2Ifz=8mJuOMUkT|#}U6$ z+Wlx`zae7vAWJp$zBRw4!1%4v^$lMUow@3mJH|S~xo7UUR)gy&_j3iI=i2A*DF`~( zGB;H;xcc2=+F6>RH@Ty!z=S&c+@V%uW!!~v9T$akab=+-=4C|fHo9JQhd1ND*c*Pq zDCTA5C8ro(E0i;$xzY8qn_rI}YcjgFxq0kx$z*Vu+}%0D|0>AYYEa8?^!m1HinsJe zv>056)NuU1tp+%W4tVHIRYzJylc`yOSZXGd+%-&^fXP+*U#4xd?DA9ft z^u;oklqy<836YrjBNrINCvA*N))fUTv187mg7ELke>XE<;3oNNVP@qVW1)~GaG{;G zRAm(|7Ba72{!iieBjfXf=d;8oZLLfGToBNcXg`jI&!8JDiPceLn!DLHbZpT)&vB(Z z0A(=Okx?aoa+r6;7H_qg#R%~UTcT)?;<1RO>U1$hRB!E5ql%4UB619p!6g@}=2i-~ ztKqtEwi?jR;8|!UO%1>r9G|laXWUv?Eo_6Pkw*ec0*ejOR&%aOy@sj+JrmYI_W{-5-*=LF1E)lw8piCXhnP7qdlwGk;ZpT${+r^JE+a7 zW$kl^AnW{i{;x^vg_XQKt95LITbk8+xhH8p9yr3Ln6h{As6O5s0Ed8+&<^4nk?Frz&Z zyZO6-fWEmIZ2^X_nX7+Da5C5BA*+2wfU!>!doq~o%21L$D!|m&XQt+6mWNFnE!6R}X=%bEeCf2=!Zf}Ik2~Ql*q^DID*)n==XqAHRcPZ&b2I0CaNFcGCh`rRW3`)-q6^GD97lz|XI z4>%W}=8xFog?v8GmcWYwv)sFKpF%ALkTN*$CQbL`NryhtVgM=Iw~6e!idN!(?Um7PD4BP!X~RQbyxRVH5h#&xWWUIf-OuBmU3)^4nqYO5OM znoVn@22TO0{;}E_tgfn|;qhuIMSFipogs~BU=3C48~sA1=~8{VRF^JQ|FL9EElO3V z>x>o9JB38=6uzGPJ1VVeL?}U8U$d$nFDg=FRXtu|YHHU>RrRawo^Gq^H+1hP8Zypu zYOfQc@en=+M&C;);iZ$ki-$WrR5ArdkFPuNq)2ZW!!%2e;GdUHT;77`X?lT4h2qtZ zoxp=7EzUKwSAW%XNYfCMqx@)SI8=nvQ!_m!(<3>aR~bEqH}lyGmae6*NAyjEK1)zK zf#(7G2IZeZF_Hh@x`!5=5ri`S&xHxWG#|253;%Utd=O2C%+5zIO0cA34KVM5MM*)l z9ApaLuqYwO*LNR(c~L?zEi2i|sr=(b@s=D6IH!pBqt?CeXFRMtA(&=ERx9wSaKe1Ew$*z-Y-UJV8QO?i9}y$$SMz}R|zx4cY9;iZcY{}(cv B#6 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 R173CrD#~n`al|9s{{t2m&9?vm diff --git a/src/android/resources/lib/mips64/libscrypt.so b/src/android/resources/lib/mips64/libscrypt.so deleted file mode 100755 index bd858716210eaaca7307cc9d43e50070c0a79e28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27088 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 diff --git a/src/android/resources/lib/x86/libscrypt.so b/src/android/resources/lib/x86/libscrypt.so index 75368f707dda211919f2aa5cfbd6a49050368e0f..f005a0f94ebb41a1c4e8778fe9e1f13183ad89b0 100755 GIT binary patch delta 3643 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 T9%$@zt;)?e{os(Opt|l~>RkoP diff --git a/src/android/resources/lib/x86_64/libscrypt.so b/src/android/resources/lib/x86_64/libscrypt.so index 17ea6d909e6590b963e0a859d316a4684b2f30e9..f9459ee13d69eeabc050fae6fe4b922c878de9e9 100755 GIT binary patch delta 5629 zcma)A4OA0X7M>XbM1+}uioZx|gB3*y%D>tsnCO5(DSvh?ih&r#6+=VZ>RD@W0n0Q5 zW1rjOIo)4TK;Hh-iYJ#ic)>3S(v-i!sQM6m@JLl!T z``z!|_uhSX-sDZoyL8J*+LugQw@!ArODL&i6G>@godyvBb=eYGUsn5|)P~8rc8V;O zehjF%pO5tOk$#G#FaZ}L)6}v`6@BHhsi56jECUbA-GsLr<* zR17L$<}%uR^eVG7xo4E@A_)%z1woCYA}LLRq*7h7px#7Z(j(pP5o-^znu)c8;QH}0 zpe7^Y-q@Q#E8~r_pw1C|&ukf(OYk0oQ%}o)kNCMR;S{<;$GX2E9G^kvJViJR><%6) zkSF7Ta9Iu`cmpr%1g0hu+(+ znl*Ox8`ZW5uuZFXpt$hN0xA~fFpkV)^n=r)hJcRqZWz?zP)9o_W*fTZVP9Y-&;N78e#j)M@| zA?eexjvthePtqr29S0-SAd0y#zyu6LVxUeUjKMnIs?ah?kHb2SMyLpM-aC5;03jP1 zqE3jpY^NwdE`lL68O=~=u;n z*)NfAWbST%9o;aM^so+`_Xr(_wED9foMu{3hoQwHqt(}{mh;E`@*NK2W0 zMV2uaWf}fi26}NsJM%*tN{b(swDP7XHV1@*T=TP#HN5A5?g;E%&8Bm=wBX4Bou~jJJUyb6>~Y?*Kb2ok}ve89@6q zF0ly)p(tZ%887@$!V6#Xo=DO693)}d8D98;7j9Updw7qT5`Fk&H#cA6+Jcb6yqDMT z-VwG%l$+vnPV?TFRf{Ofz`fSV=N#cshe3UkYkC=o#>P7wxA`S#nY|WWUs@MVg6q@4 zzi8|TsX)u1W?)(e4ehBaXq$wScJ9Wdj?1e16a1QUs9?_>#~TmR7H{~qavWdV5eT?j zf7;H~e-6eM&V+%khY`9VPhL0;n&UfAj=^@{wsUt5LmRee0OXxd?3`N_#W!|nOgW!A zcN%kUaZT^QqiU%>naAymRtujR0%D{ga3hSq-S}l<@@?-%y0OD*%(*kCC0fn3Z3He~ zEdte@Z4|nUf!mSBKq$;acLCd!+=aO<(b?XO40Pezitf=L%?^{;6CRVT!fbcjEu1{k zTpsN_Tyoy|nCu9Nz5Qp|Zh4)N5`ERr(lOiQovSwI9OBw$0==+00LPNHjG}Phsh
K;WFIvb$VNQr}ZXP<(U1HQE9X z>3&EYiWfeXpIoEp!+$QG=e^;FN+@cHvErc7yFn+W_4Du)afv4QXYwfT)A`0un$Nkr z_VcUT&1sk5aeoQiTy3@Ae=LpVY3_irEMNGB_h!t|-a0Rea?-Ghj!Ks0&4wGc9SU@UNVYZ^XKU`QTjpn+Iqym7w+gv7YSxHR-_uPAbf z4G=tVY10irzYEY0$aVM0!PCHkgKmp7@Q8oQgoT5~$9>hIzW{A;h!&*<@&(aYZWcO? zWjH>^;jH~fiAgwy`Rzduoade;&*&$IRX}h2_AS!$ zo>@9@7qp=GF*(d%ulS!GbD3toviNhxF=LsIqyE`hLm5Wbg$i^juXAagYuDt$ z#^JIcMe9t_)}?4|zqBl0ldDa#r3|WY+~a$f7Vce+2mECH*pWQK>Y6GiTEegevxm&_FX9aYU+ zzyv--@6B7_P62xbJVEQa;4i%jlss0`${5*Eo5M`3wow&!GAxQ6#j~0`R&9i<$}FI? zV*UwH?1DDtw=pJmlsC-6YFkzF*-4wj=dk+5h(gxDY-06BcG5yto5zjar;Y+@m)%==OOAELJ1_KzRZwJ8N!pvhwwS}2ktyh)DPHGJ|vHHysCN{eqfqqeh^Wa{=t3M8Sdq4Vber`lG1Wf%cnqE*a zqyn1f|0ariP;CgI^^Cu0{u2-W{FYv<+~$?FE4O&%(thufP6!Yc zscd)15^oAFeX@|gN#G_QiH;VIXWAoBZ{bq6bmIh6xgC2U18~8ah|2(pK7pws(opop z59w78>5hl=7l}?T*Tbj=0^m<2xGbwhM;DA|T53`6f_E8T?bc24#pU=`3&l?4uZY}C zMca!t^Z`^;oEp^* z?-g7iYCDTFV|je-hN8$m6e>=QH4yiT+=G%!Qsb0;R3twKtty!oXTS#r6h(H@=pBI7 z3uIW4O)At|GA;H;A01J0X=;@60chD0R8^W8rF{3PTY`3$X2!PE%C1_-7f%&BO%FqN zO2@_dh(-ApN-=11S?UmyIKE0$RhFe8+V)D>%S!a;GQEa;5TcgJU;|2Hz-3uNEHN|? k12qZtmW@Yz`DiskCQ74kC{Lo7p`GQ=DDcM;JgYeRe->13NB{r; delta 3556 zcmZ`+4Nz3q6@Kpl%a6FbVEB=L^=%4>vKSzQ0m72Syu}3<(P~tbz=9^Vm0H@#OlfyJ z{0z_4xbdV3GjST?kW@3&IJ34fmdv13!z6>nNG%PH;!LZ%BwCWThGdMd=e~Qdp=Nq! z?tb_C&OP^@`}5wr+jmjyJ0bdW#QK+V_j=X|x|J{#%#@1=1}yEhl(#qjFPg(B=g8wE zlu6tGiyL5Z9Op>KXdDZoC>LD+=x~Q)eXxcK597q3WD<7xATBg6obU)MiSjXXpnB+Oh zyji8R`S(~R?=#(1M)i>hiWiw~uA-dD!VRWpF?~OE3;#ki3!iJ=CMGcWn(C?FaTsu# zGyt}S?}wa-!*D)gO?4c$PiCYlwu#g=!62gou_hKxMFwTz>-+4U%eO`7{xb9~Q-}jK-&vbvI;L*F}0epjn zCOQ(=Irs0RI!TsHliNwAlgY4M(_N<*=iZ6yC^P|SuB0*>~?HWZX z{aO*snA40SRJwuE;!{Ns6PIRug-Vx6tNlfR!nlvZjN=6lI!ixW0E-jS5kSe$8bl+qY4n(?`YBTM-jAYufjRvGQ6u{3DmR6TgYOyjoS;vxlA5 z61160R?fHK&js=`PDa{G{pGt@`<)acHd|p=;%Vs@d9W;LiRFdQHLYhv9X0jT<0(;m z!}1vJUGT>!6EZ@GJMc_WoS4`=r)eMP?}|T?oeo{QuW7+r@Fu5uve3nw>&~DNmC&2m zg0_8)w2jd_NX0Ix*o$J@YEve8Q44}?v!Y(Hec!gpp^n=&I@Eic8Wi=ia?mZGR(z3m z)h-v>Ri|uK)Qxh9=HG&6(y88Ys<%|TN6vQm!euHJe5|O~bXm@$DtRRrd`ufV)C=E= z&X!@h4~JIN^G;O@uKXv?qUW}PtI>TO<=URRrtT}m-!o$BUPaaivxrjESzov8Mct`> zskAudJde`SA!pltn4Pl)^K`16vRMt6gDL+et4jtn_520{e5dsBFgwlf#jLPnhx$QB z8foEBr+f!=H_7!rZG#UQ@x4c$SjE>NmpIigbPstWW3C;^#OdLxfa>z3xSVq(E< z80tegp&8|_`NWRouKCoC*sl3l)ZRtyr;%9kmtc+LLDR-wHCKCREuImqhAI&G9ygpZ z2qO09mgf{-`iW|AWvy891B}KU#vv77nT-AIehPZCo{-9K2hL{Q6s1j11&%M5QlHp%H7g{C1A9@DN2ry;P+Llq?8qbzgIP)~Z7al*g?cO^H=;YSWTQ^LqTGn)#!`v;xCB3PCBebE$E1-_I9FFES3zqC{t&4;9FWAck(RmQA?;nl|M0}*zkwbx)XmUKlbMz0uVhjdq_VF;sM zxCB+M<%UVD&Rl}$T{X*PJSFY8V{3U9EQvDIkD>0TiQINQZ5TvpVh&2{*BGv1b?gh+ zS6`EnhaZBHc}>HU`M}7v#*Vsm9zLlrHFRUuI}a%vYN98xIy0CN+mT!Mw(+W}BgP4ZciReTeLUa?3-=9;6W#=?4{2TO*V+>**F2)ezFybWQkc}F4&fW>D&n3mF$Ra$I(rkuf&DOX+ za$i8>I0Ye$X<}n>9Dtmb{CIv_MoA!XV=hv_Rl69E{RLvo;xj`|F_})dFDjOZOxBn zr^UY>np+