mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Import native code changes from Mike Mohr.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@ build.properties
|
|||||||
local.properties
|
local.properties
|
||||||
bin
|
bin
|
||||||
gen
|
gen
|
||||||
|
obj
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ Brian Pellin
|
|||||||
|
|
||||||
Achim Weimert
|
Achim Weimert
|
||||||
Johan Berts - search patches
|
Johan Berts - search patches
|
||||||
|
Mike Mohr - Better native code for aes and sha
|
||||||
Tobias Selig - icon support
|
Tobias Selig - icon support
|
||||||
Tolga Onbay - password generator
|
Tolga Onbay - password generator
|
||||||
|
|
||||||
|
|||||||
25
LICENSE
25
LICENSE
@@ -261,3 +261,28 @@ no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is
|
|||||||
included in the section entitled "GNU Free Documentation License".
|
included in the section entitled "GNU Free Documentation License".
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Many files under jni/final_key/ are coverage by the following license:
|
||||||
|
|
||||||
|
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||||
|
|
||||||
|
LICENSE TERMS
|
||||||
|
|
||||||
|
The redistribution and use of this software (with or without changes)
|
||||||
|
is allowed without the payment of fees or royalties provided that:
|
||||||
|
|
||||||
|
1. source code distributions include the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer;
|
||||||
|
|
||||||
|
2. binary distributions include the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer in their documentation;
|
||||||
|
|
||||||
|
3. the name of the copyright holder is not used to endorse products
|
||||||
|
built using this software without specific written permission.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
|
||||||
|
This software is provided 'as is' with no explicit or implied warranties
|
||||||
|
in respect of its properties, including, but not limited to, correctness
|
||||||
|
and/or fitness for purpose.
|
||||||
|
|
||||||
|
|||||||
4
README
4
README
@@ -5,6 +5,4 @@ Build instructions:
|
|||||||
c. Move the KeePassDroid git root to ${ndk-root}/apps/KeePassDroid/project
|
c. Move the KeePassDroid git root to ${ndk-root}/apps/KeePassDroid/project
|
||||||
d. cp -a ${ndk-root}/apps/KeePassDroid/project/jni_root ${ndk-root}/apps/KeePassDroid
|
d. cp -a ${ndk-root}/apps/KeePassDroid/project/jni_root ${ndk-root}/apps/KeePassDroid
|
||||||
|
|
||||||
2. Run prep-build.sh from ${ndk-root}/apps/KeePassDroid to download, unpack, and patch the openssl sources.
|
2. At ${ndk-root} run 'make APP=KeePassDroid' to build the native sources.
|
||||||
|
|
||||||
3. At ${ndk-root} run 'make APP=KeePassDroid' to build the native sources.
|
|
||||||
|
|||||||
21
jni/aes/.gitignore
vendored
Normal file
21
jni/aes/.gitignore
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
aes_amd64.asm
|
||||||
|
aescpp.h
|
||||||
|
aescrypt.c
|
||||||
|
aes.h
|
||||||
|
aeskey.c
|
||||||
|
aes_modes.c
|
||||||
|
aesopt.h
|
||||||
|
aestab.c
|
||||||
|
aestab.h
|
||||||
|
aes.txt
|
||||||
|
aes_via_ace.h
|
||||||
|
aes_x86_v1.asm
|
||||||
|
aes_x86_v2.asm
|
||||||
|
aesxam.c
|
||||||
|
brg_endian.h
|
||||||
|
brg_types.h
|
||||||
|
rfc3686.c
|
||||||
|
tablegen.c
|
||||||
|
vbaxam.doc
|
||||||
|
vb.txt
|
||||||
|
via_ace.txt
|
||||||
13
jni/aes/Android.mk
Normal file
13
jni/aes/Android.mk
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := aes
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
aescrypt.c \
|
||||||
|
aeskey.c \
|
||||||
|
aes_modes.c \
|
||||||
|
aestab.c
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
@@ -4,11 +4,12 @@ include $(CLEAR_VARS)
|
|||||||
|
|
||||||
LOCAL_MODULE := final-key
|
LOCAL_MODULE := final-key
|
||||||
|
|
||||||
LOCAL_SRC_FILES := final_key.c aes.c
|
LOCAL_SRC_FILES := \
|
||||||
|
kpd_jni.c
|
||||||
|
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../openssl-0.9.8l/include
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../sha $(LOCAL_PATH)/../aes
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := openssl-crypto
|
LOCAL_STATIC_LIBRARIES := aes sha
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/aes.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
|
|
||||||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "KeePassDroidNative", __VA_ARGS__)
|
|
||||||
#define LOGD(...)
|
|
||||||
//#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "KeePassDroidNative", __VA_ARGS__)
|
|
||||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "KeePassDroidNative", __VA_ARGS__)
|
|
||||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , "KeePassDroidNative", __VA_ARGS__)
|
|
||||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "KeePassDroidNative", __VA_ARGS__)
|
|
||||||
|
|
||||||
jlong Java_com_keepassdroid_crypto_NativeAESCipherSpi_nativeInit(JNIEnv *env,
|
|
||||||
jobject this, jboolean encrypt, jbyteArray key, jbyteArray iv,
|
|
||||||
jboolean padding) {
|
|
||||||
|
|
||||||
LOGD("1");
|
|
||||||
// Convert keys to c
|
|
||||||
jsize key_len = (*env)->GetArrayLength(env, key);
|
|
||||||
char *c_key = (char *) malloc(key_len);
|
|
||||||
(*env)->GetByteArrayRegion(env, key, 0, key_len, c_key);
|
|
||||||
LOGD("2: Keylen: %d", key_len);
|
|
||||||
|
|
||||||
|
|
||||||
// Covert iv to c
|
|
||||||
jsize iv_len = (*env)->GetArrayLength(env, iv);
|
|
||||||
char *c_iv = (char *) malloc(iv_len);
|
|
||||||
(*env)->GetByteArrayRegion(env, iv, 0, iv_len, c_iv);
|
|
||||||
LOGD("3: IvLen: %d", iv_len);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *) malloc(sizeof(EVP_CIPHER_CTX));
|
|
||||||
LOGD("3.5: %d", sizeof(EVP_CIPHER_CTX));
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_init(ctx);
|
|
||||||
EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, c_key, c_iv, encrypt);
|
|
||||||
|
|
||||||
LOGD("4");
|
|
||||||
if ( padding ) {
|
|
||||||
EVP_CIPHER_CTX_set_padding(ctx, 1);
|
|
||||||
} else {
|
|
||||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGD("5");
|
|
||||||
// Free allocated memory
|
|
||||||
free(c_iv);
|
|
||||||
free(c_key);
|
|
||||||
|
|
||||||
LOGD("6: ctxPtr=%d",ctx);
|
|
||||||
|
|
||||||
return (jlong) ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Java_com_keepassdroid_crypto_NativeAESCipherSpi_nativeCleanup(JNIEnv *env,
|
|
||||||
jclass this, jlong ctxPtr) {
|
|
||||||
|
|
||||||
LOGD("cleanup");
|
|
||||||
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *) ctxPtr;
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_cleanup(ctx);
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
jint Java_com_keepassdroid_crypto_NativeAESCipherSpi_nativeUpdate(JNIEnv *env,
|
|
||||||
jobject this, jlong ctxPtr, jbyteArray input, jint inputOffset,
|
|
||||||
jint inputLen, jbyteArray output, jint outputOffset, jint outputSize) {
|
|
||||||
|
|
||||||
|
|
||||||
LOGD("InputSize: %d; InputOffset: %d, OutputOffset: %d, OutputSize: %d", inputLen, inputOffset,
|
|
||||||
outputOffset, outputSize);
|
|
||||||
if ( inputLen == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *c_input = (char *) malloc(inputLen);
|
|
||||||
|
|
||||||
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, c_input);
|
|
||||||
|
|
||||||
int outLen;
|
|
||||||
char *c_output;
|
|
||||||
|
|
||||||
// Worst case is all full blocks with 1 byte on the left and right
|
|
||||||
//int max_update_size = (((inputLen - 2) / AES_BLOCK_SIZE) + 2) * AES_BLOCK_SIZE;
|
|
||||||
c_output = (char *) malloc(outputSize);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *) ctxPtr;
|
|
||||||
LOGD("Pre: ctxPtr=%d", ctx);
|
|
||||||
EVP_CipherUpdate(ctx, c_output, &outLen, c_input, inputLen);
|
|
||||||
LOGD("Post");
|
|
||||||
|
|
||||||
/* output can differ on final
|
|
||||||
if ( outLen != ((int) outputSize) ) {
|
|
||||||
LOGD("Outsize differs: %d", outLen);
|
|
||||||
free(c_output);
|
|
||||||
free(c_input);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOGD("PreOut: outputSize=%d, outputOffset=%d, OutLen=%d", outputSize, outputOffset, outLen);
|
|
||||||
(*env)->SetByteArrayRegion(env, output, outputOffset, outLen, c_output);
|
|
||||||
|
|
||||||
free(c_output);
|
|
||||||
free(c_input);
|
|
||||||
LOGD("PostOut");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (jint) outLen; // I think jint should always be bigger than int
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
jint Java_com_keepassdroid_crypto_NativeAESCipherSpi_nativeDoFinal(JNIEnv *env,
|
|
||||||
jobject this, jlong ctxPtr, jbyteArray output, jint outputOffset,
|
|
||||||
jint outputSize) {
|
|
||||||
|
|
||||||
LOGD("outputOffset=%d", outputOffset);
|
|
||||||
char *c_output = (char *) malloc(outputSize);
|
|
||||||
|
|
||||||
int outLen;
|
|
||||||
EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *) ctxPtr;
|
|
||||||
EVP_CipherFinal_ex(ctx, c_output, &outLen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
if ( outLen != ((int) outputSize) ) {
|
|
||||||
free(c_output);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
LOGD("Final: OutputLen=%d, outputOffset=%d", outLen, (int)outputOffset);
|
|
||||||
|
|
||||||
(*env)->SetByteArrayRegion(env, output, outputOffset, outLen, c_output);
|
|
||||||
|
|
||||||
free(c_output);
|
|
||||||
|
|
||||||
return (jint) outLen;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/aes.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BLOCK_SIZE AES_BLOCK_SIZE * 2
|
|
||||||
|
|
||||||
/* Prepare the final key */
|
|
||||||
jbyteArray Java_com_keepassdroid_crypto_finalkey_NativeFinalKey_nativeTransformMasterKey(JNIEnv *env, jobject this,
|
|
||||||
jbyteArray seed, jbyteArray key, jint rounds) {
|
|
||||||
|
|
||||||
char cSeed[BLOCK_SIZE];
|
|
||||||
char key1[BLOCK_SIZE];
|
|
||||||
char key2[BLOCK_SIZE];
|
|
||||||
|
|
||||||
// Verify length of key and seed
|
|
||||||
if ( (*env)->GetArrayLength(env, seed) != BLOCK_SIZE ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ( (*env)->GetArrayLength(env, key) != BLOCK_SIZE ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Test to see if GetByteArrayElements is cheaper
|
|
||||||
(*env)->GetByteArrayRegion(env, seed, 0, BLOCK_SIZE, cSeed);
|
|
||||||
(*env)->GetByteArrayRegion(env, key, 0, BLOCK_SIZE, key1);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX ctx;
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_init(&ctx);
|
|
||||||
EVP_EncryptInit_ex(&ctx, EVP_aes_256_ecb(), NULL, cSeed, NULL);
|
|
||||||
|
|
||||||
int c_len; // Not really needed, we always work at even block sizes here
|
|
||||||
int i;
|
|
||||||
char flip = 0;
|
|
||||||
for (i = 0; i < rounds; i++) {
|
|
||||||
// Toggle between arrays as source and destination
|
|
||||||
if ( flip ) {
|
|
||||||
EVP_EncryptUpdate(&ctx, key1, &c_len, key2, BLOCK_SIZE);
|
|
||||||
flip = 0;
|
|
||||||
} else {
|
|
||||||
EVP_EncryptUpdate(&ctx, key2, &c_len, key1, BLOCK_SIZE);
|
|
||||||
flip = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
|
||||||
|
|
||||||
jbyteArray result = (*env)->NewByteArray(env, BLOCK_SIZE);
|
|
||||||
|
|
||||||
|
|
||||||
// Need to take the SHA1 digest
|
|
||||||
EVP_MD_CTX digestCtx;
|
|
||||||
EVP_MD_CTX_init(&digestCtx);
|
|
||||||
|
|
||||||
EVP_DigestInit_ex(&digestCtx, EVP_sha256(), NULL);
|
|
||||||
|
|
||||||
if ( flip ) {
|
|
||||||
EVP_DigestUpdate(&digestCtx, key2, BLOCK_SIZE);
|
|
||||||
EVP_DigestFinal_ex(&digestCtx, key1, NULL);
|
|
||||||
flip = 0;
|
|
||||||
} else {
|
|
||||||
EVP_DigestUpdate(&digestCtx, key1, BLOCK_SIZE);
|
|
||||||
EVP_DigestFinal_ex(&digestCtx, key2, NULL);
|
|
||||||
flip = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_MD_CTX_cleanup(&digestCtx);
|
|
||||||
|
|
||||||
if ( flip ) {
|
|
||||||
(*env)->SetByteArrayRegion(env, result, 0, BLOCK_SIZE, key2);
|
|
||||||
} else {
|
|
||||||
(*env)->SetByteArrayRegion(env, result, 0, BLOCK_SIZE, key1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For testing purposes only */
|
|
||||||
jbyteArray Java_com_keepassdroid_crypto_finalkey_NativeFinalKey_nativeReflect(JNIEnv *env, jclass this,
|
|
||||||
jbyteArray key) {
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
428
jni/final_key/kpd_jni.c
Normal file
428
jni/final_key/kpd_jni.c
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
/*
|
||||||
|
This is a JNI wrapper for AES & SHA source code on Android.
|
||||||
|
Copyright (C) 2010 Michael Mohr
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include "aes.h"
|
||||||
|
#include "sha2.h"
|
||||||
|
|
||||||
|
static JavaVM *cached_vm;
|
||||||
|
static jclass bad_arg, no_mem;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ENCRYPTION,
|
||||||
|
DECRYPTION,
|
||||||
|
FINALIZED
|
||||||
|
} edir_t;
|
||||||
|
|
||||||
|
typedef struct _aes_encryption_state {
|
||||||
|
edir_t direction;
|
||||||
|
uint32_t cache_len;
|
||||||
|
uint8_t iv[16], cache[16];
|
||||||
|
aes_encrypt_ctx ctx[1];
|
||||||
|
} aes_encryption_state;
|
||||||
|
|
||||||
|
typedef struct _aes_decryption_state {
|
||||||
|
edir_t direction;
|
||||||
|
uint32_t cache_len;
|
||||||
|
uint8_t iv[16], cache[16];
|
||||||
|
aes_decrypt_ctx ctx[1];
|
||||||
|
} aes_decryption_state;
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *reserved ) {
|
||||||
|
JNIEnv *env;
|
||||||
|
jclass cls;
|
||||||
|
|
||||||
|
cached_vm = vm;
|
||||||
|
if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6))
|
||||||
|
return JNI_ERR;
|
||||||
|
|
||||||
|
cls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
|
||||||
|
if( cls == NULL )
|
||||||
|
return JNI_ERR;
|
||||||
|
bad_arg = (*env)->NewWeakGlobalRef(env, cls);
|
||||||
|
if( bad_arg == NULL )
|
||||||
|
return JNI_ERR;
|
||||||
|
|
||||||
|
cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
|
||||||
|
if( cls == NULL )
|
||||||
|
return JNI_ERR;
|
||||||
|
no_mem = (*env)->NewWeakGlobalRef(env, cls);
|
||||||
|
if( no_mem == NULL )
|
||||||
|
return JNI_ERR;
|
||||||
|
|
||||||
|
aes_init();
|
||||||
|
|
||||||
|
return JNI_VERSION_1_6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// called on garbage collection
|
||||||
|
JNIEXPORT void JNICALL JNI_OnUnload( JavaVM *vm, void *reserved ) {
|
||||||
|
JNIEnv *env;
|
||||||
|
if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(*env)->DeleteWeakGlobalRef(env, bad_arg);
|
||||||
|
(*env)->DeleteWeakGlobalRef(env, no_mem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nEncryptInit(JNIEnv *env, jobject this, jbyteArray key, jbyteArray iv) {
|
||||||
|
unsigned char ckey[32];
|
||||||
|
aes_encryption_state *state;
|
||||||
|
jint key_len = (*env)->GetArrayLength(env, key);
|
||||||
|
jint iv_len = (*env)->GetArrayLength(env, iv);
|
||||||
|
|
||||||
|
if( ! ( key_len == 16 || key_len == 24 || key_len == 32 ) || iv_len != 16 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid length of key or iv");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = (aes_encryption_state *)malloc(sizeof(aes_encryption_state));
|
||||||
|
if( state == NULL ) {
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Cannot allocate memory for the encryption state");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(state, 0, sizeof(aes_encryption_state));
|
||||||
|
|
||||||
|
(*env)->GetByteArrayRegion(env, key, (jint)0, key_len, (jbyte *)ckey);
|
||||||
|
|
||||||
|
state->direction = ENCRYPTION;
|
||||||
|
(*env)->GetByteArrayRegion(env, iv, (jint)0, iv_len, (jbyte *)state->iv);
|
||||||
|
aes_encrypt_key(ckey, key_len, state->ctx);
|
||||||
|
|
||||||
|
return (jlong)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nDecryptInit(JNIEnv *env, jobject this, jbyteArray key, jbyteArray iv) {
|
||||||
|
unsigned char ckey[32];
|
||||||
|
aes_decryption_state *state;
|
||||||
|
jint key_len = (*env)->GetArrayLength(env, key);
|
||||||
|
jint iv_len = (*env)->GetArrayLength(env, iv);
|
||||||
|
|
||||||
|
if( ! ( key_len == 16 || key_len == 24 || key_len == 32 ) || iv_len != 16 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid length of key or iv");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = (aes_decryption_state *)malloc(sizeof(aes_decryption_state));
|
||||||
|
if( state == NULL ) {
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Cannot allocate memory for the decryption state");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(state, 0, sizeof(aes_decryption_state));
|
||||||
|
|
||||||
|
(*env)->GetByteArrayRegion(env, key, (jint)0, key_len, (jbyte *)ckey);
|
||||||
|
|
||||||
|
state->direction = DECRYPTION;
|
||||||
|
(*env)->GetByteArrayRegion(env, iv, (jint)0, iv_len, (jbyte *)state->iv);
|
||||||
|
aes_decrypt_key(ckey, key_len, state->ctx);
|
||||||
|
|
||||||
|
return (jlong)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nCleanup(JNIEnv *env, jclass this, jlong state) {
|
||||||
|
if( state == 0 || state == -1 ) return;
|
||||||
|
free((void *)state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO:
|
||||||
|
---Performance--- [low priority]
|
||||||
|
Align memory with posix_memalign() (does Android support this?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nEncryptUpdate(JNIEnv *env, jobject this,
|
||||||
|
jlong state, jbyteArray input, jint inputOffset, jint inputLen, jbyteArray output, jint outputOffset, jint outputSize) {
|
||||||
|
int32_t outLen, trailing_bytes, input_plus_cache_len;
|
||||||
|
uint8_t *c_input, *c_output;
|
||||||
|
aes_encryption_state *c_state;
|
||||||
|
|
||||||
|
// step 1: first, some housecleaning
|
||||||
|
if( !inputLen || state <= 0 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid input length or state");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_state = (aes_encryption_state *)state;
|
||||||
|
if( c_state->direction != ENCRYPTION ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Decryption state passed to encryption function");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
input_plus_cache_len = inputLen + c_state->cache_len;
|
||||||
|
if( input_plus_cache_len < 16 ) {
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)(c_state->cache + c_state->cache_len));
|
||||||
|
c_state->cache_len = input_plus_cache_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
trailing_bytes = input_plus_cache_len & 15; // mask bottom 4 bits
|
||||||
|
outLen = (input_plus_cache_len - trailing_bytes); // output length is now aligned to a 16-byte boundary
|
||||||
|
if( outLen > outputSize ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Output buffer does not have enough space");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: allocate memory to hold input and output data
|
||||||
|
c_input = (uint8_t *)malloc(input_plus_cache_len);
|
||||||
|
if( c_input == NULL ) {
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Unable to allocate heap space for encryption input");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_output = (uint8_t *)malloc(outLen);
|
||||||
|
if( c_output == NULL ) {
|
||||||
|
free(c_input);
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Unable to allocate heap space for encryption output");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3: copy data from Java and encrypt it
|
||||||
|
if( c_state->cache_len ) {
|
||||||
|
memcpy(c_input, c_state->cache, c_state->cache_len);
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)(c_input + c_state->cache_len));
|
||||||
|
} else {
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)c_input);
|
||||||
|
}
|
||||||
|
if( aes_cbc_encrypt(c_input, c_output, outLen, c_state->iv, c_state->ctx) != EXIT_SUCCESS ) {
|
||||||
|
free(c_input);
|
||||||
|
free(c_output);
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Failed to encrypt input data"); // FIXME: get a better exception class for this...
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
(*env)->SetByteArrayRegion(env, output, outputOffset, outLen, (jbyte *)c_output);
|
||||||
|
|
||||||
|
// step 4: cleanup and return
|
||||||
|
if( trailing_bytes ) {
|
||||||
|
c_state->cache_len = trailing_bytes; // set new cache length
|
||||||
|
memcpy(c_state->cache, (c_input + outLen), trailing_bytes); // cache overflow bytes for next call
|
||||||
|
} else {
|
||||||
|
c_state->cache_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(c_input);
|
||||||
|
free(c_output);
|
||||||
|
|
||||||
|
return outLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
nDecryptUpdate: decrypt a block of data. The input need not be a multiple of the AES block size.
|
||||||
|
Parameters:
|
||||||
|
state - a saved pointer obtained from a call to nDecryptInit()
|
||||||
|
input - an allocated Java byte[] object containing the input data
|
||||||
|
inputOffset - encrypted data will be decrypted starting at inputOffset bytes from the beginning of input
|
||||||
|
inputLen - a limit on how many bytes will be encrypted from input
|
||||||
|
output - analogous to input
|
||||||
|
outputOffset - analogous inputOffset
|
||||||
|
outputSize - a limit to how many bytes will be accepted for output
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nDecryptUpdate(JNIEnv *env, jobject this,
|
||||||
|
jlong state, jbyteArray input, jint inputOffset, jint inputLen, jbyteArray output, jint outputOffset, jint outputSize) {
|
||||||
|
int32_t outLen, trailing_bytes, input_plus_cache_len;
|
||||||
|
uint8_t *c_input, *c_output;
|
||||||
|
aes_decryption_state *c_state;
|
||||||
|
|
||||||
|
// step 1: first, some housecleaning
|
||||||
|
if( !inputLen || state <= 0 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid input length or state");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_state = (aes_decryption_state *)state;
|
||||||
|
if( c_state->direction != DECRYPTION ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Encryption state passed to decryption function");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
input_plus_cache_len = inputLen + c_state->cache_len;
|
||||||
|
if( input_plus_cache_len < 16 ) {
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)(c_state->cache + c_state->cache_len));
|
||||||
|
c_state->cache_len = input_plus_cache_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
trailing_bytes = input_plus_cache_len & 15; // mask bottom 4 bits
|
||||||
|
outLen = (input_plus_cache_len - trailing_bytes); // output length is now aligned to a 16-byte boundary
|
||||||
|
if( outLen > outputSize ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Output buffer does not have enough space");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: allocate memory to hold input and output data
|
||||||
|
c_input = (uint8_t *)malloc(input_plus_cache_len);
|
||||||
|
if( c_input == NULL ) {
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Unable to allocate heap space for decryption input");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_output = (uint8_t *)malloc(outLen);
|
||||||
|
if( c_output == NULL ) {
|
||||||
|
free(c_input);
|
||||||
|
(*env)->ThrowNew(env, no_mem, "Unable to allocate heap space for decryption output");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3: copy data from Java and decrypt it
|
||||||
|
if( c_state->cache_len ) {
|
||||||
|
memcpy(c_input, c_state->cache, c_state->cache_len);
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)(c_input + c_state->cache_len));
|
||||||
|
} else {
|
||||||
|
(*env)->GetByteArrayRegion(env, input, inputOffset, inputLen, (jbyte *)c_input);
|
||||||
|
}
|
||||||
|
if( aes_cbc_decrypt(c_input, c_output, outLen, c_state->iv, c_state->ctx) != EXIT_SUCCESS ) {
|
||||||
|
free(c_input);
|
||||||
|
free(c_output);
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Failed to decrypt input data"); // FIXME: get a better exception class for this...
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
(*env)->SetByteArrayRegion(env, output, outputOffset, outLen, (jbyte *)c_output);
|
||||||
|
|
||||||
|
// step 4: cleanup and return
|
||||||
|
if( trailing_bytes ) {
|
||||||
|
c_state->cache_len = trailing_bytes; // set new cache length
|
||||||
|
memcpy(c_state->cache, (c_input + outLen), trailing_bytes); // cache overflow bytes for next call
|
||||||
|
} else {
|
||||||
|
c_state->cache_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(c_input);
|
||||||
|
free(c_output);
|
||||||
|
|
||||||
|
return outLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
nEncryptFinal: encrypt any data remaining in the state's block cache and perform PKCS#5 padding
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nEncryptFinal(JNIEnv *env, jobject this,
|
||||||
|
jlong state, jboolean doPadding, jbyteArray output, jint outputOffset, jint outputSize) {
|
||||||
|
uint32_t pad;
|
||||||
|
uint8_t final_output[16] __attribute__ ((aligned (16)));
|
||||||
|
aes_encryption_state *c_state;
|
||||||
|
|
||||||
|
if( outputSize < 16 || state <= 0 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid state or outputSize too small");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_state = (aes_encryption_state *)state;
|
||||||
|
if( c_state->direction != ENCRYPTION ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Cannot finalize the passed state identifier");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow fetching of remaining bytes from cache
|
||||||
|
if( !doPadding ) {
|
||||||
|
(*env)->SetByteArrayRegion(env, output, outputOffset, c_state->cache_len, (jbyte *)c_state->cache);
|
||||||
|
c_state->direction = FINALIZED;
|
||||||
|
return c_state->cache_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( c_state->cache_len ) {
|
||||||
|
pad = 16 - c_state->cache_len;
|
||||||
|
memset(c_state->cache + c_state->cache_len, pad, pad);
|
||||||
|
} else {
|
||||||
|
memset(c_state->cache, 0x10, 16);
|
||||||
|
}
|
||||||
|
if( aes_cbc_encrypt(c_state->cache, final_output, 16, c_state->iv, c_state->ctx) != EXIT_SUCCESS ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Failed to encrypt final data block"); // FIXME: get a better exception class for this...
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
(*env)->SetByteArrayRegion(env, output, outputOffset, 16, (jbyte *)final_output);
|
||||||
|
c_state->direction = FINALIZED;
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_keepassdroid_crypto_NativeAESCipherSpi_nDecryptFinal(JNIEnv *env, jobject this,
|
||||||
|
jlong state, jboolean doPadding, jbyteArray output, jint outputOffset, jint outputSize) {
|
||||||
|
aes_decryption_state *c_state;
|
||||||
|
|
||||||
|
if( outputSize < 16 || state <= 0 ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Invalid state or outputSize too small");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c_state = (aes_decryption_state *)state;
|
||||||
|
if( c_state->direction != DECRYPTION ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "Cannot finalize the passed state identifier");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow fetching of remaining bytes from cache
|
||||||
|
if( !doPadding ) {
|
||||||
|
(*env)->SetByteArrayRegion(env, output, outputOffset, c_state->cache_len, (jbyte *)c_state->cache);
|
||||||
|
c_state->direction = FINALIZED;
|
||||||
|
return c_state->cache_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: is there anything else to do here?
|
||||||
|
c_state->direction = FINALIZED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MASTER_KEY_SIZE 32
|
||||||
|
JNIEXPORT jbyteArray JNICALL Java_com_keepassdroid_crypto_finalkey_NativeFinalKey_nTransformMasterKey(JNIEnv *env, jobject this, jbyteArray seed, jbyteArray key, jint rounds) {
|
||||||
|
int i, flip = 0;
|
||||||
|
jbyteArray result;
|
||||||
|
aes_encrypt_ctx e_ctx[1] __attribute__ ((aligned (16)));
|
||||||
|
sha256_ctx h_ctx[1] __attribute__ ((aligned (16)));
|
||||||
|
unsigned char c_seed[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
|
||||||
|
unsigned char key1[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
|
||||||
|
unsigned char key2[MASTER_KEY_SIZE] __attribute__ ((aligned (16)));
|
||||||
|
|
||||||
|
// step 1: housekeeping - sanity checks and fetch data from the JVM
|
||||||
|
if( (*env)->GetArrayLength(env, seed) != MASTER_KEY_SIZE ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: the seed is not the correct size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if( (*env)->GetArrayLength(env, key) != MASTER_KEY_SIZE ) {
|
||||||
|
(*env)->ThrowNew(env, bad_arg, "TransformMasterKey: the key is not the correct size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
(*env)->GetByteArrayRegion(env, seed, 0, MASTER_KEY_SIZE, (jbyte *)c_seed);
|
||||||
|
(*env)->GetByteArrayRegion(env, key, 0, MASTER_KEY_SIZE, (jbyte *)key1);
|
||||||
|
|
||||||
|
// step 2: encrypt the hash "rounds" (default: 6000) times
|
||||||
|
aes_encrypt_key(c_seed, MASTER_KEY_SIZE, e_ctx);
|
||||||
|
for (i = 0; i < rounds; i++) {
|
||||||
|
if ( flip ) {
|
||||||
|
aes_ecb_encrypt(key2, key1, MASTER_KEY_SIZE, e_ctx);
|
||||||
|
flip = 0;
|
||||||
|
} else {
|
||||||
|
aes_ecb_encrypt(key1, key2, MASTER_KEY_SIZE, e_ctx);
|
||||||
|
flip = 1;
|
||||||
|
} // if
|
||||||
|
} // for
|
||||||
|
|
||||||
|
// step 3: final SHA256 hash
|
||||||
|
sha256_begin(h_ctx);
|
||||||
|
if( flip ) {
|
||||||
|
sha256_hash(key2, MASTER_KEY_SIZE, h_ctx);
|
||||||
|
sha256_end(key1, h_ctx);
|
||||||
|
flip = 0;
|
||||||
|
} else {
|
||||||
|
sha256_hash(key1, MASTER_KEY_SIZE, h_ctx);
|
||||||
|
sha256_end(key2, h_ctx);
|
||||||
|
flip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 4: send the hash into the JVM
|
||||||
|
result = (*env)->NewByteArray(env, MASTER_KEY_SIZE);
|
||||||
|
if( flip )
|
||||||
|
(*env)->SetByteArrayRegion(env, result, 0, MASTER_KEY_SIZE, (jbyte *)key2);
|
||||||
|
else
|
||||||
|
(*env)->SetByteArrayRegion(env, result, 0, MASTER_KEY_SIZE, (jbyte *)key1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#undef MASTER_KEY_SIZE
|
||||||
13
jni/sha/.gitignore
vendored
Normal file
13
jni/sha/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
brg_endian.h
|
||||||
|
brg_types.h
|
||||||
|
hmac.c
|
||||||
|
hmac.h
|
||||||
|
pwd2key.c
|
||||||
|
pwd2key.h
|
||||||
|
sha1b.c
|
||||||
|
sha1.c
|
||||||
|
sha1.h
|
||||||
|
sha2b.c
|
||||||
|
sha2.c
|
||||||
|
sha2.h
|
||||||
|
shasum.c
|
||||||
14
jni/sha/Android.mk
Normal file
14
jni/sha/Android.mk
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := sha
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
sha1.c \
|
||||||
|
sha2.c \
|
||||||
|
hmac.c
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DUSE_SHA256
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
2
jni_root/.gitignore
vendored
2
jni_root/.gitignore
vendored
@@ -1,2 +1,4 @@
|
|||||||
openssl-0.9.8l.tar.gz
|
openssl-0.9.8l.tar.gz
|
||||||
project
|
project
|
||||||
|
aes-src-29-04-09.zip
|
||||||
|
sha2-07-01-07.zip
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
APP_PROJECT_PATH := $(call my-dir)/project
|
APP_PROJECT_PATH := $(call my-dir)
|
||||||
APP_MODULES := openssl-crypto final-key
|
APP_MODULES := aes sha final-key
|
||||||
|
APP_OPTIM := release
|
||||||
|
APP_ABI := armeabi armeabi-v7a
|
||||||
|
|||||||
@@ -1,302 +0,0 @@
|
|||||||
diff -Nru openssl-0.9.8l.orig/Android.mk openssl-0.9.8l/Android.mk
|
|
||||||
--- openssl-0.9.8l.orig/Android.mk 1969-12-31 18:00:00.000000000 -0600
|
|
||||||
+++ openssl-0.9.8l/Android.mk 2009-12-02 19:19:38.458446809 -0600
|
|
||||||
@@ -0,0 +1,3 @@
|
|
||||||
+# Recursively sources all Android.mk files in subdirs:
|
|
||||||
+include $(call all-subdir-makefiles)
|
|
||||||
+
|
|
||||||
diff -Nru openssl-0.9.8l.orig/crypto/Android.mk openssl-0.9.8l/crypto/Android.mk
|
|
||||||
--- openssl-0.9.8l.orig/crypto/Android.mk 1969-12-31 18:00:00.000000000 -0600
|
|
||||||
+++ openssl-0.9.8l/crypto/Android.mk 2009-12-01 21:02:53.490604631 -0600
|
|
||||||
@@ -0,0 +1,291 @@
|
|
||||||
+LOCAL_PATH := $(call my-dir)
|
|
||||||
+
|
|
||||||
+include $(CLEAR_VARS)
|
|
||||||
+
|
|
||||||
+LOCAL_MODULE := openssl-crypto
|
|
||||||
+
|
|
||||||
+LOCAL_SRC_FILES := \
|
|
||||||
+ cryptlib.c \
|
|
||||||
+ dyn_lck.c \
|
|
||||||
+ mem_clr.c \
|
|
||||||
+ mem.c \
|
|
||||||
+ mem_dbg.c \
|
|
||||||
+ cversion.c \
|
|
||||||
+ ex_data.c \
|
|
||||||
+ tmdiff.c \
|
|
||||||
+ cpt_err.c \
|
|
||||||
+ ebcdic.c \
|
|
||||||
+ uid.c \
|
|
||||||
+ o_time.c \
|
|
||||||
+ o_str.c \
|
|
||||||
+ o_dir.c \
|
|
||||||
+ o_init.c \
|
|
||||||
+ fips_err.c \
|
|
||||||
+ aes/aes_misc.c \
|
|
||||||
+ aes/aes_ecb.c \
|
|
||||||
+ aes/aes_cfb.c \
|
|
||||||
+ aes/aes_ofb.c \
|
|
||||||
+ aes/aes_ctr.c \
|
|
||||||
+ aes/aes_ige.c \
|
|
||||||
+ aes/aes_wrap.c \
|
|
||||||
+ aes/aes_core.c \
|
|
||||||
+ aes/aes_cbc.c \
|
|
||||||
+ evp/encode.c \
|
|
||||||
+ evp/digest.c \
|
|
||||||
+ evp/dig_eng.c \
|
|
||||||
+ evp/evp_enc.c \
|
|
||||||
+ evp/evp_key.c \
|
|
||||||
+ evp/evp_acnf.c \
|
|
||||||
+ evp/evp_cnf.c \
|
|
||||||
+ evp/e_des.c \
|
|
||||||
+ evp/e_bf.c \
|
|
||||||
+ evp/e_idea.c \
|
|
||||||
+ evp/e_des3.c \
|
|
||||||
+ evp/e_camellia.c \
|
|
||||||
+ evp/e_rc4.c \
|
|
||||||
+ evp/e_aes.c \
|
|
||||||
+ evp/names.c \
|
|
||||||
+ evp/e_seed.c \
|
|
||||||
+ evp/e_xcbc_d.c \
|
|
||||||
+ evp/e_rc2.c \
|
|
||||||
+ evp/e_cast.c \
|
|
||||||
+ evp/e_rc5.c \
|
|
||||||
+ evp/enc_min.c \
|
|
||||||
+ evp/m_null.c \
|
|
||||||
+ evp/m_md2.c \
|
|
||||||
+ evp/m_md4.c \
|
|
||||||
+ evp/m_md5.c \
|
|
||||||
+ evp/m_sha.c \
|
|
||||||
+ evp/m_sha1.c \
|
|
||||||
+ evp/m_dss.c \
|
|
||||||
+ evp/m_dss1.c \
|
|
||||||
+ evp/m_mdc2.c \
|
|
||||||
+ evp/m_ripemd.c \
|
|
||||||
+ evp/m_ecdsa.c \
|
|
||||||
+ evp/p_open.c \
|
|
||||||
+ evp/p_seal.c \
|
|
||||||
+ evp/p_sign.c \
|
|
||||||
+ evp/p_verify.c \
|
|
||||||
+ evp/p_lib.c \
|
|
||||||
+ evp/p_enc.c \
|
|
||||||
+ evp/p_dec.c \
|
|
||||||
+ evp/bio_md.c \
|
|
||||||
+ evp/bio_b64.c \
|
|
||||||
+ evp/bio_enc.c \
|
|
||||||
+ evp/evp_err.c \
|
|
||||||
+ evp/e_null.c \
|
|
||||||
+ evp/c_all.c \
|
|
||||||
+ evp/c_allc.c \
|
|
||||||
+ evp/c_alld.c \
|
|
||||||
+ evp/evp_lib.c \
|
|
||||||
+ evp/bio_ok.c \
|
|
||||||
+ evp/evp_pkey.c \
|
|
||||||
+ evp/evp_pbe.c \
|
|
||||||
+ evp/p5_crpt.c \
|
|
||||||
+ evp/p5_crpt2.c \
|
|
||||||
+ evp/e_old.c \
|
|
||||||
+ engine/eng_err.c \
|
|
||||||
+ engine/eng_lib.c \
|
|
||||||
+ engine/eng_list.c \
|
|
||||||
+ engine/eng_init.c \
|
|
||||||
+ engine/eng_ctrl.c \
|
|
||||||
+ engine/eng_table.c \
|
|
||||||
+ engine/eng_pkey.c \
|
|
||||||
+ engine/eng_fat.c \
|
|
||||||
+ engine/eng_all.c \
|
|
||||||
+ engine/tb_rsa.c \
|
|
||||||
+ engine/tb_dsa.c \
|
|
||||||
+ engine/tb_ecdsa.c \
|
|
||||||
+ engine/tb_dh.c \
|
|
||||||
+ engine/tb_ecdh.c \
|
|
||||||
+ engine/tb_rand.c \
|
|
||||||
+ engine/tb_store.c \
|
|
||||||
+ engine/tb_cipher.c \
|
|
||||||
+ engine/tb_digest.c \
|
|
||||||
+ engine/eng_openssl.c \
|
|
||||||
+ engine/eng_cnf.c \
|
|
||||||
+ engine/eng_dyn.c \
|
|
||||||
+ engine/eng_cryptodev.c \
|
|
||||||
+ engine/eng_padlock.c \
|
|
||||||
+ err/err.c \
|
|
||||||
+ err/err_def.c \
|
|
||||||
+ err/err_all.c \
|
|
||||||
+ err/err_prn.c \
|
|
||||||
+ err/err_str.c \
|
|
||||||
+ err/err_bio.c \
|
|
||||||
+ stack/stack.c \
|
|
||||||
+ lhash/lhash.c \
|
|
||||||
+ lhash/lh_stats.c \
|
|
||||||
+ buffer/buffer.c \
|
|
||||||
+ buffer/buf_str.c \
|
|
||||||
+ buffer/buf_err.c \
|
|
||||||
+ rand/md_rand.c \
|
|
||||||
+ rand/randfile.c \
|
|
||||||
+ rand/rand_lib.c \
|
|
||||||
+ rand/rand_eng.c \
|
|
||||||
+ rand/rand_err.c \
|
|
||||||
+ rand/rand_egd.c \
|
|
||||||
+ rand/rand_win.c \
|
|
||||||
+ rand/rand_unix.c \
|
|
||||||
+ rand/rand_os2.c \
|
|
||||||
+ rand/rand_nw.c \
|
|
||||||
+ bio/bio_lib.c \
|
|
||||||
+ bio/bio_cb.c \
|
|
||||||
+ bio/bio_err.c \
|
|
||||||
+ bio/bss_mem.c \
|
|
||||||
+ bio/bss_null.c \
|
|
||||||
+ bio/bss_fd.c \
|
|
||||||
+ bio/bss_file.c \
|
|
||||||
+ bio/bss_sock.c \
|
|
||||||
+ bio/bss_conn.c \
|
|
||||||
+ bio/bf_null.c \
|
|
||||||
+ bio/bf_buff.c \
|
|
||||||
+ bio/b_print.c \
|
|
||||||
+ bio/b_dump.c \
|
|
||||||
+ bio/b_sock.c \
|
|
||||||
+ bio/bss_acpt.c \
|
|
||||||
+ bio/bf_nbio.c \
|
|
||||||
+ bio/bss_log.c \
|
|
||||||
+ bio/bss_bio.c \
|
|
||||||
+ bio/bss_dgram.c \
|
|
||||||
+ objects/o_names.c \
|
|
||||||
+ objects/obj_dat.c \
|
|
||||||
+ objects/obj_lib.c \
|
|
||||||
+ objects/obj_err.c \
|
|
||||||
+ sha/sha_dgst.c \
|
|
||||||
+ sha/sha1dgst.c \
|
|
||||||
+ sha/sha_one.c \
|
|
||||||
+ sha/sha1_one.c \
|
|
||||||
+ sha/sha256.c \
|
|
||||||
+ sha/sha512.c \
|
|
||||||
+ rsa/rsa_eay.c \
|
|
||||||
+ rsa/rsa_gen.c \
|
|
||||||
+ rsa/rsa_lib.c \
|
|
||||||
+ rsa/rsa_sign.c \
|
|
||||||
+ rsa/rsa_saos.c \
|
|
||||||
+ rsa/rsa_err.c \
|
|
||||||
+ rsa/rsa_pk1.c \
|
|
||||||
+ rsa/rsa_ssl.c \
|
|
||||||
+ rsa/rsa_none.c \
|
|
||||||
+ rsa/rsa_oaep.c \
|
|
||||||
+ rsa/rsa_chk.c \
|
|
||||||
+ rsa/rsa_null.c \
|
|
||||||
+ rsa/rsa_pss.c \
|
|
||||||
+ rsa/rsa_x931.c \
|
|
||||||
+ rsa/rsa_x931g.c \
|
|
||||||
+ rsa/rsa_asn1.c \
|
|
||||||
+ rsa/rsa_depr.c \
|
|
||||||
+ rsa/rsa_eng.c \
|
|
||||||
+ bn/bn_add.c \
|
|
||||||
+ bn/bn_div.c \
|
|
||||||
+ bn/bn_exp.c \
|
|
||||||
+ bn/bn_lib.c \
|
|
||||||
+ bn/bn_ctx.c \
|
|
||||||
+ bn/bn_mul.c \
|
|
||||||
+ bn/bn_mod.c \
|
|
||||||
+ bn/bn_print.c \
|
|
||||||
+ bn/bn_rand.c \
|
|
||||||
+ bn/bn_shift.c \
|
|
||||||
+ bn/bn_word.c \
|
|
||||||
+ bn/bn_blind.c \
|
|
||||||
+ bn/bn_kron.c \
|
|
||||||
+ bn/bn_sqrt.c \
|
|
||||||
+ bn/bn_gcd.c \
|
|
||||||
+ bn/bn_prime.c \
|
|
||||||
+ bn/bn_err.c \
|
|
||||||
+ bn/bn_sqr.c \
|
|
||||||
+ bn/bn_asm.c \
|
|
||||||
+ bn/bn_recp.c \
|
|
||||||
+ bn/bn_mont.c \
|
|
||||||
+ bn/bn_mpi.c \
|
|
||||||
+ bn/bn_exp2.c \
|
|
||||||
+ bn/bn_gf2m.c \
|
|
||||||
+ bn/bn_nist.c \
|
|
||||||
+ bn/bn_depr.c \
|
|
||||||
+ bn/bn_x931p.c \
|
|
||||||
+ bn/bn_const.c \
|
|
||||||
+ bn/bn_opt.c \
|
|
||||||
+ asn1/a_object.c \
|
|
||||||
+ asn1/a_bitstr.c \
|
|
||||||
+ asn1/a_utctm.c \
|
|
||||||
+ asn1/a_gentm.c \
|
|
||||||
+ asn1/a_time.c \
|
|
||||||
+ asn1/a_int.c \
|
|
||||||
+ asn1/a_octet.c \
|
|
||||||
+ asn1/a_print.c \
|
|
||||||
+ asn1/a_type.c \
|
|
||||||
+ asn1/a_set.c \
|
|
||||||
+ asn1/a_dup.c \
|
|
||||||
+ asn1/a_d2i_fp.c \
|
|
||||||
+ asn1/a_i2d_fp.c \
|
|
||||||
+ asn1/a_enum.c \
|
|
||||||
+ asn1/a_utf8.c \
|
|
||||||
+ asn1/a_sign.c \
|
|
||||||
+ asn1/a_digest.c \
|
|
||||||
+ asn1/a_verify.c \
|
|
||||||
+ asn1/a_mbstr.c \
|
|
||||||
+ asn1/a_strex.c \
|
|
||||||
+ asn1/x_algor.c \
|
|
||||||
+ asn1/x_val.c \
|
|
||||||
+ asn1/x_pubkey.c \
|
|
||||||
+ asn1/x_sig.c \
|
|
||||||
+ asn1/x_req.c \
|
|
||||||
+ asn1/x_attrib.c \
|
|
||||||
+ asn1/x_bignum.c \
|
|
||||||
+ asn1/x_long.c \
|
|
||||||
+ asn1/x_name.c \
|
|
||||||
+ asn1/x_x509.c \
|
|
||||||
+ asn1/x_x509a.c \
|
|
||||||
+ asn1/x_crl.c \
|
|
||||||
+ asn1/x_info.c \
|
|
||||||
+ asn1/x_spki.c \
|
|
||||||
+ asn1/nsseq.c \
|
|
||||||
+ asn1/d2i_pu.c \
|
|
||||||
+ asn1/d2i_pr.c \
|
|
||||||
+ asn1/i2d_pu.c \
|
|
||||||
+ asn1/i2d_pr.c \
|
|
||||||
+ asn1/t_req.c \
|
|
||||||
+ asn1/t_x509.c \
|
|
||||||
+ asn1/t_x509a.c \
|
|
||||||
+ asn1/t_crl.c \
|
|
||||||
+ asn1/t_pkey.c \
|
|
||||||
+ asn1/t_spki.c \
|
|
||||||
+ asn1/t_bitst.c \
|
|
||||||
+ asn1/tasn_new.c \
|
|
||||||
+ asn1/tasn_fre.c \
|
|
||||||
+ asn1/tasn_enc.c \
|
|
||||||
+ asn1/tasn_dec.c \
|
|
||||||
+ asn1/tasn_utl.c \
|
|
||||||
+ asn1/tasn_typ.c \
|
|
||||||
+ asn1/f_int.c \
|
|
||||||
+ asn1/f_string.c \
|
|
||||||
+ asn1/n_pkey.c \
|
|
||||||
+ asn1/f_enum.c \
|
|
||||||
+ asn1/a_hdr.c \
|
|
||||||
+ asn1/x_pkey.c \
|
|
||||||
+ asn1/a_bool.c \
|
|
||||||
+ asn1/x_exten.c \
|
|
||||||
+ asn1/asn_mime.c \
|
|
||||||
+ asn1/asn1_gen.c \
|
|
||||||
+ asn1/asn1_par.c \
|
|
||||||
+ asn1/asn1_lib.c \
|
|
||||||
+ asn1/asn1_err.c \
|
|
||||||
+ asn1/a_meth.c \
|
|
||||||
+ asn1/a_bytes.c \
|
|
||||||
+ asn1/a_strnid.c \
|
|
||||||
+ asn1/evp_asn1.c \
|
|
||||||
+ asn1/asn_pack.c \
|
|
||||||
+ asn1/p5_pbe.c \
|
|
||||||
+ asn1/p5_pbev2.c \
|
|
||||||
+ asn1/p8_pkey.c \
|
|
||||||
+ asn1/asn_moid.c \
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/../include
|
|
||||||
+
|
|
||||||
+LOCAL_CFLAGS := -DNO_WINDOWS_BRAINDEATH
|
|
||||||
+
|
|
||||||
+include $(BUILD_STATIC_LIBRARY)
|
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
http://gladman.plushost.co.uk/oldsite/AES/
|
||||||
FILE="openssl-0.9.8l.tar.gz"
|
AES_FILE="aes-src-29-04-09.zip"
|
||||||
|
SHA_FILE="sha2-07-01-07.zip"
|
||||||
EXTRACT_PATH=project/jni/
|
EXTRACT_PATH=project/jni/
|
||||||
PATCH=build.patch
|
PATCH=build.patch
|
||||||
|
|
||||||
ln -s ../ project
|
ln -s ../ project
|
||||||
curl http://www.openssl.org/source/$FILE > $FILE
|
curl http://gladman.plushost.co.uk/oldsite/AES/$AES_FILE > $AES_FILE
|
||||||
tar xzf $FILE -C $EXTRACT_PATH
|
unzip $AES_FILE -d $EXTRACT_PATH/aes
|
||||||
patch -p1 -d $EXTRACT_PATH/openssl-0.9.8l < $PATCH
|
curl http://gladman.plushost.co.uk/oldsite/cryptography_technology/sha/$SHA_FILE > $SHA_FILE
|
||||||
|
unzip $SHA_FILE -d $EXTRACT_PATH/sha
|
||||||
|
|||||||
Reference in New Issue
Block a user