diff --git a/core/java/android/security/Scrypt.java b/core/java/android/security/Scrypt.java new file mode 100644 index 0000000000000..edf8d31183db5 --- /dev/null +++ b/core/java/android/security/Scrypt.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security; + +/** + * A Java wrapper for the JNI function to perform the password hashing algorithm SCRYPT. + * + * @hide + */ +public class Scrypt { + + native byte[] nativeScrypt(byte[] password, byte[] salt, int n, int r, int p, int outLen); + + /** Computes the password hashing algorithm SCRYPT. */ + public byte[] scrypt(byte[] password, byte[] salt, int n, int r, int p, int outLen) { + return nativeScrypt(password, salt, n, r, p, outLen); + } +} diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 1d22093158490..302189fbb7008 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -195,6 +195,7 @@ cc_library_shared { "android_content_res_ObbScanner.cpp", "android_content_res_Configuration.cpp", "android_animation_PropertyValuesHolder.cpp", + "android_security_Scrypt.cpp", "com_android_internal_net_NetworkStatsFactory.cpp", "com_android_internal_os_ClassLoaderFactory.cpp", "com_android_internal_os_FuseAppLoop.cpp", @@ -228,6 +229,7 @@ cc_library_shared { "libseccomp_policy", "libselinux", "libgrallocusage", + "libscrypt_static", ], shared_libs: [ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 5ae4a521ad6d5..f8dd7ac82255c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -208,6 +208,7 @@ extern int register_android_view_VelocityTracker(JNIEnv* env); extern int register_android_content_res_ObbScanner(JNIEnv* env); extern int register_android_content_res_Configuration(JNIEnv* env); extern int register_android_animation_PropertyValuesHolder(JNIEnv *env); +extern int register_android_security_Scrypt(JNIEnv *env); extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env); extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env); extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env); @@ -1492,6 +1493,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_content_res_Configuration), REG_JNI(register_android_animation_PropertyValuesHolder), + REG_JNI(register_android_security_Scrypt), REG_JNI(register_com_android_internal_content_NativeLibraryHelper), REG_JNI(register_com_android_internal_net_NetworkStatsFactory), REG_JNI(register_com_android_internal_os_FuseAppLoop), diff --git a/core/jni/android_security_Scrypt.cpp b/core/jni/android_security_Scrypt.cpp new file mode 100644 index 0000000000000..33508049799e6 --- /dev/null +++ b/core/jni/android_security_Scrypt.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "Scrypt" + +#include +#include "jni.h" + +#include +#include +#include +#include +#include + +extern "C" { +#include "crypto_scrypt.h" +} + +namespace android { + +static jbyteArray android_security_Scrypt_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) { + if (!password || !salt) { + return NULL; + } + + int passwordLen = env->GetArrayLength(password); + int saltLen = env->GetArrayLength(salt); + jbyteArray ret = env->NewByteArray(outLen); + + jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL); + jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL); + jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL); + + int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen, + (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr, + outLen); + env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT); + env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT); + env->ReleaseByteArrayElements(ret, retPtr, 0); + + if (!rc) { + return ret; + } else { + SLOGE("scrypt failed"); + return NULL; + } +} + +static const JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"nativeScrypt", "([B[BIIII)[B", (void*)android_security_Scrypt_nativeScrypt}, +}; + +int register_android_security_Scrypt(JNIEnv* env) { + return jniRegisterNativeMethods(env, "android/security/Scrypt", + sMethods, NELEM(sMethods)); +} + +} /* namespace android */