├── .gitignore
├── CHANGELOG
├── LICENSE
├── README.md
├── jni
├── Android.mk
├── Application.mk
├── README.txt
└── scrypt-jni.c
├── libs
├── arm64-v8a
│ └── libscrypt_crypho.so
├── armeabi-v7a
│ └── libscrypt_crypho.so
├── armeabi
│ └── libscrypt_crypho.so
├── mips
│ └── libscrypt_crypho.so
├── mips64
│ └── libscrypt_crypho.so
├── x86
│ └── libscrypt_crypho.so
└── x86_64
│ └── libscrypt_crypho.so
├── package.json
├── plugin.xml
├── src
├── android
│ └── com
│ │ └── crypho
│ │ └── plugins
│ │ └── ScryptPlugin.java
├── ios
│ ├── ScryptPlugin.h
│ └── ScryptPlugin.m
└── libscrypt
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── android.h
│ ├── b64.c
│ ├── b64.h
│ ├── crypto-mcf.c
│ ├── crypto-scrypt-saltgen.c
│ ├── crypto_scrypt-check.c
│ ├── crypto_scrypt-hash.c
│ ├── crypto_scrypt-hexconvert.c
│ ├── crypto_scrypt-hexconvert.h
│ ├── crypto_scrypt-nosse.c
│ ├── libscrypt.h
│ ├── libscrypt.version
│ ├── main.c
│ ├── sha256.c
│ ├── sha256.h
│ ├── slowequals.c
│ ├── slowequals.h
│ └── sysendian.h
├── testing.config.xml
├── tests
├── package.json
├── plugin.xml
└── tests.js
└── www
└── scrypt.js
/.gitignore:
--------------------------------------------------------------------------------
1 | obj/
2 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | 2.1.2 - 2017-06-23
5 | ------------------
6 |
7 | - Fix unicode strings on android.
8 | [ggozad]
9 |
10 | 2.1.1 - 2017-05-19
11 | ------------------
12 |
13 | - Fix scrypt for certain android phones.
14 | [demetris-manikas, ggozad]
15 |
16 | 2.1.0 - 2015-10-28
17 | ------------------
18 |
19 | - Rename to cordova-plugin-scrypt, publish to npm.
20 | [ggozad]
21 |
22 | - Add testing instructions.
23 | [ggozad]
24 |
25 | 2.0.2 - 2015-04-01
26 | ------------------
27 |
28 | - Android bug fixes.
29 | [demetris-manikas]
30 |
31 |
32 | 2.0.1 - 2015-03-24
33 | ------------------
34 |
35 | - Android implementation.
36 | [demetris-manikas, ggozad]
37 |
38 | 1.0.2 - 2015-03-20
39 | ------------------
40 |
41 | - Fix salt, now runs on iphone < 5s properly.
42 | [ggozad]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2015 Crypho AS
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scrypt plugin for iOS & Android
2 |
3 | ## Project no longer mantained.
4 | As Crypho does not use Cordova for a long time now, it has become clear that we cannot keep maintaining this project any longer, or give it the attention it deserves. A big thanks to all the contributors.
5 |
6 | ## Introduction
7 |
8 | [scrypt](http://www.tarsnap.com/scrypt.html) is a password-based key derivation function designed to make it costly to perform hardware attacks on the derived keys. While there exist scrypt implentations for the browser in javascript they are extremely slow and impractical for use in mobile apps.
9 |
10 | This plugin is for use with [Cordova](http://incubator.apache.org/cordova/) and allows your application to use scrypt on iOS/Android devices using native C code. It is based on [libscrypt](https://github.com/technion/libscrypt).
11 |
12 | ### Contents
13 |
14 | - [Installation](#installation)
15 | - [Plugin API](#plugin-api)
16 | - [LICENSE](#license)
17 |
18 | ##Installation
19 |
20 | Below are the methods for installing this plugin automatically using command line tools. For additional info, take a look at the [Plugman Documentation](https://github.com/apache/cordova-plugman/blob/master/README.md) and [Cordova Plugin Specification](https://github.com/alunny/cordova-plugin-spec).
21 |
22 | ### Cordova
23 |
24 | The plugin can be installed via the Cordova command line interface:
25 |
26 | * Navigate to the root folder for your phonegap project.
27 | * Run the command:
28 |
29 | ```sh
30 | cordova plugin add cordova-plugin-scrypt
31 | ```
32 |
33 | or if you want to be running the development version,
34 |
35 | ```sh
36 | cordova plugin add https://github.com/Crypho/cordova-plugin-scrypt.git
37 | ```
38 |
39 | ## Plugin API
40 |
41 | Grab the plugin instance variable.
42 |
43 | ```js
44 | var scrypt;
45 |
46 | document.addEventListener("deviceready", function(){
47 | scrypt = window.plugins.scrypt;
48 | ...
49 | });
50 | ```
51 |
52 | You can get the derived key in hexadecimal format by invoking ``scrypt(onSuccess, onFailure, password, salt, options)``
53 |
54 | ```js
55 | var key;
56 |
57 | scrypt(
58 | function (res) { key = res; },
59 | function (err) { key = null },
60 | 'password', 'salt', {N: 16384}
61 | )
62 | ```
63 |
64 | The ``salt`` parameter can be a string or an array of uint8. You can provide custom ``scrypt`` parameters in the options dict. The defaults are
65 | ```js
66 | {
67 | N: 16384,
68 | r: 8,
69 | p: 1,
70 | dkLen: 32
71 | }
72 | ```
73 |
74 | ## Testing
75 |
76 | ### Setup
77 |
78 | 1. Create a cordova app.
79 | 2. Replace ``config.xml`` with the ``testing.config.xml``
80 | 3. Add your platforms.
81 | 4. Add the ``cordova-plugin-test-framework`` plugin:
82 |
83 | ```
84 | cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-test-framework.git
85 | ```
86 |
87 | 4. Finally add the scrypt plugin as well as the tests from its location
88 |
89 | ```
90 | cordova plugin add PATH_TO_SCRYPT_PLUGIN
91 | cordova plugin add PATH_TO_SCRYPT_PLUGIN/tests
92 | ```
93 |
94 | ### Running the tests
95 |
96 | Just run the app for all platforms. Remember, if you have changes to test you will need to remove the scrypt plugin and add it again for the changes to be seen by the app.
97 |
98 | ## LICENSE
99 |
100 | The MIT License
101 |
102 | Copyright (c) 2015 Crypho AS.
103 |
104 | Permission is hereby granted, free of charge, to any person obtaining a copy
105 | of this software and associated documentation files (the "Software"), to deal
106 | in the Software without restriction, including without limitation the rights
107 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108 | copies of the Software, and to permit persons to whom the Software is
109 | furnished to do so, subject to the following conditions:
110 |
111 | The above copyright notice and this permission notice shall be included in
112 | all copies or substantial portions of the Software.
113 |
114 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
115 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
116 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
117 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
118 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
119 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
120 | THE SOFTWARE.
121 |
122 | libscrypt is Copyright (c) 2013, Joshua Small under the BSD license. See src/libscrypt/LICENSE
123 |
--------------------------------------------------------------------------------
/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 | include $(CLEAR_VARS)
3 | LOCAL_MODULE := scrypt
4 | LOCAL_SCRYPT_SRC := $(LOCAL_PATH)/../src/libscrypt
5 | LOCAL_C_INCLUDES := $(LOCAL_SCRYPT_SRC)/
6 |
7 | LOCAL_SRC_FILES := \
8 | $(LOCAL_SCRYPT_SRC)/b64.c \
9 | $(LOCAL_SCRYPT_SRC)/crypto_scrypt-hexconvert.c \
10 | $(LOCAL_SCRYPT_SRC)/sha256.c \
11 | $(LOCAL_SCRYPT_SRC)/crypto-mcf.c \
12 | $(LOCAL_SCRYPT_SRC)/crypto_scrypt-nosse.c \
13 | $(LOCAL_SCRYPT_SRC)/slowequals.c \
14 | $(LOCAL_SCRYPT_SRC)/crypto_scrypt-check.c \
15 | $(LOCAL_SCRYPT_SRC)/crypto-scrypt-saltgen.c \
16 | $(LOCAL_SCRYPT_SRC)/crypto_scrypt-hash.c \
17 | $(LOCAL_SCRYPT_SRC)/main.c
18 |
19 | include $(BUILD_STATIC_LIBRARY)
20 |
21 | include $(CLEAR_VARS)
22 | LOCAL_MODULE := scrypt_crypho
23 | LOCAL_STATIC_LIBRARIES := scrypt
24 |
25 | LOCAL_SCRYPT_SRC := $(LOCAL_PATH)/../src/libscrypt
26 | LOCAL_C_INCLUDES := $(LOCAL_SCRYPT_SRC)
27 |
28 | LOCAL_CRYPHO_SRC := $(LOCAL_PATH)
29 | LOCAL_SRC_FILES := $(LOCAL_PATH)/scrypt-jni.c
30 |
31 | LOCAL_LDLIBS := -llog
32 |
33 | include $(BUILD_SHARED_LIBRARY)
--------------------------------------------------------------------------------
/jni/Application.mk:
--------------------------------------------------------------------------------
1 | APP_PLATFORM := android-19
2 |
3 | APP_ABI := all
4 |
--------------------------------------------------------------------------------
/jni/README.txt:
--------------------------------------------------------------------------------
1 | To create the shared libraries run ndk-build from inside the jni directory
--------------------------------------------------------------------------------
/jni/scrypt-jni.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "libscrypt.h"
8 |
9 | #define LOG_TAG "libscrypt_crypho"
10 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
11 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
12 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
13 |
14 | static jobject JC_Integer;
15 | static jmethodID JMID_Integer_intValue;
16 |
17 | static jint callIntMethod(JNIEnv* env, jmethodID method, jobject integerObject, jint defaultValue);
18 | static void throwException(JNIEnv* env, char *msg);
19 |
20 | JNIEXPORT jbyteArray JNICALL
21 | Java_com_crypho_plugins_ScryptPlugin_scrypt( JNIEnv* env, jobject thiz,
22 | jbyteArray pass, jcharArray salt, jobject N, jobject r, jobject p, jobject dkLen)
23 | {
24 | int i;
25 | char *msg_error;
26 |
27 | jint N_i = callIntMethod(env, JMID_Integer_intValue, N, SCRYPT_N);
28 | jint r_i = callIntMethod(env, JMID_Integer_intValue, r, SCRYPT_r);
29 | jint p_i = callIntMethod(env, JMID_Integer_intValue, p, SCRYPT_p);
30 | jint dkLen_i = callIntMethod(env, JMID_Integer_intValue, dkLen, 32);
31 |
32 | jint passLen = (*env)->GetArrayLength(env, pass);
33 | if((*env)->ExceptionOccurred(env)) {
34 | LOGE("Failed to get passphrase lenght.");
35 | goto END;
36 | }
37 |
38 | jint saltLen = (*env)->GetArrayLength(env, salt);
39 | if((*env)->ExceptionOccurred(env)) {
40 | LOGE("Failed to get salt lenght.");
41 | goto END;
42 | }
43 |
44 | jbyte *passphrase = (*env)->GetByteArrayElements(env, pass, NULL);
45 | if((*env)->ExceptionOccurred(env)) {
46 | LOGE("Failed to get passphrase elements.");
47 | goto END;
48 | }
49 |
50 | jchar *salt_chars = (*env)->GetCharArrayElements(env, salt, NULL);
51 | if((*env)->ExceptionOccurred(env)) {
52 | LOGE("Failed to get salt elements.");
53 | goto END;
54 | }
55 |
56 | uint8_t *parsedSalt = malloc(sizeof(uint8_t) * saltLen);
57 | if (parsedSalt == NULL) {
58 | msg_error = "Failed to malloc parsedSalt.";
59 | LOGE("%s", msg_error);
60 | throwException(env, msg_error);
61 | goto END;
62 | }
63 |
64 | uint8_t *hashbuf = malloc(sizeof(uint8_t) * dkLen_i);
65 | if (hashbuf == NULL) {
66 | msg_error = "Failed to malloc hashbuf.";
67 | LOGE("%s", msg_error);
68 | throwException(env, msg_error);
69 | goto END;
70 | }
71 |
72 | for (i = 0; i < saltLen; ++i) {
73 | parsedSalt[i] = (uint8_t) salt_chars[i];
74 | }
75 |
76 | if (libscrypt_scrypt(passphrase, passLen, parsedSalt, saltLen, N_i, r_i, p_i, hashbuf, dkLen_i)) {
77 | switch (errno) {
78 | case EINVAL:
79 | msg_error = "N must be a power of 2 greater than 1.";
80 | break;
81 | case EFBIG:
82 | case ENOMEM:
83 | msg_error = "Insufficient memory available.";
84 | break;
85 | default:
86 | msg_error = "Memory allocation failed.";
87 | }
88 | throwException(env, msg_error);
89 | goto END;
90 | }
91 |
92 | jbyteArray result = (*env)->NewByteArray(env, dkLen_i);
93 | if((*env)->ExceptionOccurred(env)) {
94 | LOGE("Failed to allocate result buffer.");
95 | goto END;
96 | }
97 |
98 | (*env)->SetByteArrayRegion(env, result, 0, dkLen_i, (jbyte *) hashbuf);
99 | if((*env)->ExceptionOccurred(env)) {
100 | LOGE("Failed to set result buffer.");
101 | goto END;
102 | }
103 |
104 | END:
105 | if (passphrase) (*env)->ReleaseByteArrayElements(env, pass, passphrase, JNI_ABORT);
106 | if (salt_chars) (*env)->ReleaseCharArrayElements(env, salt, salt_chars, JNI_ABORT);
107 | if (hashbuf) free(hashbuf);
108 | if (parsedSalt) free(parsedSalt);
109 |
110 | return result;
111 | }
112 |
113 | static jint
114 | callIntMethod(JNIEnv* env, jmethodID method, jobject integerObject, jint defaultValue) {
115 | if (integerObject == NULL) {
116 | return defaultValue;
117 | }
118 | jint result = (*env)->CallIntMethod(env, integerObject, method);
119 | if((*env)->ExceptionOccurred(env)) {
120 | return defaultValue;
121 | }
122 | return result;
123 | }
124 |
125 | static void
126 | throwException(JNIEnv* env, char *msg) {
127 | jclass JC_Exception = (*env)->FindClass(env, "java/lang/Exception");
128 | (*env)->ThrowNew(env, JC_Exception, msg);
129 | }
130 |
131 | JNIEXPORT jint JNICALL
132 | JNI_OnLoad(JavaVM* vm, void* aReserved){
133 | JNIEnv* env;
134 | jclass aClass;
135 |
136 | if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK){
137 | LOGE("Failed to get the environment");
138 | return JNI_ERR;
139 | }
140 |
141 | aClass = (*env)->FindClass(env, "java/lang/Integer");
142 | if((*env)->ExceptionOccurred(env)) {
143 | LOGE("Failed to load class java.lang.Integer.");
144 | return JNI_ERR;
145 | }
146 |
147 | JC_Integer = (*env)->NewWeakGlobalRef(env, aClass);
148 | if((*env)->ExceptionOccurred(env)) {
149 | LOGE("Failed to asign global java.lang.Integer.");
150 | return JNI_ERR;
151 | }
152 |
153 | (*env)->DeleteLocalRef(env, aClass);
154 | if((*env)->ExceptionOccurred(env)) {
155 | LOGE("Failed to delete local ref of java.lang.Integer.");
156 | return JNI_ERR;
157 | }
158 |
159 | JMID_Integer_intValue = (*env)->GetMethodID(env, JC_Integer, "intValue", "()I");
160 | if((*env)->ExceptionOccurred(env)) {
161 | LOGE("Failed to fetch inValue method from java.lang.Integer.");
162 | return JNI_ERR;
163 | }
164 |
165 | // env->RegisterNatives(activityClass, methodTable, sizeof(methodTable) / sizeof(methodTable[0]));
166 | return JNI_VERSION_1_6;
167 | }
168 |
169 | JNIEXPORT void JNICALL
170 | JNI_OnUnLoad(JavaVM* vm, void* aReserved){
171 | JNIEnv* env;
172 |
173 | if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK){
174 | LOGE("Failed to get the environment");
175 | return;
176 | }
177 | (*env)->DeleteWeakGlobalRef(env, JC_Integer);
178 | }
--------------------------------------------------------------------------------
/libs/arm64-v8a/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/arm64-v8a/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/armeabi-v7a/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/armeabi-v7a/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/armeabi/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/armeabi/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/mips/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/mips/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/mips64/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/mips64/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/x86/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/x86/libscrypt_crypho.so
--------------------------------------------------------------------------------
/libs/x86_64/libscrypt_crypho.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Crypho/cordova-plugin-scrypt/a6d6f3fffab4cf49598795303e30448892ee1c59/libs/x86_64/libscrypt_crypho.so
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-scrypt",
3 | "version": "2.1.2",
4 | "description": "An scrypt implementation for cordova apps in iOS and Android.",
5 | "author": "Yiorgis Gozadinos ",
6 | "contributors": [
7 | {"name": "Demetris Manikas", "email": "demetris.manikas@gmail.com"}
8 | ],
9 | "cordova": {
10 | "id": "cordova-plugin-scrypt",
11 | "platforms": [
12 | "android",
13 | "ios"
14 | ]
15 | },
16 | "keywords": [
17 | "cordova",
18 | "security",
19 | "encryption",
20 | "scrypt",
21 | "ecosystem:cordova",
22 | "cordova-android",
23 | "cordova-ios",
24 | "cordova-browser"
25 | ],
26 | "main": "www/securestorage.js",
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/crypho/cordova-plugin-scrypt.git"
30 | },
31 | "devDependencies": {
32 | "cordova-plugin-test-framework": ">=1.0.0"
33 | },
34 | "license": "MIT",
35 | "bugs": {
36 | "url": "https://github.com/crypho/cordova-plugin-scrypt/issues"
37 | },
38 | "homepage": "https://github.com/crypho/cordova-plugin-scrypt#readme"
39 | }
40 |
--------------------------------------------------------------------------------
/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | ScryptPlugin
8 | Crypho AS
9 |
10 |
11 | An scrypt implementation for cordova apps in iOS and Android.
12 |
13 |
14 | MIT
15 |
16 | scrypt, encryption
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/src/android/com/crypho/plugins/ScryptPlugin.java:
--------------------------------------------------------------------------------
1 | package com.crypho.plugins;
2 |
3 | import android.util.Log;
4 |
5 | import org.apache.cordova.CallbackContext;
6 | import org.apache.cordova.CordovaArgs;
7 | import org.apache.cordova.CordovaInterface;
8 | import org.apache.cordova.CordovaPlugin;
9 | import org.apache.cordova.CordovaWebView;
10 | import org.apache.cordova.PluginResult;
11 | import org.json.JSONArray;
12 | import org.json.JSONObject;
13 | import org.json.JSONException;
14 |
15 | public class ScryptPlugin extends CordovaPlugin {
16 | private static final String TAG = "Scrypt";
17 | private static final char[] HEX = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
18 |
19 | static {
20 | System.loadLibrary("scrypt_crypho");
21 | }
22 |
23 | public native byte[] scrypt(byte[] pass, char[] salt, Integer N, Integer r, Integer p, Integer dkLen);
24 |
25 | @Override
26 | public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
27 | if ("scrypt".equals(action)) {
28 | String parsedSalt = null;
29 | final String arg_passphrase = args.getString(0);
30 | final char[] arg_salt = getSalt(args.get(1));
31 |
32 | JSONObject options = args.getJSONObject(2);
33 | final Integer N = getIntegerOption("N", options);
34 | final Integer r = getIntegerOption("r", options);
35 | final Integer p = getIntegerOption("p", options);
36 | final Integer dkLen = getIntegerOption("dkLen", options);
37 |
38 | cordova.getThreadPool().execute(new Runnable() {
39 | public void run() {
40 | try {
41 | byte[] passwordBytes = arg_passphrase.getBytes("UTF-8");
42 | byte[] res = scrypt(passwordBytes, arg_salt, N, r, p, dkLen);
43 | String result = hexify(res);
44 | callbackContext.success(result);
45 | } catch (Exception e) {
46 | Log.e(TAG, "Scrypt Failed: " + e.getMessage());
47 | callbackContext.error(e.getMessage());
48 | }
49 | }
50 | });
51 | return true;
52 | }
53 | return false;
54 | }
55 |
56 | private String hexify (byte[] input) {
57 | int len = input.length;
58 | char[] result = new char[2 * len];
59 | for ( int j = 0; j < len; j++ ) {
60 | int v = input[j] & 0xFF;
61 | result[j * 2] = HEX[v >>> 4];
62 | result[j * 2 + 1] = HEX[v & 0x0F];
63 | }
64 | return new String(result).toLowerCase();
65 | }
66 |
67 | private Integer getIntegerOption(String option, JSONObject options) {
68 | int arg = options.optInt(option);
69 | return arg != 0 ? Integer.valueOf(arg) : null;
70 | }
71 |
72 | private char[] getSalt(Object src){
73 | if (src instanceof JSONArray) {
74 | JSONArray tmp = (JSONArray) src;
75 | int len = tmp.length();
76 | char[] result = new char[len];
77 | for (int i = 0; i < len ; i++) {
78 | result[i] = (char) tmp.optInt(i);
79 | }
80 | return result;
81 | } else {
82 | return ((String) src).toCharArray();
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/src/ios/ScryptPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface ScryptPlugin : CDVPlugin
4 |
5 | - (void)scrypt:(CDVInvokedUrlCommand*)command;
6 |
7 | @property (nonatomic, copy) NSString *callbackId;
8 |
9 | @end
10 |
11 |
--------------------------------------------------------------------------------
/src/ios/ScryptPlugin.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "ScryptPlugin.h"
3 | #import "libscrypt.h"
4 | #import
5 |
6 | @implementation ScryptPlugin
7 |
8 | @synthesize callbackId;
9 |
10 | - (void)scrypt:(CDVInvokedUrlCommand*)command
11 | {
12 |
13 | int i, success;
14 | size_t saltLength;
15 | const uint8_t *parsedSalt;
16 | uint8_t *buffer = NULL;
17 | const char* passphrase = [[command argumentAtIndex:0] UTF8String];
18 | id salt = [command argumentAtIndex:1];
19 |
20 | if ([salt isKindOfClass:[NSString class]]) {
21 | parsedSalt = (const uint8_t *)[salt UTF8String];
22 | saltLength = (size_t) [salt length];
23 | } else if ([salt isKindOfClass:[NSArray class]]) {
24 | saltLength = (int) [salt count];
25 | buffer = malloc(sizeof(uint8_t) * saltLength);
26 |
27 | for (i = 0; i < saltLength; ++i) {
28 | buffer[i] = (uint8_t)[[salt objectAtIndex:i] integerValue];
29 | }
30 | parsedSalt = buffer;
31 | }
32 |
33 | // Parse options
34 | NSMutableDictionary* options = [command.arguments objectAtIndex:2];
35 | uint64_t N = [options[@"N"] unsignedLongValue] ?: SCRYPT_N;
36 | uint32_t r = [options[@"r"] unsignedShortValue] ?: SCRYPT_r;
37 | uint32_t p = [options[@"p"] unsignedShortValue] ?: SCRYPT_p;
38 | uint32_t dkLen = [options[@"dkLen"] unsignedShortValue] ?: 32;
39 |
40 | uint8_t hashbuf[dkLen];
41 | self.callbackId = command.callbackId;
42 |
43 | @try {
44 | success = libscrypt_scrypt((uint8_t *)passphrase, strlen(passphrase), parsedSalt, saltLength, N, r, p, hashbuf, dkLen);
45 | }
46 | @catch (NSException * e) {
47 | [self failWithMessage: [NSString stringWithFormat:@"%@", e] withError: nil];
48 | }
49 |
50 | if (success!=0) {
51 | [self failWithMessage: @"Failure in scrypt" withError: nil];
52 | }
53 |
54 |
55 | // Hexify
56 | NSMutableString *hexResult = [NSMutableString stringWithCapacity:dkLen * 2];
57 | for(i = 0;i < dkLen; i++ )
58 | {
59 | [hexResult appendFormat:@"%02x", hashbuf[i]];
60 | }
61 | NSString *result = [NSString stringWithString: hexResult];
62 | [self successWithMessage: result];
63 |
64 | free(buffer);
65 | }
66 |
67 | -(void)successWithMessage:(NSString *)message
68 | {
69 | if (self.callbackId != nil)
70 | {
71 | CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
72 | [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
73 | }
74 | }
75 |
76 | -(void)failWithMessage:(NSString *)message withError:(NSError *)error
77 | {
78 | NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message;
79 | CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage];
80 |
81 | [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/src/libscrypt/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Joshua Small
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 | 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.
7 |
8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
9 |
10 |
--------------------------------------------------------------------------------
/src/libscrypt/Makefile:
--------------------------------------------------------------------------------
1 | PREFIX ?= /usr/local
2 | LIBDIR ?= $(PREFIX)/lib
3 | INCLUDEDIR ?= $(PREFIX)/include
4 | MAKE_DIR ?= install -d
5 | INSTALL_DATA ?= install
6 |
7 | CC?=gcc
8 | CFLAGS?=-O2 -Wall -g -D_FORTIFY_SOURCE=2 -fstack-protector -fPIC
9 | LDFLAGS?=-Wl,-z,now -Wl,-z,relro -Wl,-soname,libscrypt.so.0 -Wl,--version-script=libscrypt.version
10 | CFLAGS_EXTRA?=-Wl,-rpath=.
11 |
12 | all: reference
13 |
14 | OBJS= crypto_scrypt-nosse.o sha256.o crypto-mcf.o b64.o crypto-scrypt-saltgen.o crypto_scrypt-check.o crypto_scrypt-hash.o slowequals.o
15 |
16 | libscrypt.so.0: $(OBJS)
17 | $(CC) $(LDFLAGS) -shared -o libscrypt.so.0 $(OBJS) -lm -lc
18 | ar rcs libscrypt.a $(OBJS)
19 |
20 | reference: libscrypt.so.0 main.o crypto_scrypt-hexconvert.o
21 | ln -s -f libscrypt.so.0 libscrypt.so
22 | $(CC) -Wall -o reference main.o b64.o crypto_scrypt-hexconvert.o $(CFLAGS_EXTRA) -L. -lscrypt
23 |
24 | clean:
25 | rm -f *.o reference libscrypt.so* libscrypt.a endian.h
26 |
27 | check: all
28 | ./reference
29 |
30 | devtest:
31 | splint crypto_scrypt-hexconvert.c
32 | splint crypto-mcf.c crypto_scrypt-check.c crypto_scrypt-hash.c -unrecog
33 | splint crypto-scrypt-saltgen.c +posixlib -compdef
34 | valgrind ./reference
35 |
36 | asan: main.c
37 | clang -O1 -g -fsanitize=address -fno-omit-frame-pointer *.c -o asantest
38 | ./asantest
39 | scan-build clang -O1 -g -fsanitize=memory -fno-omit-frame-pointer *.c -o asantest
40 | ./asantest
41 | rm -f asantest
42 |
43 | install: libscrypt.so.0
44 | $(MAKE_DIR) $(DESTDIR) $(DESTDIR)$(PREFIX) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCLUDEDIR)
45 | $(INSTALL_DATA) -pm 0755 libscrypt.so.0 $(DESTDIR)$(LIBDIR)
46 | cd $(DESTDIR)$(LIBDIR) && ln -s -f libscrypt.so.0 $(DESTDIR)$(LIBDIR)/libscrypt.so
47 | $(INSTALL_DATA) -pm 0644 libscrypt.h $(DESTDIR)$(INCLUDEDIR)
48 |
49 | install-osx: libscrypt.so.0
50 | $(MAKE_DIR) $(DESTDIR) $(DESTDIR)$(PREFIX) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCLUDEDIR)
51 | $(INSTALL_DATA) -pm 0755 libscrypt.so.0 $(DESTDIR)$(LIBDIR)/libscrypt.0.dylib
52 | cd $(DESTDIR)$(LIBDIR) && install_name_tool -id $(DESTDIR)$(LIBDIR)/libscrypt.0.dylib $(DESTDIR)$(LIBDIR)/libscrypt.0.dylib
53 | cd $(DESTDIR)$(LIBDIR) && ln -s -f libscrypt.0.dylib $(DESTDIR)$(LIBDIR)/libscrypt.dylib
54 | $(INSTALL_DATA) -pm 0644 libscrypt.h $(DESTDIR)$(INCLUDEDIR)
55 |
56 | install-static: libscrypt.a
57 | $(INSTALL_DATA) -pm 0644 libscrypt.a $(DESTDIR)$(LIBDIR)
58 |
--------------------------------------------------------------------------------
/src/libscrypt/README.md:
--------------------------------------------------------------------------------
1 | libscrypt
2 | =========
3 | Linux scrypt shared library.
4 |
5 | Full credit to algorithm designer and example code from Colin Percival here:
6 | http://www.tarsnap.com/scrypt.html
7 |
8 | Utilises BASE64 encoding library from ISC.
9 |
10 | Official project page, including stable tarballs found here:
11 | http://www.lolware.net/libscrypt.html
12 |
13 | Simple hashing interface
14 |
15 | The (reference) internal hashing function can be directly called as follows:
16 |
17 | int libscrypt_scrypt(const uint8_t *passwd, size_t passwdlen,
18 | const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t r,
19 | uint32_t p, /*@out@*/ uint8_t *buf, size_t buflen);
20 |
21 | Libscrypt's easier to use interface wraps this up to deal with the salt and produce BASE64 output as so:
22 |
23 | int libscrypt_hash(char *dst, char *passphrase, uint32_t N, uint8_t r, uint8_t p);
24 |
25 | Sane constants have been created for N, r and p so you can create a hash like this:
26 |
27 | libscrypt_hash(outbuf, "My cats's breath smells like cat food", SCRYPT_N, SCRYPT_r, SCRYPT_p);
28 |
29 | This function sets errno as required for any error conditions.
30 |
31 | Output stored in "outbuf" is stored in a standardised MCF form, which means includes the randomly created, 128 bit salt, all N, r and p values, and a BASE64 encoded version of the hash. The entire MCF can be stored in a database, and compared for use as below:
32 |
33 | retval = libscrypt_check(mcf, "pleasefailme");
34 | retval < 0 error
35 | retval = 0 password incorrect
36 | retval > 0 pass
37 |
38 | mcf should be defined as at least SCRYPT_MCF_LEN in size.
39 |
40 | Note that libscrypt_check needs to modify the mcf string and will not return it
41 | to the original state. Pass it a copy if you need to keep the original mcf.
42 |
43 | A number of internal functions are exposed, and users wishing to create more complex use cases should consult the header file, which is aimed at documenting the API fully.
44 |
45 | The test reference is also aimed at providing a well documented use case.
46 | Building
47 | --------
48 | make
49 | make check
50 | Check the Makefile for advice on linking against your application.
51 |
52 | OSX
53 | -----
54 | Please compile and install with:
55 |
56 | make LDFLAGS= CFLAGS_EXTRA=
57 | make install-osx
58 |
59 |
60 | BUGS
61 | ----
62 | SCRYPT_* constants are probably a little high for something like a Raspberry pi. Using '1' as SCRYPT_p is acceptable from a security and performance standpoint if needed.
63 | Experiments were performed with using memset() to zero out passwords as they were checked. This often caused issues with calling applications where the password based have been passed as a const*. We highly recommend implementing your own zeroing function the moment this library is called.
64 |
65 | Notes on Code Development
66 | ------------------------
67 |
68 | Code is now declared "stable", the master branch will always be "stable" and development will be done on branches.
69 | The reference machines are Fedora, CentOS, FreeBSD and Raspbian, and the code is expected to compile and run on all of these before being moved to stable branch.
70 | Full transparancy on the regular application of thorough testing can be found by reviewing recent test harness results here:
71 | http://www.lolware.net/libscrypttesting.txt
72 |
73 | Please, no more pull requests for Windows compatibility. If it's important to you - fork the project. I have no intention of pulling an OpenSSL and becoming a maze of ifdefs for platforms I don't even have a build environment for.
74 |
75 | Contact
76 | -------
77 | I can be contacted at: technion@lolware.net
78 |
79 | If required, my GPG key can be found at: https://lolware.net/technion-GPG-KEY
80 |
81 | Future releases will have the Git tag signed.
82 |
83 |
84 | Changenotes
85 | -----------
86 | v1.1a: Single Makefile line change. I wouldn't ordinarily tag this as a new "release", but the purpose here is to assist with packaging in distributions.
87 |
88 | v1.12: The static library is built, but no longer installed by default. You can install it with "make install-static". This is because static libraries are not typically bundled in packages.
89 |
90 | v1.13: Minor packaging related update
91 |
92 | v1.15: Replaced the b64 libraries with more portable one from ISC. Now tested and verified on a wider variety of architectures. Note, libscrypt_b64_encrypt was originally an exported function. This is no longer the case as it is considered an internal function only.
93 |
94 | v1.18: God damnit Apple
95 |
96 | v1.19: Code safety cleanups. Now running Coverity.
97 |
98 | v1.20: Bigfixes involving large N values, return values on error
99 |
100 |
101 |
103 |
104 |
--------------------------------------------------------------------------------
/src/libscrypt/android.h:
--------------------------------------------------------------------------------
1 | #ifndef SIZE_MAX
2 | # if defined(__LP64__)
3 | # define SIZE_MAX UINT64_MAX
4 | # else
5 | # define SIZE_MAX UINT32_MAX
6 | # endif
7 | #endif
--------------------------------------------------------------------------------
/src/libscrypt/b64.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 1996 by Internet Software Consortium.
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15 | * SOFTWARE.
16 | */
17 |
18 | /*
19 | * Portions Copyright (c) 1995 by International Business Machines, Inc.
20 | *
21 | * International Business Machines, Inc. (hereinafter called IBM) grants
22 | * permission under its copyrights to use, copy, modify, and distribute this
23 | * Software with or without fee, provided that the above copyright notice and
24 | * all paragraphs of this notice appear in all copies, and that the name of IBM
25 | * not be used in connection with the marketing of any product incorporating
26 | * the Software or modifications thereof, without specific, written prior
27 | * permission.
28 | *
29 | * To the extent it has a right to do so, IBM grants an immunity from suit
30 | * under its patents, if any, for the use, sale or manufacture of products to
31 | * the extent that such products are used for performing Domain Name System
32 | * dynamic updates in TCP/IP networks by means of the Software. No immunity is
33 | * granted for any product per se or for any other function of any product.
34 | *
35 | * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
36 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37 | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
38 | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
39 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
40 | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
41 | */
42 |
43 | /*
44 | * Base64 encode/decode functions from OpenBSD (src/lib/libc/net/base64.c).
45 | */
46 | #include
47 | #include
48 | #include
49 | #include
50 | #include
51 |
52 | #include "b64.h"
53 |
54 |
55 | static const char Base64[] =
56 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
57 | static const char Pad64 = '=';
58 |
59 | /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
60 | The following encoding technique is taken from RFC 1521 by Borenstein
61 | and Freed. It is reproduced here in a slightly edited form for
62 | convenience.
63 |
64 | A 65-character subset of US-ASCII is used, enabling 6 bits to be
65 | represented per printable character. (The extra 65th character, "=",
66 | is used to signify a special processing function.)
67 |
68 | The encoding process represents 24-bit groups of input bits as output
69 | strings of 4 encoded characters. Proceeding from left to right, a
70 | 24-bit input group is formed by concatenating 3 8-bit input groups.
71 | These 24 bits are then treated as 4 concatenated 6-bit groups, each
72 | of which is translated into a single digit in the base64 alphabet.
73 |
74 | Each 6-bit group is used as an index into an array of 64 printable
75 | characters. The character referenced by the index is placed in the
76 | output string.
77 |
78 | Table 1: The Base64 Alphabet
79 |
80 | Value Encoding Value Encoding Value Encoding Value Encoding
81 | 0 A 17 R 34 i 51 z
82 | 1 B 18 S 35 j 52 0
83 | 2 C 19 T 36 k 53 1
84 | 3 D 20 U 37 l 54 2
85 | 4 E 21 V 38 m 55 3
86 | 5 F 22 W 39 n 56 4
87 | 6 G 23 X 40 o 57 5
88 | 7 H 24 Y 41 p 58 6
89 | 8 I 25 Z 42 q 59 7
90 | 9 J 26 a 43 r 60 8
91 | 10 K 27 b 44 s 61 9
92 | 11 L 28 c 45 t 62 +
93 | 12 M 29 d 46 u 63 /
94 | 13 N 30 e 47 v
95 | 14 O 31 f 48 w (pad) =
96 | 15 P 32 g 49 x
97 | 16 Q 33 h 50 y
98 |
99 | Special processing is performed if fewer than 24 bits are available
100 | at the end of the data being encoded. A full encoding quantum is
101 | always completed at the end of a quantity. When fewer than 24 input
102 | bits are available in an input group, zero bits are added (on the
103 | right) to form an integral number of 6-bit groups. Padding at the
104 | end of the data is performed using the '=' character.
105 |
106 | Since all base64 input is an integral number of octets, only the
107 | -------------------------------------------------
108 | following cases can arise:
109 |
110 | (1) the final quantum of encoding input is an integral
111 | multiple of 24 bits; here, the final unit of encoded
112 | output will be an integral multiple of 4 characters
113 | with no "=" padding,
114 | (2) the final quantum of encoding input is exactly 8 bits;
115 | here, the final unit of encoded output will be two
116 | characters followed by two "=" padding characters, or
117 | (3) the final quantum of encoding input is exactly 16 bits;
118 | here, the final unit of encoded output will be three
119 | characters followed by one "=" padding character.
120 | */
121 |
122 | int
123 | libscrypt_b64_encode(src, srclength, target, targsize)
124 | unsigned char const *src;
125 | size_t srclength;
126 | char *target;
127 | size_t targsize;
128 | {
129 | size_t datalength = 0;
130 | unsigned char input[3];
131 | unsigned char output[4];
132 | unsigned int i;
133 |
134 | while (2 < srclength) {
135 | input[0] = *src++;
136 | input[1] = *src++;
137 | input[2] = *src++;
138 | srclength -= 3;
139 |
140 | output[0] = input[0] >> 2;
141 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
142 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
143 | output[3] = input[2] & 0x3f;
144 |
145 | if (datalength + 4 > targsize)
146 | return (-1);
147 | target[datalength++] = Base64[output[0]];
148 | target[datalength++] = Base64[output[1]];
149 | target[datalength++] = Base64[output[2]];
150 | target[datalength++] = Base64[output[3]];
151 | }
152 |
153 | /* Now we worry about padding. */
154 | if (0 != srclength) {
155 | /* Get what's left. */
156 | input[0] = input[1] = input[2] = '\0';
157 | for (i = 0; i < srclength; i++)
158 | input[i] = *src++;
159 |
160 | output[0] = input[0] >> 2;
161 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
162 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
163 |
164 | if (datalength + 4 > targsize)
165 | return (-1);
166 | target[datalength++] = Base64[output[0]];
167 | target[datalength++] = Base64[output[1]];
168 | if (srclength == 1)
169 | target[datalength++] = Pad64;
170 | else
171 | target[datalength++] = Base64[output[2]];
172 | target[datalength++] = Pad64;
173 | }
174 | if (datalength >= targsize)
175 | return (-1);
176 | target[datalength] = '\0'; /* Returned value doesn't count \0. */
177 | return (int)(datalength);
178 | }
179 |
180 | /* skips all whitespace anywhere.
181 | converts characters, four at a time, starting at (or after)
182 | src from base - 64 numbers into three 8 bit bytes in the target area.
183 | it returns the number of data bytes stored at the target, or -1 on error.
184 | */
185 |
186 | int
187 | libscrypt_b64_decode(src, target, targsize)
188 | char const *src;
189 | unsigned char *target;
190 | size_t targsize;
191 | {
192 | int state, ch;
193 | unsigned int tarindex;
194 | unsigned char nextbyte;
195 | char *pos;
196 |
197 | state = 0;
198 | tarindex = 0;
199 |
200 | while ((ch = (unsigned char)*src++) != '\0') {
201 | if (isspace(ch)) /* Skip whitespace anywhere. */
202 | continue;
203 |
204 | if (ch == Pad64)
205 | break;
206 |
207 | pos = strchr(Base64, ch);
208 | if (pos == 0) /* A non-base64 character. */
209 | return (-1);
210 |
211 | switch (state) {
212 | case 0:
213 | if (target) {
214 | if (tarindex >= targsize)
215 | return (-1);
216 | target[tarindex] = (pos - Base64) << 2;
217 | }
218 | state = 1;
219 | break;
220 | case 1:
221 | if (target) {
222 | if (tarindex >= targsize)
223 | return (-1);
224 | target[tarindex] |= (pos - Base64) >> 4;
225 | nextbyte = ((pos - Base64) & 0x0f) << 4;
226 | if (tarindex + 1 < targsize)
227 | target[tarindex+1] = nextbyte;
228 | else if (nextbyte)
229 | return (-1);
230 | }
231 | tarindex++;
232 | state = 2;
233 | break;
234 | case 2:
235 | if (target) {
236 | if (tarindex >= targsize)
237 | return (-1);
238 | target[tarindex] |= (pos - Base64) >> 2;
239 | nextbyte = ((pos - Base64) & 0x03) << 6;
240 | if (tarindex + 1 < targsize)
241 | target[tarindex+1] = nextbyte;
242 | else if (nextbyte)
243 | return (-1);
244 | }
245 | tarindex++;
246 | state = 3;
247 | break;
248 | case 3:
249 | if (target) {
250 | if (tarindex >= targsize)
251 | return (-1);
252 | target[tarindex] |= (pos - Base64);
253 | }
254 | tarindex++;
255 | state = 0;
256 | break;
257 | }
258 | }
259 |
260 | /*
261 | * We are done decoding Base-64 chars. Let's see if we ended
262 | * on a byte boundary, and/or with erroneous trailing characters.
263 | */
264 |
265 | if (ch == Pad64) { /* We got a pad char. */
266 | ch = (unsigned char)*src++; /* Skip it, get next. */
267 | switch (state) {
268 | case 0: /* Invalid = in first position */
269 | case 1: /* Invalid = in second position */
270 | return (-1);
271 |
272 | case 2: /* Valid, means one byte of info */
273 | /* Skip any number of spaces. */
274 | for (; ch != '\0'; ch = (unsigned char)*src++)
275 | if (!isspace(ch))
276 | break;
277 | /* Make sure there is another trailing = sign. */
278 | if (ch != Pad64)
279 | return (-1);
280 | ch = (unsigned char)*src++; /* Skip the = */
281 | /* Fall through to "single trailing =" case. */
282 | /* FALLTHROUGH */
283 |
284 | case 3: /* Valid, means two bytes of info */
285 | /*
286 | * We know this char is an =. Is there anything but
287 | * whitespace after it?
288 | */
289 | for (; ch != '\0'; ch = (unsigned char)*src++)
290 | if (!isspace(ch))
291 | return (-1);
292 |
293 | /*
294 | * Now make sure for cases 2 and 3 that the "extra"
295 | * bits that slopped past the last full byte were
296 | * zeros. If we don't check them, they become a
297 | * subliminal channel.
298 | */
299 | if (target && tarindex < targsize &&
300 | target[tarindex] != 0)
301 | return (-1);
302 | }
303 | } else {
304 | /*
305 | * We ended by seeing the end of the string. Make sure we
306 | * have no partial bytes lying around.
307 | */
308 | if (state != 0)
309 | return (-1);
310 | }
311 |
312 | return (tarindex);
313 | }
314 |
--------------------------------------------------------------------------------
/src/libscrypt/b64.h:
--------------------------------------------------------------------------------
1 |
2 | /* BASE64 libraries used internally - should not need to be packaged */
3 |
4 | #define b64_encode_len(A) ((A+2)/3 * 4 + 1)
5 | #define b64_decode_len(A) (A / 4 * 3 + 2)
6 |
7 | int libscrypt_b64_encode(unsigned char const *src, size_t srclength,
8 | /*@out@*/ char *target, size_t targetsize);
9 | int libscrypt_b64_decode(char const *src, /*@out@*/ unsigned char *target,
10 | size_t targetsize);
11 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto-mcf.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #ifndef S_SPLINT_S /* Including this here triggers a known bug in splint */
10 | #include
11 | #endif
12 |
13 | #include "libscrypt.h"
14 |
15 | /* ilog2 for powers of two */
16 | static uint32_t scrypt_ilog2(uint32_t n)
17 | {
18 | #ifndef S_SPLINT_S
19 |
20 | /* Check for a valid power of two */
21 | if (n < 2 || (n & (n - 1)))
22 | return -1;
23 | #endif
24 | uint32_t t = 1;
25 | while (((uint32_t)1 << t) < n)
26 | {
27 | if(t > SCRYPT_SAFE_N)
28 | return (uint32_t) -1; /* Check for insanity */
29 | t++;
30 | }
31 |
32 | return t;
33 | }
34 |
35 | #ifdef _MSC_VER
36 | #define SNPRINTF _snprintf
37 | #else
38 | #define SNPRINTF snprintf
39 | #endif
40 |
41 | int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt,
42 | const char *hash, char *mcf)
43 | {
44 |
45 | uint32_t t, params;
46 | int s;
47 |
48 | if(!mcf || !hash)
49 | return 0;
50 | /* Although larger values of r, p are valid in scrypt, this mcf format
51 | * limits to 8 bits. If your number is larger, current computers will
52 | * struggle
53 | */
54 | if(r > (uint8_t)(-1) || p > (uint8_t)(-1))
55 | return 0;
56 |
57 | t = scrypt_ilog2(N);
58 | if (t < 1)
59 | return 0;
60 |
61 | params = (r << 8) + p;
62 | params += (uint32_t)t << 16;
63 |
64 | /* Using snprintf - not checking for overflows. We've already
65 | * determined that mcf should be defined as at least SCRYPT_MCF_LEN
66 | * in length
67 | */
68 | s = SNPRINTF(mcf, SCRYPT_MCF_LEN, SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash);
69 | if (s > SCRYPT_MCF_LEN)
70 | return 0;
71 |
72 | return 1;
73 | }
74 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto-scrypt-saltgen.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #ifndef S_SPLINT_S /* Including this here triggers a known bug in splint */
8 | #include
9 | #endif
10 |
11 | #define RNGDEV "/dev/urandom"
12 |
13 | int libscrypt_salt_gen(uint8_t *salt, size_t len)
14 | {
15 | unsigned char buf[len];
16 | size_t data_read = 0;
17 | int urandom = open(RNGDEV, O_RDONLY);
18 |
19 | if (urandom < 0)
20 | {
21 | return -1;
22 | }
23 |
24 | while (data_read < len) {
25 | ssize_t result = read(urandom, buf + data_read, len - data_read);
26 |
27 | if (result < 0)
28 | {
29 | if (errno == EINTR || errno == EAGAIN) {
30 | continue;
31 | }
32 |
33 | else {
34 | (void)close(urandom);
35 | return -1;
36 | }
37 | }
38 |
39 | data_read += result;
40 | }
41 |
42 | /* Failures on close() shouldn't occur with O_RDONLY */
43 | (void)close(urandom);
44 |
45 | memcpy(salt, buf, len);
46 |
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto_scrypt-check.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "b64.h"
7 | #include "slowequals.h"
8 | #include "libscrypt.h"
9 |
10 | #ifdef _WIN32
11 | /* On windows, strtok uses a thread-local static variable in strtok to
12 | * make strtok thread-safe. It also neglects to provide a strtok_r. */
13 | #define strtok_r(str, val, saveptr) strtok((str), (val))
14 | #endif
15 |
16 | int libscrypt_check(char *mcf, const char *password)
17 | {
18 | /* Return values:
19 | * <0 error
20 | * == 0 password incorrect
21 | * >0 correct password
22 | */
23 |
24 | #ifndef _WIN32
25 | char *saveptr = NULL;
26 | #endif
27 | uint32_t params;
28 | uint64_t N;
29 | uint8_t r, p;
30 | int retval;
31 | uint8_t hashbuf[64];
32 | char outbuf[128];
33 | uint8_t salt[32];
34 | char *tok;
35 |
36 | if(memcmp(mcf, SCRYPT_MCF_ID, 3) != 0)
37 | {
38 | /* Only version 0 supported */
39 | return -1;
40 | }
41 |
42 | tok = strtok_r(mcf, "$", &saveptr);
43 | if ( !tok )
44 | return -1;
45 |
46 | tok = strtok_r(NULL, "$", &saveptr);
47 |
48 | if ( !tok )
49 | return -1;
50 |
51 | params = (uint32_t)strtoul(tok, NULL, 16);
52 | if ( params == 0 )
53 | return -1;
54 |
55 | tok = strtok_r(NULL, "$", &saveptr);
56 |
57 | if ( !tok )
58 | return -1;
59 |
60 | p = params & 0xff;
61 | r = (params >> 8) & 0xff;
62 | N = params >> 16;
63 |
64 | if (N > SCRYPT_SAFE_N)
65 | return -1;
66 |
67 | N = (uint64_t)1 << N;
68 |
69 | /* Useful debugging:
70 | printf("We've obtained salt 'N' r p of '%s' %d %d %d\n", tok, N,r,p);
71 | */
72 |
73 | memset(salt, 0, sizeof(salt)); /* Keeps splint happy */
74 | retval = libscrypt_b64_decode(tok, (unsigned char*)salt, sizeof(salt));
75 | if (retval < 1)
76 | return -1;
77 |
78 | retval = libscrypt_scrypt((uint8_t*)password, strlen(password), salt,
79 | (uint32_t)retval, N, r, p, hashbuf, sizeof(hashbuf));
80 |
81 | if (retval != 0)
82 | return -1;
83 |
84 | retval = libscrypt_b64_encode((unsigned char*)hashbuf, sizeof(hashbuf),
85 | outbuf, sizeof(outbuf));
86 |
87 | if (retval == 0)
88 | return -1;
89 |
90 | tok = strtok_r(NULL, "$", &saveptr);
91 |
92 | if ( !tok )
93 | return -1;
94 |
95 | if(slow_equals(tok, outbuf) == 0)
96 | {
97 | return 0;
98 | }
99 |
100 | return 1; /* This is the "else" condition */
101 | }
102 |
103 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto_scrypt-hash.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "b64.h"
7 | #include "libscrypt.h"
8 |
9 | int libscrypt_hash(char *dst, const char *passphrase, uint32_t N, uint8_t r,
10 | uint8_t p)
11 | {
12 |
13 | int retval;
14 | uint8_t salt[SCRYPT_SALT_LEN];
15 | uint8_t hashbuf[SCRYPT_HASH_LEN];
16 | char outbuf[256];
17 | char saltbuf[256];
18 |
19 | if(libscrypt_salt_gen(salt, SCRYPT_SALT_LEN) == -1)
20 | {
21 | return 0;
22 | }
23 |
24 | retval = libscrypt_scrypt((const uint8_t*)passphrase, strlen(passphrase),
25 | (uint8_t*)salt, SCRYPT_SALT_LEN, N, r, p, hashbuf, sizeof(hashbuf));
26 | if(retval == -1)
27 | return 0;
28 |
29 | retval = libscrypt_b64_encode((unsigned char*)hashbuf, sizeof(hashbuf),
30 | outbuf, sizeof(outbuf));
31 | if(retval == -1)
32 | return 0;
33 |
34 | retval = libscrypt_b64_encode((unsigned char *)salt, sizeof(salt),
35 | saltbuf, sizeof(saltbuf));
36 | if(retval == -1)
37 | return 0;
38 |
39 | retval = libscrypt_mcf(N, r, p, saltbuf, outbuf, dst);
40 | if(retval != 1)
41 | return 0;
42 |
43 | return 1;
44 | }
45 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto_scrypt-hexconvert.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | /* The hexconvert function is only used to test reference vectors against
7 | * known answers. The contents of this file are therefore a component
8 | * to assist with test harnesses only
9 | */
10 |
11 | int libscrypt_hexconvert(uint8_t *buf, size_t s, char *outbuf, size_t obs)
12 | {
13 |
14 | size_t i;
15 | int len = 0;
16 |
17 | if (!buf || s < 1 || obs < (s * 2 + 1))
18 | return 0;
19 |
20 | memset(outbuf, 0, obs);
21 |
22 |
23 | for(i=0; i<=(s-1); i++)
24 | {
25 | /* snprintf(outbuf, s,"%s...", outbuf....) has undefined results
26 | * and can't be used. Using offests like this makes snprintf
27 | * nontrivial. we therefore have use inescure sprintf() and
28 | * lengths checked elsewhere (start of function) */
29 | /*@ -bufferoverflowhigh @*/
30 | len += sprintf(outbuf+len, "%02x", (unsigned int) buf[i]);
31 | }
32 |
33 | return 1;
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto_scrypt-hexconvert.h:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | /**
5 | * Converts a binary string to a hex representation of that string
6 | * outbuf must have size of at least buf * 2 + 1.
7 | */
8 | int libscrypt_hexconvert(const uint8_t *buf, size_t s, char *outbuf,
9 | size_t obs);
10 |
--------------------------------------------------------------------------------
/src/libscrypt/crypto_scrypt-nosse.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2009 Colin Percival
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | * 1. Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | * 2. Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 | * SUCH DAMAGE.
25 | *
26 | * This file was originally written by Colin Percival as part of the Tarsnap
27 | * online backup system.
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 |
35 | #include "sha256.h"
36 | #include "sysendian.h"
37 |
38 | #include "libscrypt.h"
39 |
40 | static void blkcpy(uint8_t *, uint8_t *, size_t);
41 | static void blkxor(uint8_t *, uint8_t *, size_t);
42 | static void salsa20_8(uint8_t[64]);
43 | static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
44 | static uint64_t integerify(uint8_t *, size_t);
45 | static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
46 |
47 | static void
48 | blkcpy(uint8_t * dest, uint8_t * src, size_t len)
49 | {
50 | size_t i;
51 |
52 | for (i = 0; i < len; i++)
53 | dest[i] = src[i];
54 | }
55 |
56 | static void
57 | blkxor(uint8_t * dest, uint8_t * src, size_t len)
58 | {
59 | size_t i;
60 |
61 | for (i = 0; i < len; i++)
62 | dest[i] ^= src[i];
63 | }
64 |
65 | /**
66 | * salsa20_8(B):
67 | * Apply the salsa20/8 core to the provided block.
68 | */
69 | static void
70 | salsa20_8(uint8_t B[64])
71 | {
72 | uint32_t B32[16];
73 | uint32_t x[16];
74 | size_t i;
75 |
76 | /* Convert little-endian values in. */
77 | for (i = 0; i < 16; i++)
78 | B32[i] = le32dec(&B[i * 4]);
79 |
80 | /* Compute x = doubleround^4(B32). */
81 | for (i = 0; i < 16; i++)
82 | x[i] = B32[i];
83 | for (i = 0; i < 8; i += 2) {
84 | #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
85 | /* Operate on columns. */
86 | x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9);
87 | x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18);
88 |
89 | x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9);
90 | x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18);
91 |
92 | x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9);
93 | x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18);
94 |
95 | x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9);
96 | x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18);
97 |
98 | /* Operate on rows. */
99 | x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9);
100 | x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18);
101 |
102 | x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9);
103 | x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18);
104 |
105 | x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9);
106 | x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18);
107 |
108 | x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9);
109 | x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18);
110 | #undef R
111 | }
112 |
113 | /* Compute B32 = B32 + x. */
114 | for (i = 0; i < 16; i++)
115 | B32[i] += x[i];
116 |
117 | /* Convert little-endian values out. */
118 | for (i = 0; i < 16; i++)
119 | le32enc(&B[4 * i], B32[i]);
120 | }
121 |
122 | /**
123 | * blockmix_salsa8(B, Y, r):
124 | * Compute B = BlockMix_{salsa20/8, r}(B). The input B must be 128r bytes in
125 | * length; the temporary space Y must also be the same size.
126 | */
127 | static void
128 | blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
129 | {
130 | uint8_t X[64];
131 | size_t i;
132 |
133 | /* 1: X <-- B_{2r - 1} */
134 | blkcpy(X, &B[(2 * r - 1) * 64], 64);
135 |
136 | /* 2: for i = 0 to 2r - 1 do */
137 | for (i = 0; i < 2 * r; i++) {
138 | /* 3: X <-- H(X \xor B_i) */
139 | blkxor(X, &B[i * 64], 64);
140 | salsa20_8(X);
141 |
142 | /* 4: Y_i <-- X */
143 | blkcpy(&Y[i * 64], X, 64);
144 | }
145 |
146 | /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
147 | for (i = 0; i < r; i++)
148 | blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
149 | for (i = 0; i < r; i++)
150 | blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
151 | }
152 |
153 | /**
154 | * integerify(B, r):
155 | * Return the result of parsing B_{2r-1} as a little-endian integer.
156 | */
157 | static uint64_t
158 | integerify(uint8_t * B, size_t r)
159 | {
160 | uint8_t * X = &B[(2 * r - 1) * 64];
161 |
162 | return (le64dec(X));
163 | }
164 |
165 | /**
166 | * smix(B, r, N, V, XY):
167 | * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; the
168 | * temporary storage V must be 128rN bytes in length; the temporary storage
169 | * XY must be 256r bytes in length. The value N must be a power of 2.
170 | */
171 | static void
172 | smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
173 | {
174 | uint8_t * X = XY;
175 | uint8_t * Y = &XY[128 * r];
176 | uint64_t i;
177 | uint64_t j;
178 |
179 | /* 1: X <-- B */
180 | blkcpy(X, B, 128 * r);
181 |
182 | /* 2: for i = 0 to N - 1 do */
183 | for (i = 0; i < N; i++) {
184 | /* 3: V_i <-- X */
185 | blkcpy(&V[i * (128 * r)], X, 128 * r);
186 |
187 | /* 4: X <-- H(X) */
188 | blockmix_salsa8(X, Y, r);
189 | }
190 |
191 | /* 6: for i = 0 to N - 1 do */
192 | for (i = 0; i < N; i++) {
193 | /* 7: j <-- Integerify(X) mod N */
194 | j = integerify(X, r) & (N - 1);
195 |
196 | /* 8: X <-- H(X \xor V_j) */
197 | blkxor(X, &V[j * (128 * r)], 128 * r);
198 | blockmix_salsa8(X, Y, r);
199 | }
200 |
201 | /* 10: B' <-- X */
202 | blkcpy(B, X, 128 * r);
203 | }
204 |
205 | /**
206 | * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
207 | * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
208 | * p, buflen) and write the result into buf. The parameters r, p, and buflen
209 | * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
210 | * must be a power of 2.
211 | *
212 | * Return 0 on success; or -1 on error.
213 | */
214 | int
215 | libscrypt_scrypt(const uint8_t * passwd, size_t passwdlen,
216 | const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
217 | uint8_t * buf, size_t buflen)
218 | {
219 | uint8_t * B;
220 | uint8_t * V;
221 | uint8_t * XY;
222 | size_t r = _r, p = _p;
223 | uint32_t i;
224 |
225 | /* Sanity-check parameters. */
226 | #if SIZE_MAX > UINT32_MAX
227 | if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
228 | errno = EFBIG;
229 | goto err0;
230 | }
231 | #endif
232 | if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
233 | errno = EFBIG;
234 | goto err0;
235 | }
236 | if (((N & (N - 1)) != 0) || (N == 0)) {
237 | errno = EINVAL;
238 | goto err0;
239 | }
240 | if ((r > SIZE_MAX / 128 / p) ||
241 | #if SIZE_MAX / 256 <= UINT32_MAX
242 | (r > SIZE_MAX / 256) ||
243 | #endif
244 | (N > SIZE_MAX / 128 / r)) {
245 | errno = ENOMEM;
246 | goto err0;
247 | }
248 |
249 | /* Allocate memory. */
250 | if ((B = malloc(128 * r * p)) == NULL)
251 | goto err0;
252 | if ((XY = malloc(256 * r)) == NULL)
253 | goto err1;
254 | if ((V = malloc(128 * r * N)) == NULL)
255 | goto err2;
256 |
257 | /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
258 | libscrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
259 |
260 | /* 2: for i = 0 to p - 1 do */
261 | for (i = 0; i < p; i++) {
262 | /* 3: B_i <-- MF(B_i, N) */
263 | smix(&B[i * 128 * r], r, N, V, XY);
264 | }
265 |
266 | /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
267 | libscrypt_PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
268 |
269 | /* Free memory. */
270 | free(V);
271 | free(XY);
272 | free(B);
273 |
274 | /* Success! */
275 | return (0);
276 |
277 | err2:
278 | free(XY);
279 | err1:
280 | free(B);
281 | err0:
282 | /* Failure! */
283 | return (-1);
284 | }
--------------------------------------------------------------------------------
/src/libscrypt/libscrypt.h:
--------------------------------------------------------------------------------
1 | /*-
2 | */
3 | #ifndef _CRYPTO_SCRYPT_H_
4 | #define _CRYPTO_SCRYPT_H_
5 |
6 |
7 | #include
8 | #include "android.h"
9 |
10 | #ifdef __cplusplus
11 | extern "C"{
12 | #endif
13 |
14 | /**
15 | * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
16 | * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
17 | * p, buflen) and write the result into buf. The parameters r, p, and buflen
18 | * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N
19 | * must be a power of 2 greater than 1.
20 | *
21 | * libscrypt_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
22 | * password; duh
23 | * N: CPU AND RAM cost (first modifier)
24 | * r: RAM Cost
25 | * p: CPU cost (parallelisation)
26 | * In short, N is your main performance modifier. Values of r = 8, p = 1 are
27 | * standard unless you want to modify the CPU/RAM ratio.
28 | * Return 0 on success; or -1 on error.
29 | */
30 | int libscrypt_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
31 | uint32_t, uint32_t, /*@out@*/ uint8_t *, size_t);
32 |
33 | /* Converts a series of input parameters to a MCF form for storage */
34 | int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, const char *salt,
35 | const char *hash, char *mcf);
36 |
37 | #ifndef _MSC_VER
38 | /* Generates a salt. Uses /dev/urandom/
39 | */
40 | int libscrypt_salt_gen(/*@out@*/ uint8_t *rand, size_t len);
41 |
42 | /* Creates a hash of a passphrase using a randomly generated salt */
43 | /* Returns >0 on success, or 0 for fail */
44 | int libscrypt_hash(char *dst, const char* passphrase, uint32_t N, uint8_t r,
45 | uint8_t p);
46 | #endif
47 |
48 | /* Checks a given MCF against a password */
49 | int libscrypt_check(char *mcf, const char *password);
50 |
51 | #ifdef __cplusplus
52 | }
53 | #endif
54 |
55 | /* Sane default values */
56 | #define SCRYPT_HASH_LEN 64 /* This can be user defined -
57 | *but 64 is the reference size
58 | */
59 | #define SCRYPT_SAFE_N 30 /* This is much higher than you want. It's just
60 | * a blocker for insane defines
61 | */
62 | #define SCRYPT_SALT_LEN 16 /* This is just a recommended size */
63 | #define SCRYPT_MCF_LEN 125 /* mcf is 120 byte + nul */
64 | #define SCRYPT_MCF_ID "$s1"
65 | #define SCRYPT_N 16384
66 | #define SCRYPT_r 8
67 | #define SCRYPT_p 16
68 | #endif /* !_CRYPTO_SCRYPT_H_ */
69 |
--------------------------------------------------------------------------------
/src/libscrypt/libscrypt.version:
--------------------------------------------------------------------------------
1 | libscrypt {
2 | global: libscrypt_check;
3 | libscrypt_hash;
4 | libscrypt_mcf;
5 | libscrypt_salt_gen;
6 | libscrypt_scrypt;
7 | local: *;
8 | };
9 |
--------------------------------------------------------------------------------
/src/libscrypt/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "b64.h"
7 | #include "crypto_scrypt-hexconvert.h"
8 | #include "libscrypt.h"
9 |
10 | #define REF1 "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"
11 |
12 | #define REF2 "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"
13 |
14 |
15 | int main()
16 | {
17 | uint8_t hashbuf[SCRYPT_HASH_LEN];
18 | char outbuf[132];
19 | char mcf[SCRYPT_MCF_LEN];
20 | char mcf2[SCRYPT_MCF_LEN];
21 | char saltbuf[64];
22 | int retval;
23 | /**
24 | * libscrypt_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
25 | * password; duh
26 | * N: CPU AND RAM cost (first modifier)
27 | * r: RAM Cost
28 | * p: CPU cost (parallelisation)
29 | * In short, N is your main performance modifier. Values of r = 8, p = 1 are
30 | * standard unless you want to modify the CPU/RAM ratio.
31 | int libscrypt_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
32 | uint32_t, uint32_t, uint8_t *, size_t);
33 | */
34 |
35 | printf("TEST ONE: Direct call to reference function with password 'password' and salt 'NaCL'\n");
36 |
37 | retval = libscrypt_scrypt((uint8_t*)"password",strlen("password"), (uint8_t*)"NaCl", strlen("NaCl"), 1024, 8, 16, hashbuf, sizeof(hashbuf));
38 |
39 | if(retval != 0)
40 | {
41 | printf("TEST ONE FAILED: Failed to create hash of \"password\"\\n");
42 | exit(EXIT_FAILURE);
43 | }
44 |
45 | printf("TEST ONE: SUCCESSFUL\n");
46 |
47 | printf("TEST ONE and a half: Review errno on invalid input\n");
48 |
49 | retval = libscrypt_scrypt((uint8_t*)"password",strlen("password"), (uint8_t*)"NaCl", strlen("NaCl"), 47, 1, 1, hashbuf, sizeof(hashbuf));
50 |
51 | if(retval != -1)
52 | {
53 | printf("TEST ONE FAILED: Failed to detect invalid input\n");
54 | exit(EXIT_FAILURE);
55 | }
56 | printf("TEST ONE and a half: Successfully failed on error: %s\n", strerror(errno));
57 |
58 | /* Convert the binary string to hex representation. Outbuf must be
59 | * at least sizeof(hashbuf) * 2 + 1
60 | * Returns 0 on fail, 1 on success
61 | */
62 | printf("TEST TWO: Convert binary output to hex\n");
63 | retval = libscrypt_hexconvert(hashbuf, sizeof(hashbuf), outbuf, sizeof(outbuf));
64 | if(!retval)
65 | {
66 | printf("TEST TWO: FAILED\n");
67 | exit(EXIT_FAILURE);
68 | }
69 | printf("TEST TWO: SUCCESSFUL, Hex output is:\n%s\n", outbuf);
70 |
71 | printf("TEST THREE: Compare hex output to reference hash output\n");
72 |
73 | /* REF1 is a reference vector from Colin's implementation. */
74 | if(strcmp(outbuf, REF1) != 0)
75 | {
76 | printf("TEST THREE: FAILED to match reference on hash\n");
77 | exit(EXIT_FAILURE);
78 | }
79 | else
80 | {
81 | printf("TEST THREE: SUCCESSUL, Test vector matched!\n");
82 | }
83 |
84 | printf("TEST FOUR: Direct call to reference function with pleaseletmein password and SodiumChloride as salt\n");
85 |
86 | /* Tests 4-6 repeat tests 1-3 with a different reference vector */
87 |
88 | retval = libscrypt_scrypt((uint8_t*)"pleaseletmein",strlen("pleaseletmein"), (uint8_t*)"SodiumChloride", strlen("SodiumChloride"), 16384, 8, 1, hashbuf, sizeof(hashbuf));
89 |
90 | if(retval != 0)
91 | {
92 | printf("TEST FOUR FAILED: Failed to create hash of 'pleaseletmein'\n");
93 | exit(EXIT_FAILURE);
94 | }
95 |
96 | printf("TEST FOUR: SUCCESSFUL\n");
97 |
98 | /* Convert the binary string to hex representation. Outbuf must be
99 | * at least sizeof(hashbuf) * 2 + 1
100 | */
101 | printf("TEST FIVE: Convert binary output to hex\n");
102 | retval = libscrypt_hexconvert(hashbuf, sizeof(hashbuf), outbuf, sizeof(outbuf));
103 | if(!retval)
104 | {
105 | printf("TEST FIVE: FAILED\n");
106 | exit(EXIT_FAILURE);
107 | }
108 | printf("TEST FIVE: SUCCESSFUL, Hex output is:\n%s\n", outbuf);
109 |
110 | printf("TEST SIX: Compare hex output to reference hash output\n");
111 |
112 | if(strcmp(outbuf, REF2) != 0)
113 | {
114 | printf("TEST SIX: FAILED to match reference on hash\n");
115 | exit(EXIT_FAILURE);
116 | }
117 | else
118 | {
119 | printf("TEST SIX: SUCCESSUL, Test vector matched!\n");
120 | }
121 |
122 | /* This function will convert the binary output to BASE64. Although
123 | * we converted to hex for the reference vectors, BASE64 is more useful.
124 | * Returns -1 on error, else returns length.
125 | * Correct buffer length can be determined using the below function if
126 | retuired.
127 | * char* dest = (char*) malloc(modp_b64_encode_len);
128 | * Note that this is not an exported function
129 | */
130 |
131 | printf("TEST SEVEN: BASE64 encoding the salt and hash output\n");
132 |
133 | retval = libscrypt_b64_encode(hashbuf, sizeof(hashbuf), outbuf, sizeof(outbuf));
134 | if(retval == -1)
135 | {
136 | printf("TEST SEVEN FAILED\n");
137 | exit(EXIT_FAILURE);
138 | }
139 | retval = libscrypt_b64_encode((unsigned char*)"SodiumChloride", strlen("SodiumChloride"), saltbuf, sizeof(saltbuf));
140 | if(retval == -1)
141 | {
142 | printf("TEST SEVEN FAILED\n");
143 | exit(EXIT_FAILURE);
144 | }
145 |
146 | printf("TEST SEVEN: SUCCESSFUL\n");
147 |
148 | printf("TEST EIGHT: Create an MCF format output\n");
149 |
150 | /* Creates a standard format output
151 | * int crypto_scrypt_mcf(uint32_t N, uint32_t r, uint32_t p, char *salt, char *hash, char *mcf);
152 | * Returns 0 on error, most likely reason is log2(N) not an integer.
153 | */
154 | retval = libscrypt_mcf(16384, 8, 1, saltbuf, outbuf, mcf);
155 | if(!retval)
156 | {
157 | printf("TEST EIGHT FAILED\n");
158 | exit(EXIT_FAILURE);
159 | }
160 |
161 | printf("TEST EIGHT: SUCCESSFUL, calculated mcf\n%s\n", mcf);
162 |
163 | /* Since later calls to scrypt_check() butcher mcf, make a second */
164 | strcpy(mcf2, mcf);
165 |
166 | /* Couldn't be simpler - for a given mcf, check is the password is valid
167 | * Returns < 0 on failure to calculate hash
168 | * 0 if password incorrect
169 | * >1 if password correct
170 | */
171 |
172 | printf("TEST NINE: Password verify on given MCF\n");
173 | retval = libscrypt_check(mcf, "pleaseletmein");
174 |
175 | if(retval < 0)
176 | {
177 | printf("TEST NINE: FAILED, hash failed to calculate\n");
178 | exit(EXIT_FAILURE);
179 | }
180 | if(retval == 0)
181 | {
182 | printf("TEST NINE: FAILED, claimed pleaseletmein hash claimed did not verify\n");
183 | exit(EXIT_FAILURE);
184 | }
185 | /* retval >0 is a success */
186 | printf("TEST NINE: SUCCESSFUL, tested pleaseletmein password\n");
187 |
188 | printf("TEST TEN: Password verify on same MCF, incorrect password\n");
189 | retval = libscrypt_check(mcf2, "pleasefailme");
190 |
191 | if(retval < 0)
192 | {
193 | printf("TEST TEN: FAILED, hash failed to calculate\n");
194 | exit(EXIT_FAILURE);
195 | }
196 | if(retval > 0)
197 | {
198 | printf("TEST TEN: FAILED, fail hash has passed\n");
199 | exit(EXIT_FAILURE);
200 | }
201 |
202 | printf("TEST TEN: SUCCESSFUL, refused incorrect password\n");
203 |
204 | printf("TEST ELEVEN: Testing salt generator\n");
205 |
206 | retval = libscrypt_salt_gen((uint8_t*)saltbuf, SCRYPT_SALT_LEN);
207 | if(retval == -1)
208 | {
209 | printf("TEST ELEVEN (salt generate) FAILED\n");
210 | exit(EXIT_FAILURE);
211 | }
212 |
213 | retval = libscrypt_b64_encode((uint8_t*)saltbuf, SCRYPT_SALT_LEN, outbuf, sizeof(outbuf));
214 | if(retval == -1)
215 | {
216 | printf("TEST ELEVEN (b64 encode) FAILED\n");
217 | exit(EXIT_FAILURE);
218 | }
219 | printf("TEST ELEVEN: SUCCESSFUL, Generated %s\n", outbuf);
220 |
221 | printf("TEST TWELVE: Simple hash creation\n");
222 |
223 | retval = libscrypt_hash(outbuf, "My cats's breath smells like cat food", SCRYPT_N, SCRYPT_r, SCRYPT_p);
224 | if(!retval)
225 | {
226 | printf("TEST TWELVE: FAILED, Failed to create simple hash\n");
227 | exit(EXIT_FAILURE);
228 | }
229 | printf("TEST TWELVE: SUCCESSFUL. Received the following from simple hash:\n%s\n", outbuf);
230 |
231 | printf("TEST THIRTEEN: Verify test twelve's hash\n");
232 |
233 | retval = libscrypt_check(outbuf, "My cats's breath smells like cat food");
234 |
235 | if (retval != 1) {
236 | printf("TEST THIRTEEN: FAILED, hash not verified\n");
237 | exit(EXIT_FAILURE);
238 | }
239 |
240 | printf("TEST THIRTEEN: SUCCESSFUL\n");
241 |
242 | return 0;
243 | }
244 |
245 |
--------------------------------------------------------------------------------
/src/libscrypt/sha256.c:
--------------------------------------------------------------------------------
1 | /*-
2 | * Copyright 2005,2007,2009 Colin Percival
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | * 1. Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | * 2. Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 | * SUCH DAMAGE.
25 | */
26 |
27 | #include
28 |
29 | #include
30 | #include
31 |
32 | #include "sysendian.h"
33 |
34 | #include "sha256.h"
35 |
36 | /*
37 | * Encode a length len/4 vector of (uint32_t) into a length len vector of
38 | * (unsigned char) in big-endian form. Assumes len is a multiple of 4.
39 | */
40 | static void
41 | be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
42 | {
43 | size_t i;
44 |
45 | for (i = 0; i < len / 4; i++)
46 | be32enc(dst + i * 4, src[i]);
47 | }
48 |
49 | /*
50 | * Decode a big-endian length len vector of (unsigned char) into a length
51 | * len/4 vector of (uint32_t). Assumes len is a multiple of 4.
52 | */
53 | static void
54 | be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
55 | {
56 | size_t i;
57 |
58 | for (i = 0; i < len / 4; i++)
59 | dst[i] = be32dec(src + i * 4);
60 | }
61 |
62 | /* Elementary functions used by SHA256 */
63 | #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
64 | #define Maj(x, y, z) ((x & (y | z)) | (y & z))
65 | #define SHR(x, n) (x >> n)
66 | #define ROTR(x, n) ((x >> n) | (x << (32 - n)))
67 | #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
68 | #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
69 | #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
70 | #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
71 |
72 | /* SHA256 round function */
73 | #define RND(a, b, c, d, e, f, g, h, k) \
74 | t0 = h + S1(e) + Ch(e, f, g) + k; \
75 | t1 = S0(a) + Maj(a, b, c); \
76 | d += t0; \
77 | h = t0 + t1;
78 |
79 | /* Adjusted round function for rotating state */
80 | #define RNDr(S, W, i, k) \
81 | RND(S[(64 - i) % 8], S[(65 - i) % 8], \
82 | S[(66 - i) % 8], S[(67 - i) % 8], \
83 | S[(68 - i) % 8], S[(69 - i) % 8], \
84 | S[(70 - i) % 8], S[(71 - i) % 8], \
85 | W[i] + k)
86 |
87 | /*
88 | * SHA256 block compression function. The 256-bit state is transformed via
89 | * the 512-bit input block to produce a new state.
90 | */
91 | static void
92 | SHA256_Transform(uint32_t * state, const unsigned char block[64])
93 | {
94 | uint32_t W[64];
95 | uint32_t S[8];
96 | uint32_t t0, t1;
97 | int i;
98 |
99 | /* 1. Prepare message schedule W. */
100 | be32dec_vect(W, block, 64);
101 | for (i = 16; i < 64; i++)
102 | W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
103 |
104 | /* 2. Initialize working variables. */
105 | memcpy(S, state, 32);
106 |
107 | /* 3. Mix. */
108 | RNDr(S, W, 0, 0x428a2f98);
109 | RNDr(S, W, 1, 0x71374491);
110 | RNDr(S, W, 2, 0xb5c0fbcf);
111 | RNDr(S, W, 3, 0xe9b5dba5);
112 | RNDr(S, W, 4, 0x3956c25b);
113 | RNDr(S, W, 5, 0x59f111f1);
114 | RNDr(S, W, 6, 0x923f82a4);
115 | RNDr(S, W, 7, 0xab1c5ed5);
116 | RNDr(S, W, 8, 0xd807aa98);
117 | RNDr(S, W, 9, 0x12835b01);
118 | RNDr(S, W, 10, 0x243185be);
119 | RNDr(S, W, 11, 0x550c7dc3);
120 | RNDr(S, W, 12, 0x72be5d74);
121 | RNDr(S, W, 13, 0x80deb1fe);
122 | RNDr(S, W, 14, 0x9bdc06a7);
123 | RNDr(S, W, 15, 0xc19bf174);
124 | RNDr(S, W, 16, 0xe49b69c1);
125 | RNDr(S, W, 17, 0xefbe4786);
126 | RNDr(S, W, 18, 0x0fc19dc6);
127 | RNDr(S, W, 19, 0x240ca1cc);
128 | RNDr(S, W, 20, 0x2de92c6f);
129 | RNDr(S, W, 21, 0x4a7484aa);
130 | RNDr(S, W, 22, 0x5cb0a9dc);
131 | RNDr(S, W, 23, 0x76f988da);
132 | RNDr(S, W, 24, 0x983e5152);
133 | RNDr(S, W, 25, 0xa831c66d);
134 | RNDr(S, W, 26, 0xb00327c8);
135 | RNDr(S, W, 27, 0xbf597fc7);
136 | RNDr(S, W, 28, 0xc6e00bf3);
137 | RNDr(S, W, 29, 0xd5a79147);
138 | RNDr(S, W, 30, 0x06ca6351);
139 | RNDr(S, W, 31, 0x14292967);
140 | RNDr(S, W, 32, 0x27b70a85);
141 | RNDr(S, W, 33, 0x2e1b2138);
142 | RNDr(S, W, 34, 0x4d2c6dfc);
143 | RNDr(S, W, 35, 0x53380d13);
144 | RNDr(S, W, 36, 0x650a7354);
145 | RNDr(S, W, 37, 0x766a0abb);
146 | RNDr(S, W, 38, 0x81c2c92e);
147 | RNDr(S, W, 39, 0x92722c85);
148 | RNDr(S, W, 40, 0xa2bfe8a1);
149 | RNDr(S, W, 41, 0xa81a664b);
150 | RNDr(S, W, 42, 0xc24b8b70);
151 | RNDr(S, W, 43, 0xc76c51a3);
152 | RNDr(S, W, 44, 0xd192e819);
153 | RNDr(S, W, 45, 0xd6990624);
154 | RNDr(S, W, 46, 0xf40e3585);
155 | RNDr(S, W, 47, 0x106aa070);
156 | RNDr(S, W, 48, 0x19a4c116);
157 | RNDr(S, W, 49, 0x1e376c08);
158 | RNDr(S, W, 50, 0x2748774c);
159 | RNDr(S, W, 51, 0x34b0bcb5);
160 | RNDr(S, W, 52, 0x391c0cb3);
161 | RNDr(S, W, 53, 0x4ed8aa4a);
162 | RNDr(S, W, 54, 0x5b9cca4f);
163 | RNDr(S, W, 55, 0x682e6ff3);
164 | RNDr(S, W, 56, 0x748f82ee);
165 | RNDr(S, W, 57, 0x78a5636f);
166 | RNDr(S, W, 58, 0x84c87814);
167 | RNDr(S, W, 59, 0x8cc70208);
168 | RNDr(S, W, 60, 0x90befffa);
169 | RNDr(S, W, 61, 0xa4506ceb);
170 | RNDr(S, W, 62, 0xbef9a3f7);
171 | RNDr(S, W, 63, 0xc67178f2);
172 |
173 | /* 4. Mix local working variables into global state */
174 | for (i = 0; i < 8; i++)
175 | state[i] += S[i];
176 |
177 | /* Clean the stack. */
178 | memset(W, 0, 256);
179 | memset(S, 0, 32);
180 | t0 = t1 = 0;
181 | }
182 |
183 | static unsigned char PAD[64] = {
184 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
185 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
188 | };
189 |
190 | /* Add padding and terminating bit-count. */
191 | static void
192 | SHA256_Pad(SHA256_CTX * ctx)
193 | {
194 | unsigned char len[8];
195 | uint32_t r, plen;
196 |
197 | /*
198 | * Convert length to a vector of bytes -- we do this now rather
199 | * than later because the length will change after we pad.
200 | */
201 | be32enc_vect(len, ctx->count, 8);
202 |
203 | /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
204 | r = (ctx->count[1] >> 3) & 0x3f;
205 | plen = (r < 56) ? (56 - r) : (120 - r);
206 | libscrypt_SHA256_Update(ctx, PAD, (size_t)plen);
207 |
208 | /* Add the terminating bit-count */
209 | libscrypt_SHA256_Update(ctx, len, 8);
210 | }
211 |
212 | /* SHA-256 initialization. Begins a SHA-256 operation. */
213 | void
214 | libscrypt_SHA256_Init(SHA256_CTX * ctx)
215 | {
216 |
217 | /* Zero bits processed so far */
218 | ctx->count[0] = ctx->count[1] = 0;
219 |
220 | /* Magic initialization constants */
221 | ctx->state[0] = 0x6A09E667;
222 | ctx->state[1] = 0xBB67AE85;
223 | ctx->state[2] = 0x3C6EF372;
224 | ctx->state[3] = 0xA54FF53A;
225 | ctx->state[4] = 0x510E527F;
226 | ctx->state[5] = 0x9B05688C;
227 | ctx->state[6] = 0x1F83D9AB;
228 | ctx->state[7] = 0x5BE0CD19;
229 | }
230 |
231 | /* Add bytes into the hash */
232 | void
233 | libscrypt_SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
234 | {
235 | uint32_t bitlen[2];
236 | uint32_t r;
237 | const unsigned char *src = in;
238 |
239 | /* Number of bytes left in the buffer from previous updates */
240 | r = (ctx->count[1] >> 3) & 0x3f;
241 |
242 | /* Convert the length into a number of bits */
243 | bitlen[1] = ((uint32_t)len) << 3;
244 | bitlen[0] = (uint32_t)(len >> 29);
245 |
246 | /* Update number of bits */
247 | if ((ctx->count[1] += bitlen[1]) < bitlen[1])
248 | ctx->count[0]++;
249 | ctx->count[0] += bitlen[0];
250 |
251 | /* Handle the case where we don't need to perform any transforms */
252 | if (len < 64 - r) {
253 | memcpy(&ctx->buf[r], src, len);
254 | return;
255 | }
256 |
257 | /* Finish the current block */
258 | memcpy(&ctx->buf[r], src, 64 - r);
259 | SHA256_Transform(ctx->state, ctx->buf);
260 | src += 64 - r;
261 | len -= 64 - r;
262 |
263 | /* Perform complete blocks */
264 | while (len >= 64) {
265 | SHA256_Transform(ctx->state, src);
266 | src += 64;
267 | len -= 64;
268 | }
269 |
270 | /* Copy left over data into buffer */
271 | memcpy(ctx->buf, src, len);
272 | }
273 |
274 | /*
275 | * SHA-256 finalization. Pads the input data, exports the hash value,
276 | * and clears the context state.
277 | */
278 | void
279 | libscrypt_SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
280 | {
281 |
282 | /* Add padding */
283 | SHA256_Pad(ctx);
284 |
285 | /* Write the hash */
286 | be32enc_vect(digest, ctx->state, 32);
287 |
288 | /* Clear the context state */
289 | memset((void *)ctx, 0, sizeof(*ctx));
290 | }
291 |
292 | /* Initialize an HMAC-SHA256 operation with the given key. */
293 | void
294 | libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
295 | {
296 | unsigned char pad[64];
297 | unsigned char khash[32];
298 | const unsigned char * K = _K;
299 | size_t i;
300 |
301 | /* If Klen > 64, the key is really SHA256(K). */
302 | if (Klen > 64) {
303 | libscrypt_SHA256_Init(&ctx->ictx);
304 | libscrypt_SHA256_Update(&ctx->ictx, K, Klen);
305 | libscrypt_SHA256_Final(khash, &ctx->ictx);
306 | K = khash;
307 | Klen = 32;
308 | }
309 |
310 | /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
311 | libscrypt_SHA256_Init(&ctx->ictx);
312 | memset(pad, 0x36, 64);
313 | for (i = 0; i < Klen; i++)
314 | pad[i] ^= K[i];
315 | libscrypt_SHA256_Update(&ctx->ictx, pad, 64);
316 |
317 | /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
318 | libscrypt_SHA256_Init(&ctx->octx);
319 | memset(pad, 0x5c, 64);
320 | for (i = 0; i < Klen; i++)
321 | pad[i] ^= K[i];
322 | libscrypt_SHA256_Update(&ctx->octx, pad, 64);
323 |
324 | /* Clean the stack. */
325 | memset(khash, 0, 32);
326 | }
327 |
328 | /* Add bytes to the HMAC-SHA256 operation. */
329 | void
330 | libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
331 | {
332 |
333 | /* Feed data to the inner SHA256 operation. */
334 | libscrypt_SHA256_Update(&ctx->ictx, in, len);
335 | }
336 |
337 | /* Finish an HMAC-SHA256 operation. */
338 | void
339 | libscrypt_HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
340 | {
341 | unsigned char ihash[32];
342 |
343 | /* Finish the inner SHA256 operation. */
344 | libscrypt_SHA256_Final(ihash, &ctx->ictx);
345 |
346 | /* Feed the inner hash to the outer SHA256 operation. */
347 | libscrypt_SHA256_Update(&ctx->octx, ihash, 32);
348 |
349 | /* Finish the outer SHA256 operation. */
350 | libscrypt_SHA256_Final(digest, &ctx->octx);
351 |
352 | /* Clean the stack. */
353 | memset(ihash, 0, 32);
354 | }
355 |
356 | /**
357 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
358 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
359 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
360 | */
361 | void
362 | libscrypt_PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
363 | size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
364 | {
365 | HMAC_SHA256_CTX PShctx, hctx;
366 | size_t i;
367 | uint8_t ivec[4];
368 | uint8_t U[32];
369 | uint8_t T[32];
370 | uint64_t j;
371 | int k;
372 | size_t clen;
373 |
374 | /* Compute HMAC state after processing P and S. */
375 | libscrypt_HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
376 | libscrypt_HMAC_SHA256_Update(&PShctx, salt, saltlen);
377 |
378 | /* Iterate through the blocks. */
379 | for (i = 0; i * 32 < dkLen; i++) {
380 | /* Generate INT(i + 1). */
381 | be32enc(ivec, (uint32_t)(i + 1));
382 |
383 | /* Compute U_1 = PRF(P, S || INT(i)). */
384 | memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
385 | libscrypt_HMAC_SHA256_Update(&hctx, ivec, 4);
386 | libscrypt_HMAC_SHA256_Final(U, &hctx);
387 |
388 | /* T_i = U_1 ... */
389 | memcpy(T, U, 32);
390 |
391 | for (j = 2; j <= c; j++) {
392 | /* Compute U_j. */
393 | libscrypt_HMAC_SHA256_Init(&hctx, passwd, passwdlen);
394 | libscrypt_HMAC_SHA256_Update(&hctx, U, 32);
395 | libscrypt_HMAC_SHA256_Final(U, &hctx);
396 |
397 | /* ... xor U_j ... */
398 | for (k = 0; k < 32; k++)
399 | T[k] ^= U[k];
400 | }
401 |
402 | /* Copy as many bytes as necessary into buf. */
403 | clen = dkLen - i * 32;
404 | if (clen > 32)
405 | clen = 32;
406 | memcpy(&buf[i * 32], T, clen);
407 | }
408 |
409 | /* Clean PShctx, since we never called _Final on it. */
410 | memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
411 | }
412 |
--------------------------------------------------------------------------------
/src/libscrypt/sha256.h:
--------------------------------------------------------------------------------
1 | /*-
2 | * Copyright 2005,2007,2009 Colin Percival
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | * 1. Redistributions of source code must retain the above copyright
9 | * notice, this list of conditions and the following disclaimer.
10 | * 2. Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | *
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 | * SUCH DAMAGE.
25 | *
26 | * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $
27 | */
28 |
29 | #ifndef _SHA256_H_
30 | #define _SHA256_H_
31 |
32 | #include
33 |
34 | #include
35 |
36 | typedef struct libscrypt_SHA256Context {
37 | uint32_t state[8];
38 | uint32_t count[2];
39 | unsigned char buf[64];
40 | } SHA256_CTX;
41 |
42 | typedef struct libscrypt_HMAC_SHA256Context {
43 | SHA256_CTX ictx;
44 | SHA256_CTX octx;
45 | } HMAC_SHA256_CTX;
46 |
47 | void libscrypt_SHA256_Init(/*@out@*/ SHA256_CTX *);
48 | void libscrypt_SHA256_Update(SHA256_CTX *, const void *, size_t);
49 |
50 | /* Original declaration:
51 | * void SHA256_Final(unsigned char [32], SHA256_CTX *);
52 | */
53 | void libscrypt_SHA256_Final(/*@out@*/ unsigned char [], SHA256_CTX *);
54 | void libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
55 | void libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
56 |
57 | /* Original declaration:
58 | * void HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
59 | */
60 | void libscrypt_HMAC_SHA256_Final(unsigned char [], HMAC_SHA256_CTX *);
61 |
62 | /**
63 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
64 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
65 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
66 | */
67 | void libscrypt_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
68 | uint64_t, uint8_t *, size_t);
69 |
70 | #endif /* !_SHA256_H_ */
71 |
--------------------------------------------------------------------------------
/src/libscrypt/slowequals.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /* Implements a constant time version of strcmp()
4 | * Will return 1 if a and b are equal, 0 if they are not */
5 | int slow_equals(const char* a, const char* b)
6 | {
7 | size_t lena, lenb, diff, i;
8 | lena = strlen(a);
9 | lenb = strlen(b);
10 | diff = strlen(a) ^ strlen(b);
11 |
12 | for(i=0; i we have isn't usable. */
34 | #if !HAVE_DECL_BE64ENC
35 | #undef HAVE_SYS_ENDIAN_H
36 | #endif
37 |
38 | #ifdef HAVE_SYS_ENDIAN_H
39 |
40 | #include
41 |
42 | #else
43 |
44 | #include
45 | #ifdef _MSC_VER
46 | #define INLINE __inline
47 | #else
48 | #define INLINE inline
49 | #endif
50 |
51 | static INLINE uint32_t
52 | be32dec(const void *pp)
53 | {
54 | const uint8_t *p = (uint8_t const *)pp;
55 |
56 | return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
57 | ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
58 | }
59 |
60 | static INLINE void
61 | be32enc(void *pp, uint32_t x)
62 | {
63 | uint8_t * p = (uint8_t *)pp;
64 |
65 | p[3] = x & 0xff;
66 | p[2] = (x >> 8) & 0xff;
67 | p[1] = (x >> 16) & 0xff;
68 | p[0] = (x >> 24) & 0xff;
69 | }
70 |
71 | static INLINE uint64_t
72 | be64dec(const void *pp)
73 | {
74 | const uint8_t *p = (uint8_t const *)pp;
75 |
76 | return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
77 | ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
78 | ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
79 | ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
80 | }
81 |
82 | static INLINE void
83 | be64enc(void *pp, uint64_t x)
84 | {
85 | uint8_t * p = (uint8_t *)pp;
86 |
87 | p[7] = x & 0xff;
88 | p[6] = (x >> 8) & 0xff;
89 | p[5] = (x >> 16) & 0xff;
90 | p[4] = (x >> 24) & 0xff;
91 | p[3] = (x >> 32) & 0xff;
92 | p[2] = (x >> 40) & 0xff;
93 | p[1] = (x >> 48) & 0xff;
94 | p[0] = (x >> 56) & 0xff;
95 | }
96 |
97 | static INLINE uint32_t
98 | le32dec(const void *pp)
99 | {
100 | const uint8_t *p = (uint8_t const *)pp;
101 |
102 | return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
103 | ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
104 | }
105 |
106 | static INLINE void
107 | le32enc(void *pp, uint32_t x)
108 | {
109 | uint8_t * p = (uint8_t *)pp;
110 |
111 | p[0] = x & 0xff;
112 | p[1] = (x >> 8) & 0xff;
113 | p[2] = (x >> 16) & 0xff;
114 | p[3] = (x >> 24) & 0xff;
115 | }
116 |
117 | static INLINE uint64_t
118 | le64dec(const void *pp)
119 | {
120 | const uint8_t *p = (uint8_t const *)pp;
121 |
122 | return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
123 | ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
124 | ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
125 | ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
126 | }
127 |
128 | static INLINE void
129 | le64enc(void *pp, uint64_t x)
130 | {
131 | uint8_t * p = (uint8_t *)pp;
132 |
133 | p[0] = x & 0xff;
134 | p[1] = (x >> 8) & 0xff;
135 | p[2] = (x >> 16) & 0xff;
136 | p[3] = (x >> 24) & 0xff;
137 | p[4] = (x >> 32) & 0xff;
138 | p[5] = (x >> 40) & 0xff;
139 | p[6] = (x >> 48) & 0xff;
140 | p[7] = (x >> 56) & 0xff;
141 | }
142 | #endif /* !HAVE_SYS_ENDIAN_H */
143 |
144 | #endif /* !_SYSENDIAN_H_ */
145 |
--------------------------------------------------------------------------------
/testing.config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Scrypt tests
4 |
5 |
6 |
7 | Crypho AS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cordova-plugin-scrypt-tests",
3 | "version": "1.0.0",
4 | "description": "Tests for cordova-plugin-scrypt",
5 | "author": "Yiorgis Gozadinos ",
6 | "cordova": {
7 | "id": "cordova-plugin-scrypt",
8 | "platforms": [
9 | "android",
10 | "ios"
11 | ]
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/crypho/cordova-plugin-scrypt.git"
16 | },
17 | "devDependencies": {
18 | "cordova-plugin-test-framework": ">=1.0.0"
19 | },
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/crypho/cordova-plugin-scrypt/issues"
23 | },
24 | "homepage": "https://github.com/crypho/cordova-plugin-scrypt#readme"
25 | }
26 |
--------------------------------------------------------------------------------
/tests/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | ScryptPlugin Tests
8 | Crypho AS
9 |
10 |
11 | Test for cordova-plugin-scrypt
12 |
13 |
14 | MIT
15 |
16 | scrypt, encryption, tests
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/tests.js:
--------------------------------------------------------------------------------
1 | var testCases = [
2 | {
3 | "salt": [207, 45, 55, 220, 196, 92, 83, 32],
4 | "password": "hello",
5 | "p": 1,
6 | "expected": "6907e763e5fd22fcce6f1fa74498b1580cfe8233746c39a0cafae86b9ee34214"
7 | },
8 | {
9 | "salt": "salt",
10 | "password": "password",
11 | "N": 2,
12 | "r": 1,
13 | "p": 1,
14 | "dkLen": 32,
15 | "expected": "6d1bb878eee9ce4a7b77d7a44103574d4cbfe3c15ae3940f0ffe75cd5e1e0afa"
16 | },
17 | {
18 | "salt": "salt",
19 | "password": "password",
20 | "N": 2,
21 | "r": 2,
22 | "p": 1,
23 | "dkLen": 32,
24 | "expected": "b6902e4c128feb4b3a475d59773bc4b25e44080cea51d7526b18986c52008386"
25 | },
26 | {
27 | "salt": "salt",
28 | "password": "password",
29 | "N": 2,
30 | "r": 1,
31 | "p": 1,
32 | "dkLen": 32,
33 | "expected": "6d1bb878eee9ce4a7b77d7a44103574d4cbfe3c15ae3940f0ffe75cd5e1e0afa"
34 | },
35 | {
36 | "salt": "salt",
37 | "password": "password",
38 | "N": 2,
39 | "r": 1,
40 | "p": 2,
41 | "dkLen": 32,
42 | "expected": "4db52954f6ece830ebef61b6613b9f1dfd921922d32a1af5b719d15a6676e8ad"
43 | },
44 | {
45 | "salt": "salt",
46 | "password": "password",
47 | "N": 2,
48 | "r": 2,
49 | "p": 1,
50 | "dkLen": 32,
51 | "expected": "b6902e4c128feb4b3a475d59773bc4b25e44080cea51d7526b18986c52008386"
52 | },
53 | {
54 | "salt": "salt",
55 | "password": "password",
56 | "N": 4,
57 | "r": 1,
58 | "p": 1,
59 | "dkLen": 32,
60 | "expected": "2ef4390d867dcad84fbb1c064e7fe984e1e9850922ac45c11b2f30c85043f9bd"
61 | },
62 | {
63 | "salt": "salt",
64 | "password": "password",
65 | "N": 2,
66 | "r": 1,
67 | "p": 1,
68 | "dkLen": 48,
69 | "expected": "6d1bb878eee9ce4a7b77d7a44103574d4cbfe3c15ae3940f0ffe75cd5e1e0afadb0a556b482b5dcb0d1a54b6e4070beb"
70 | },
71 | {
72 | "salt": "salt",
73 | "password": "password",
74 | "N": 4,
75 | "r": 2,
76 | "p": 2,
77 | "dkLen": 48,
78 | "expected": "89d93e71c0cae21fb524624e6e0229ecae4fb727fb8e5b5f705aaed078aa455fba9e2186b6d5c7dcd7c9561affefd597"
79 | },
80 | {
81 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
82 | "password": "passwordPASSWORDpassword",
83 | "N": 2,
84 | "r": 1,
85 | "p": 1,
86 | "dkLen": 32,
87 | "expected": "2e40cbd0f2e5b348d11b25ce977f572c20bbb133b188c5b182f939e92f5581c1"
88 | },
89 | {
90 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
91 | "password": "passwordPASSWORDpassword",
92 | "N": 2,
93 | "r": 1,
94 | "p": 2,
95 | "dkLen": 32,
96 | "expected": "b8f439cd39d8c2db78fbc6846bbe4c7af559039af2a44140f4648333bd706a9f"
97 | },
98 | {
99 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
100 | "password": "passwordPASSWORDpassword",
101 | "N": 2,
102 | "r": 2,
103 | "p": 1,
104 | "dkLen": 32,
105 | "expected": "60ecb015fc3e8ee29c05253d3827639cee3163ba9e724e84675be7923101aba6"
106 | },
107 | {
108 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
109 | "password": "passwordPASSWORDpassword",
110 | "N": 4,
111 | "r": 1,
112 | "p": 1,
113 | "dkLen": 32,
114 | "expected": "0ca4071216a28c62c86e9b6499de4df73db413cb8f6af8e7210dbedb908340d3"
115 | },
116 | {
117 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
118 | "password": "passwordPASSWORDpassword",
119 | "N": 2,
120 | "r": 1,
121 | "p": 1,
122 | "dkLen": 48,
123 | "expected": "2e40cbd0f2e5b348d11b25ce977f572c20bbb133b188c5b182f939e92f5581c16f89084a1ceea4d5b52050498bd94ba5"
124 | },
125 | {
126 | "salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt",
127 | "password": "passwordPASSWORDpassword",
128 | "N": 4,
129 | "r": 2,
130 | "p": 2,
131 | "dkLen": 48,
132 | "expected": "e5f5bce126455eec251b65667e0feb532b07ffcf56164c1b7e81e6cdd88a647cf679d16a7fe8d640de40028df832fd19"
133 | },
134 | {
135 | "salt": "",
136 | "password": "",
137 | "N": 16,
138 | "r": 1,
139 | "p": 1,
140 | "dkLen": 64,
141 | "expected": "77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906"
142 | },
143 | {
144 | "salt": "NaCl", // heh
145 | "password": "password",
146 | "N": 1024,
147 | "r": 8,
148 | "p": 16,
149 | "dkLen": 64,
150 | "expected": "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"
151 | },
152 | {
153 | "salt": "SodiumChloride",
154 | "password": "pleaseletmein",
155 | "N": 16384,
156 | "r": 8,
157 | "p": 1,
158 | "dkLen": 64,
159 | "expected": "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"
160 | },
161 | {
162 | "salt": "salt",
163 | "password": "Hellø",
164 | "N": 2,
165 | "r": 1,
166 | "p": 1,
167 | "dkLen": 64,
168 | "expected": "6837d88873b164bf5692e878fb0f20bd4a1cdc29f5f48a57e94a298984cbc661cb539e2a868498bee67a7a277d962d06ba1d45325eb1c756ff8f685bbacf585a"
169 | }
170 |
171 |
172 |
173 | ];
174 |
175 | exports.defineAutoTests = function() {
176 | describe('cordova-plugin-scrypt', function () {
177 |
178 | it("should be defined", function() {
179 | expect(window.plugins.scrypt).toBeDefined();
180 | });
181 |
182 | it('derives the right keys from test vectors', function (done) {
183 | var count = 0;
184 | var fail = jasmine.createSpy('fail');
185 | testCases.forEach(function (testCase) {
186 | window.plugins.scrypt(
187 | function(res){
188 | expect(res).toEqual(testCase.expected);
189 | count++;
190 | if (count === testCases.length) done();
191 | },
192 | function (err) {
193 | fail(err);
194 | count++;
195 | expect(fail).not.toHaveBeenCalled();
196 | if (count === testCases.length) done();
197 | },
198 | testCase.password,
199 | testCase.salt,
200 | testCase
201 | );
202 | });
203 | });
204 | });
205 | };
206 |
--------------------------------------------------------------------------------
/www/scrypt.js:
--------------------------------------------------------------------------------
1 | var scrypt = function(successCallback, errorCallback, message, salt, options) {
2 | if (typeof errorCallback != "function") {
3 | console.log("ScryptPlugin.scrypt failure: failure parameter not a function");
4 | return;
5 | }
6 |
7 | if (typeof successCallback != "function") {
8 | console.log("ScryptPlugin.scrypt failure: success callback parameter must be a function");
9 | return;
10 | }
11 | options = options || {};
12 | cordova.exec(successCallback, errorCallback, "ScryptPlugin", "scrypt", [message, salt, options]);
13 | };
14 |
15 |
16 | if(!window.plugins) {
17 | window.plugins = {};
18 | }
19 | if (!window.plugins.scrypt) {
20 | window.plugins.scrypt = scrypt;
21 | }
22 |
23 | if (typeof module != 'undefined' && module.exports) {
24 | module.exports = scrypt;
25 | }
--------------------------------------------------------------------------------