├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── themes.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── values-night │ │ │ │ └── themes.xml │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── jni │ │ │ │ └── encrypt │ │ │ │ ├── MainActivity.java │ │ │ │ └── AESEncrypt.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── jni │ │ │ └── encrypt │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── jni │ │ └── encrypt │ │ ├── ExampleInstrumentedTest.java │ │ └── EncryptPerformanceTest.java ├── proguard-rules.pro └── build.gradle ├── NativeEncrypt ├── .gitignore ├── consumer-rules.pro ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── cpp │ │ │ ├── include │ │ │ │ ├── base │ │ │ │ │ └── log.h │ │ │ │ └── openssl │ │ │ │ │ ├── aes.h │ │ │ │ │ └── modes.h │ │ │ ├── crypto │ │ │ │ ├── aes │ │ │ │ │ ├── aes_misc.c │ │ │ │ │ ├── aes_ofb.c │ │ │ │ │ ├── aes_ecb.c │ │ │ │ │ ├── aes_cbc.c │ │ │ │ │ ├── aes_wrap.c │ │ │ │ │ ├── aes_local.h │ │ │ │ │ ├── aes_cfb.c │ │ │ │ │ ├── aes_ige.c │ │ │ │ │ └── aes_x86core.c │ │ │ │ └── modes │ │ │ │ │ ├── ofb128.c │ │ │ │ │ ├── cbc128.c │ │ │ │ │ ├── modes_local.h │ │ │ │ │ └── cfb128.c │ │ │ ├── base │ │ │ │ └── log.cpp │ │ │ ├── encode │ │ │ │ ├── base64.h │ │ │ │ └── base64.cpp │ │ │ ├── CMakeLists.txt │ │ │ └── NativeUtil.cpp │ │ └── java │ │ │ └── com │ │ │ └── jni │ │ │ └── encrypt │ │ │ └── NativeUtil.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── jni │ │ │ └── encrypt │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── jni │ │ └── encrypt │ │ ├── ExampleInstrumentedTest.java │ │ ├── EncryptTest.java │ │ └── Base64Test.java ├── proguard-rules.pro └── build.gradle ├── .idea ├── .gitignore ├── compiler.xml ├── vcs.xml ├── misc.xml ├── gradle.xml └── jarRepositories.xml ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── README.md ├── .gitignore ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /NativeEncrypt/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /NativeEncrypt/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':NativeEncrypt' 2 | include ':app' 3 | rootProject.name = "JNIEncrypt" -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | JNIEncrypt 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heqinghqocsh/JNIEncrypt/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JNIEncrypt 2 | 使用JNI实现Base64编解码,AES加解密(从OpenSSL中抽出),非常适合Android端使用,保持了与调用java输出结果相同,可以直接使用。 3 | ## 2020.4.20 4 | 1. 优化了目录结构,其中AES加解密部分的目录结构保持与OpenSSL一致,方便后期抽取其他加解密算法,例如RSA等。 5 | 2. 重新处理了Base64编解码,大大提高了编解码效率。 6 | 3. 加入了基本的单元测试。 7 | 4. 加入了应用包名和签名的验证。 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 08 20:58:34 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/include/base/log.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #ifndef LOG_TAG 5 | #define LOG_TAG "NativeTools-lib" 6 | #endif 7 | 8 | #ifndef LOG_ENABLE 9 | #define LOG_ENABLE true 10 | #endif 11 | 12 | int LogI(const char* fmt, ...); 13 | 14 | int LogD(const char* fmt, ...); 15 | 16 | int LogE(const char* fmt, ...); -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/test/java/com/jni/encrypt/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /NativeEncrypt/src/test/java/com/jni/encrypt/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/jni/encrypt/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | import android.widget.TextView; 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | // Example of a call to a native method 16 | TextView tv = findViewById(R.id.sample_text); 17 | } 18 | } -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include 11 | #include 12 | #include "aes_local.h" 13 | 14 | const char *AES_options(void) 15 | { 16 | #ifdef FULL_UNROLL 17 | return "aes(full)"; 18 | #else 19 | return "aes(partial)"; 20 | #endif 21 | } 22 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/java/com/jni/encrypt/NativeUtil.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.content.Context; 4 | 5 | public class NativeUtil { 6 | 7 | // Used to load the 'native-lib' library on application startup. 8 | static { 9 | System.loadLibrary("NativeTools-lib"); 10 | } 11 | 12 | public static native boolean init(Context appContext); 13 | 14 | public static native String encrypt(String plainText); 15 | 16 | public static native String decrypt(String cipherText); 17 | 18 | public static native String base64Encode(String cipherText,boolean doNewLine); 19 | 20 | public static native String base64Decode(String cipherText); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_ofb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, 14 | size_t length, const AES_KEY *key, 15 | unsigned char *ivec, int *num) 16 | { 17 | CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, 18 | (block128_f) AES_encrypt); 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /NativeEncrypt/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_ecb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include "aes_local.h" 14 | 15 | void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, 16 | const AES_KEY *key, const int enc) 17 | { 18 | 19 | assert(in && out && key); 20 | assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); 21 | 22 | if (AES_ENCRYPT == enc) 23 | AES_encrypt(in, out, key); 24 | else 25 | AES_decrypt(in, out, key); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/jni/encrypt/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.jni.encrypt", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_cbc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 14 | size_t len, const AES_KEY *key, 15 | unsigned char *ivec, const int enc) 16 | { 17 | 18 | if (enc) 19 | CRYPTO_cbc128_encrypt(in, out, len, key, ivec, 20 | (block128_f) AES_encrypt); 21 | else 22 | CRYPTO_cbc128_decrypt(in, out, len, key, ivec, 23 | (block128_f) AES_decrypt); 24 | } 25 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/base/log.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int LogD(const char* fmt, ...) { 5 | if (!LOG_ENABLE){ 6 | return -1; 7 | } 8 | va_list argList; 9 | va_start(argList, fmt); 10 | int result = __android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, fmt, argList); 11 | va_end(argList); 12 | return result; 13 | } 14 | 15 | int LogE(const char* fmt, ...) { 16 | if (!LOG_ENABLE){ 17 | return -1; 18 | } 19 | va_list argList; 20 | va_start(argList, fmt); 21 | int result = __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, fmt, argList); 22 | va_end(argList); 23 | return result; 24 | } 25 | 26 | int LogI(const char* fmt, ...) { 27 | if (!LOG_ENABLE){ 28 | return -1; 29 | } 30 | va_list argList; 31 | va_start(argList, fmt); 32 | int result = __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, fmt, argList); 33 | va_end(argList); 34 | return result; 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 22 | 23 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_wrap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #include "internal/cryptlib.h" 11 | #include 12 | #include 13 | 14 | int AES_wrap_key(AES_KEY *key, const unsigned char *iv, 15 | unsigned char *out, 16 | const unsigned char *in, unsigned int inlen) 17 | { 18 | return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt); 19 | } 20 | 21 | int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, 22 | unsigned char *out, 23 | const unsigned char *in, unsigned int inlen) 24 | { 25 | return CRYPTO_128_unwrap(key, iv, out, in, inlen, 26 | (block128_f) AES_decrypt); 27 | } 28 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | #控制运行哪个模块(app, NativeTools-lib) 22 | runModule=app -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | if (String.valueOf(runModule) == "app") { 2 | apply plugin: 'com.android.application' 3 | } else { 4 | apply plugin: 'com.android.library' 5 | } 6 | 7 | android { 8 | compileSdkVersion 30 9 | buildToolsVersion "30.0.1" 10 | 11 | defaultConfig { 12 | if (String.valueOf(runModule) == "app") { 13 | applicationId "com.jni.encrypt" 14 | } 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode 1 18 | versionName "1.0" 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | } 34 | 35 | dependencies { 36 | 37 | implementation 'androidx.appcompat:appcompat:1.2.0' 38 | implementation 'com.google.android.material:material:1.1.0' 39 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 40 | testImplementation 'junit:junit:4.13.2' 41 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 42 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 43 | androidTestImplementation project(path: ':NativeEncrypt') 44 | } -------------------------------------------------------------------------------- /NativeEncrypt/build.gradle: -------------------------------------------------------------------------------- 1 | if (String.valueOf(runModule) == "NativeTools-lib") { 2 | apply plugin: 'com.android.application' 3 | } else { 4 | apply plugin: 'com.android.library' 5 | } 6 | 7 | android { 8 | compileSdkVersion 30 9 | buildToolsVersion "30.0.1" 10 | 11 | defaultConfig { 12 | if (String.valueOf(runModule) == "NativeTools-lib") { 13 | applicationId "com.jni.encrypt" 14 | } 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode 1 18 | versionName "1.0" 19 | 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | consumerProguardFiles "consumer-rules.pro" 22 | externalNativeBuild { 23 | cmake { 24 | cppFlags "" 25 | } 26 | } 27 | } 28 | 29 | buildTypes { 30 | release { 31 | minifyEnabled false 32 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 33 | } 34 | } 35 | externalNativeBuild { 36 | cmake { 37 | path "src/main/cpp/CMakeLists.txt" 38 | version "3.10.2" 39 | } 40 | } 41 | compileOptions { 42 | sourceCompatibility JavaVersion.VERSION_1_8 43 | targetCompatibility JavaVersion.VERSION_1_8 44 | } 45 | } 46 | 47 | dependencies { 48 | testImplementation 'junit:junit:4.13.2' 49 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 50 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 51 | } -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_local.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #ifndef OSSL_CRYPTO_AES_LOCAL_H 11 | # define OSSL_CRYPTO_AES_LOCAL_H 12 | 13 | //# include 14 | # include 15 | # include 16 | # include 17 | 18 | # if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) 19 | # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) 20 | # define GETU32(p) SWAP(*((u32 *)(p))) 21 | # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } 22 | # else 23 | # define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) 24 | # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } 25 | # endif 26 | 27 | typedef unsigned long long u64; 28 | # ifdef AES_LONG 29 | typedef unsigned long u32; 30 | # else 31 | typedef unsigned int u32; 32 | # endif 33 | typedef unsigned short u16; 34 | typedef unsigned char u8; 35 | 36 | # define MAXKC (256/32) 37 | # define MAXKB (256/8) 38 | # define MAXNR 14 39 | 40 | /* This controls loop-unrolling in aes_core.c */ 41 | # undef FULL_UNROLL 42 | 43 | #endif /* !OSSL_CRYPTO_AES_LOCAL_H */ 44 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_cfb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | /* 14 | * The input and output encrypted as though 128bit cfb mode is being used. 15 | * The extra state information to record how much of the 128bit block we have 16 | * used is contained in *num; 17 | */ 18 | 19 | void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, 20 | size_t length, const AES_KEY *key, 21 | unsigned char *ivec, int *num, const int enc) 22 | { 23 | 24 | CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, 25 | (block128_f) AES_encrypt); 26 | } 27 | 28 | /* N.B. This expects the input to be packed, MS bit first */ 29 | void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, 30 | size_t length, const AES_KEY *key, 31 | unsigned char *ivec, int *num, const int enc) 32 | { 33 | CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, 34 | (block128_f) AES_encrypt); 35 | } 36 | 37 | void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, 38 | size_t length, const AES_KEY *key, 39 | unsigned char *ivec, int *num, const int enc) 40 | { 41 | CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, 42 | (block128_f) AES_encrypt); 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /NativeEncrypt/src/androidTest/java/com/jni/encrypt/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | import android.content.pm.Signature; 7 | import android.util.Log; 8 | 9 | import androidx.test.ext.junit.runners.AndroidJUnit4; 10 | import androidx.test.platform.app.InstrumentationRegistry; 11 | 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | 15 | import static org.junit.Assert.assertEquals; 16 | import static org.junit.Assert.assertTrue; 17 | 18 | /** 19 | * Instrumented test, which will execute on an Android device. 20 | * 21 | * @see Testing documentation 22 | */ 23 | @RunWith(AndroidJUnit4.class) 24 | public class ExampleInstrumentedTest { 25 | 26 | private static final String TAG = "签名"; 27 | 28 | @Test 29 | public void useAppContext() { 30 | // Context of the app under test. 31 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 32 | final PackageManager packageManager = appContext.getPackageManager(); 33 | final String packageName = appContext.getPackageName(); 34 | Log.d(TAG,"包名:"+packageName); 35 | assertEquals("com.jni.encrypt.test", appContext.getPackageName()); 36 | try { 37 | final PackageInfo packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 38 | final Signature signature = packageInfo.signatures[0]; 39 | Log.d(TAG, signature.toCharsString()); 40 | } catch (PackageManager.NameNotFoundException e) { 41 | e.printStackTrace(); 42 | } 43 | boolean init = NativeUtil.init(appContext); 44 | Log.d(TAG,"签名验证结果:"+init); 45 | assertTrue(init); 46 | } 47 | } -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/encode/base64.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ENCRYPTUTIL_BASE64_H 3 | #define ENCRYPTUTIL_BASE64_H 4 | 5 | #endif //ENCRYPTUTIL_BASE64_H 6 | 7 | # include 8 | #include 9 | #include 10 | #include 11 | 12 | static const int B64_LINE_LENGTH = 76; 13 | static const int LINE_GROUPS = 19; 14 | static const char CRLF_CR = '\r'; 15 | static const char CRLF_LF = '\n'; 16 | static const char PADDING_CHAR = '='; 17 | 18 | /** 19 | * Base64 index table. 20 | */ 21 | static const unsigned char data_bin2ascii[65] = 22 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 23 | 24 | static const unsigned char data_ascii2bin[128] = { 25 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 26 | 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 27 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 28 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 29 | 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 30 | 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, 31 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 32 | 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 33 | 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 34 | 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 35 | 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 36 | 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 37 | 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 38 | 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 39 | 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 40 | 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 41 | }; 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | /** 48 | * 在使用Base64编码函数b64_encode()之前,该函数可以为函数调用者预先算出 49 | * 存放编码结果的缓冲区大小 50 | * @return 所需存放base64编码结果的缓冲区大小,以字节为单位。当raw_data_len <= 0 时,返回值为 0 51 | */ 52 | unsigned int calcBase64EncodeBufLen(unsigned int raw_data_len, bool newLine); 53 | 54 | int encodeB64(const unsigned char *in, unsigned char *out, size_t len, bool newLine); 55 | 56 | size_t decodeB64(const unsigned char *in, unsigned char *out, size_t len); 57 | 58 | #ifdef __cplusplus 59 | } 60 | #endif 61 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.10.2) 7 | 8 | message("工程源目录:${PROJECT_SOURCE_DIR}") 9 | message("当前CMake路径:${CMAKE_SOURCE_DIR}") 10 | # 包含include文件 11 | include_directories(${CMAKE_SOURCE_DIR}/include/) 12 | 13 | # Creates and names a library, sets it as either STATIC 14 | # or SHARED, and provides the relative paths to its source code. 15 | # You can define multiple libraries, and CMake builds them for you. 16 | # Gradle automatically packages shared libraries with your APK. 17 | 18 | set(AES_DIR crypto/aes/) 19 | add_library( # Sets the name of the library. 20 | NativeTools-lib 21 | 22 | # Sets the library as a shared library. 23 | SHARED 24 | 25 | # Provides a relative path to your source file(s). 26 | NativeUtil.cpp encode/base64.cpp base/log.cpp 27 | ${AES_DIR}aes_cbc.c ${AES_DIR}aes_misc.c ${AES_DIR}aes_cfb.c ${AES_DIR}aes_core.c 28 | ${AES_DIR}aes_local.h ${AES_DIR}aes_ecb.c ${AES_DIR}aes_ige.c ${AES_DIR}aes_ofb.c 29 | crypto/modes/cbc128.c crypto/modes/cfb128.c crypto/modes/modes_local.h crypto/modes/ofb128.c) 30 | 31 | # Searches for a specified prebuilt library and stores the path as a 32 | # variable. Because CMake includes system libraries in the search path by 33 | # default, you only need to specify the name of the public NDK library 34 | # you want to add. CMake verifies that the library exists before 35 | # completing its build. 36 | 37 | find_library( # Sets the name of the path variable. 38 | log-lib 39 | 40 | # Specifies the name of the NDK library that 41 | # you want CMake to locate. 42 | log) 43 | 44 | # Specifies libraries CMake should link to your target library. You 45 | # can link multiple libraries, such as libraries you define in this 46 | # build script, prebuilt third-party libraries, or system libraries. 47 | 48 | target_link_libraries( # Specifies the target library. 49 | NativeTools-lib 50 | 51 | # Links the target library to the log library 52 | # included in the NDK. 53 | ${log-lib}) -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /NativeEncrypt/src/androidTest/java/com/jni/encrypt/EncryptTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.util.Log; 4 | 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | import static org.junit.Assert.assertTrue; 12 | 13 | /** 14 | * JNI加解密测试 15 | */ 16 | @RunWith(AndroidJUnit4.class) 17 | public class EncryptTest { 18 | private static final String TAG = "Encrypt"; 19 | 20 | @Test 21 | public void testBase() { 22 | testEncryptDecrypt("123456"); 23 | testEncryptDecrypt("Android安卓abcdefg"); 24 | testEncryptDecrypt("中国上海123abcABC;;!!!???"); 25 | testEncryptDecrypt("中国上海123abcABC;;!!!???加解密测试---------------啊啊啊123abcABC;;!!!???加解密测试"); 26 | } 27 | 28 | private void testEncryptDecrypt(String plain) { 29 | String encrypt = NativeUtil.encrypt(plain); 30 | String decrypt = NativeUtil.decrypt(encrypt); 31 | Log.d(TAG, "明文:\n" + plain + "\n密文:\n" + encrypt + "\n解密:\n" + decrypt); 32 | assertEquals("加解密失败:\n" + plain, plain, decrypt); 33 | } 34 | 35 | @Test 36 | public void testPerformance() { 37 | final String s = "{type:1,name:\"bob;:&#$\\\",function:\"加解密对比\",url:\"https://www.baidu.com/\"}"; 38 | final StringBuilder plainText = new StringBuilder(10000); 39 | int i; 40 | for (i = 0; i < 800; i++) { 41 | plainText.append(s); 42 | } 43 | for (i = 0; i < 100; i++) { 44 | plainText.append(s); 45 | final String str = plainText.toString(); 46 | encrypt(str); 47 | } 48 | } 49 | 50 | private void encrypt(String plainText) { 51 | long startTime; 52 | long diffC; 53 | final int length = plainText.length(); 54 | final StringBuilder log = new StringBuilder(100); 55 | //C加解密------------------------------------------------------ 56 | startTime = System.currentTimeMillis(); 57 | String cE = NativeUtil.encrypt(plainText); 58 | final String cD = NativeUtil.decrypt(cE); 59 | diffC = System.currentTimeMillis() - startTime; 60 | log.append("字符串长度:").append(length).append(" C加解密耗时(ms):").append(diffC); 61 | Log.d(TAG, log.toString()); 62 | final boolean success = plainText.equals(cD); 63 | if (!success) { 64 | Log.d(TAG, "加解密失败原文:\n" + plainText + "---" + plainText.length()); 65 | } 66 | assertTrue("加解密失败", success); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /NativeEncrypt/src/androidTest/java/com/jni/encrypt/Base64Test.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.util.Base64; 4 | import android.util.Log; 5 | 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import java.nio.charset.Charset; 12 | 13 | import static org.junit.Assert.assertFalse; 14 | 15 | /** 16 | * Created on 2021/4/6. 17 | * 18 | * desc : Base64编解码测试 19 | */ 20 | @RunWith(AndroidJUnit4.class) 21 | public class Base64Test { 22 | private static final String TAG = "base64"; 23 | 24 | @Test 25 | public void testBase() { 26 | testBase64(""); 27 | testBase64("123456"); 28 | testBase64("啊哈哈嘿123456ABCDEF;"); 29 | } 30 | 31 | @Test 32 | public void testPerformance() { 33 | final String s = "123456abcdef:\\{\"\"汉字http://."; 34 | final StringBuilder builder = new StringBuilder(1000); 35 | final int length = 3200; 36 | for (int i = 0; i < length; i++) { 37 | builder.append(s); 38 | if (i >= 3150) { 39 | testBase64(builder.toString()); 40 | } 41 | } 42 | Log.d(TAG, "测试完成--" + length); 43 | } 44 | 45 | private void testBase64(String s) { 46 | final StringBuilder log = new StringBuilder(100); 47 | log.append("数据长度:").append(s.length()); 48 | long start = System.currentTimeMillis(); 49 | String encodeJ = javaBase64Encode(s); 50 | String decodeJ = javaBase64Decode(encodeJ); 51 | log.append(" java base64编码耗时(ms):").append(System.currentTimeMillis() - start); 52 | start = System.currentTimeMillis(); 53 | String encodeC = NativeUtil.base64Encode(s, true); 54 | String decodeC = NativeUtil.base64Decode(encodeC); 55 | log.append("---------------C base64编码耗时(ms):").append(System.currentTimeMillis() - start); 56 | Log.d(TAG, log.toString()); 57 | final boolean error = !encodeC.equals(encodeJ) || !decodeC.equals(decodeJ); 58 | if (error) { 59 | Log.d(TAG, "以下数据不同"); 60 | Log.d(TAG, s + "----" + s.length()); 61 | Log.d(TAG, encodeC); 62 | Log.d(TAG, encodeJ); 63 | } 64 | assertFalse(error); 65 | } 66 | 67 | private String javaBase64Encode(String s) { 68 | return Base64.encodeToString(s.getBytes(Charset.forName("UTF-8")), Base64.DEFAULT); 69 | } 70 | 71 | private String javaBase64Decode(String s) { 72 | return new String(Base64.decode(s, Base64.DEFAULT)); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/modes/ofb128.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include 11 | #include "modes_local.h" 12 | #include 13 | 14 | #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) 15 | typedef size_t size_t_aX __attribute((__aligned__(1))); 16 | #else 17 | typedef size_t size_t_aX; 18 | #endif 19 | 20 | /* 21 | * The input and output encrypted as though 128bit ofb mode is being used. 22 | * The extra state information to record how much of the 128bit block we have 23 | * used is contained in *num; 24 | */ 25 | void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, 26 | size_t len, const void *key, 27 | unsigned char ivec[16], int *num, block128_f block) 28 | { 29 | unsigned int n; 30 | size_t l = 0; 31 | 32 | n = *num; 33 | 34 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 35 | if (16 % sizeof(size_t) == 0) { /* always true actually */ 36 | do { 37 | while (n && len) { 38 | *(out++) = *(in++) ^ ivec[n]; 39 | --len; 40 | n = (n + 1) % 16; 41 | } 42 | # if defined(STRICT_ALIGNMENT) 43 | if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 44 | 0) 45 | break; 46 | # endif 47 | while (len >= 16) { 48 | (*block) (ivec, ivec, key); 49 | for (; n < 16; n += sizeof(size_t)) 50 | *(size_t_aX *)(out + n) = 51 | *(size_t_aX *)(in + n) 52 | ^ *(size_t_aX *)(ivec + n); 53 | len -= 16; 54 | out += 16; 55 | in += 16; 56 | n = 0; 57 | } 58 | if (len) { 59 | (*block) (ivec, ivec, key); 60 | while (len--) { 61 | out[n] = in[n] ^ ivec[n]; 62 | ++n; 63 | } 64 | } 65 | *num = n; 66 | return; 67 | } while (0); 68 | } 69 | /* the rest would be commonly eliminated by x86* compiler */ 70 | #endif 71 | while (l < len) { 72 | if (n == 0) { 73 | (*block) (ivec, ivec, key); 74 | } 75 | out[l] = in[l] ^ ivec[n]; 76 | ++l; 77 | n = (n + 1) % 16; 78 | } 79 | 80 | *num = n; 81 | } 82 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/jni/encrypt/EncryptPerformanceTest.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.util.Log; 4 | 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import java.io.UnsupportedEncodingException; 12 | import java.util.LinkedHashMap; 13 | import java.util.Map; 14 | import java.util.Set; 15 | 16 | /** 17 | * java加解密和C语言加解密性能测试 18 | */ 19 | @RunWith(AndroidJUnit4.class) 20 | public class EncryptPerformanceTest { 21 | private static final String TAG = "EncryptPerformance"; 22 | private static final Map table = new LinkedHashMap<>(100); 23 | 24 | @Test 25 | public void testPerformance() { 26 | table.clear(); 27 | final String s = "{type:1,name:\"bob;:&#$\\\",function:\"加解密对比\",url:\"https://www.baidu.com/\"}"; 28 | final StringBuilder plainText = new StringBuilder(100000); 29 | int i; 30 | for (i = 0; i < 3000; i++) { 31 | plainText.append(s); 32 | } 33 | for (i = 0; i < 50; i++) { 34 | plainText.append(s); 35 | final String str = plainText.toString(); 36 | encrypt(str); 37 | } 38 | final StringBuilder builder = new StringBuilder(1000); 39 | Set> entrySet = table.entrySet(); 40 | builder.append("加解密字符串长度以及耗时差(J-C),单位 ms\n"); 41 | for (Map.Entry entry : entrySet) { 42 | builder.append("长度:").append(entry.getKey()) 43 | .append(" 耗时差:").append(entry.getValue()) 44 | .append("\n"); 45 | } 46 | Log.d(TAG, " \n\n" + builder.toString()); 47 | } 48 | 49 | private void encrypt(String plainText) { 50 | long startTime; 51 | long diffJ, diffC; 52 | final int length = plainText.length(); 53 | final StringBuilder log = new StringBuilder(100); 54 | 55 | String javaE; 56 | String javaD; 57 | try { 58 | //java加解密------------------------------------------------------ 59 | startTime = System.currentTimeMillis(); 60 | javaE = AESEncrypt.encodeReplace(plainText); 61 | javaD = AESEncrypt.decodeReplace(javaE); 62 | diffJ = System.currentTimeMillis() - startTime; 63 | log.append("字符串长度:").append(length).append(" java耗时:").append(diffJ); 64 | 65 | //C加解密------------------------------------------------------ 66 | startTime = System.currentTimeMillis(); 67 | String cE = NativeUtil.encrypt(plainText); 68 | final String cD = NativeUtil.decrypt(cE); 69 | diffC = System.currentTimeMillis() - startTime; 70 | log.append(" C耗时:").append(diffC); 71 | table.put(length, diffJ - diffC); 72 | Log.d(TAG, log.toString()); 73 | final boolean success = javaE.equals(cE) && cD.equals(javaD); 74 | if (!success) { 75 | Log.d(TAG, "\n加解密失败:\n"); 76 | Log.d(TAG, "失败原文:\n" + plainText + "---" + plainText.length()); 77 | Log.d(TAG, "\n明文:\n" + plainText); 78 | Log.d(TAG, "\nJ密文:\n" + cE); 79 | Log.d(TAG, "\nC密文:\n" + cE); 80 | Log.d(TAG, "\nC解密:\n" + cD); 81 | } 82 | Assert.assertTrue(success); 83 | } catch (UnsupportedEncodingException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/jni/encrypt/AESEncrypt.java: -------------------------------------------------------------------------------- 1 | package com.jni.encrypt; 2 | 3 | import android.text.TextUtils; 4 | import android.util.Base64; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | import java.io.UnsupportedEncodingException; 10 | import java.security.InvalidAlgorithmParameterException; 11 | import java.security.InvalidKeyException; 12 | import java.security.NoSuchAlgorithmException; 13 | 14 | import javax.crypto.Cipher; 15 | import javax.crypto.NoSuchPaddingException; 16 | import javax.crypto.spec.IvParameterSpec; 17 | import javax.crypto.spec.SecretKeySpec; 18 | 19 | public class AESEncrypt { 20 | 21 | private static final String AES_KEY = "ynadcc@p$abw0rdcdbttye$38949!@$@"; 22 | private static final String AES_IV = "=o&g%m,*o?dL~def"; 23 | private static final String AES_ALGORITHM = "AES/CFB/PKCS7Padding"; 24 | private static final String CHARSET = "UTF-8"; 25 | 26 | @Nullable 27 | private static Cipher encodeCipher = null; 28 | @Nullable 29 | private static Cipher decodeCipher = null; 30 | 31 | private static synchronized Cipher getEncodeCipher() throws InvalidKeyException, 32 | NoSuchAlgorithmException, NoSuchPaddingException, 33 | InvalidAlgorithmParameterException, UnsupportedEncodingException { 34 | 35 | if (encodeCipher == null) { 36 | SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(CHARSET), "AES"); 37 | encodeCipher = Cipher.getInstance(AES_ALGORITHM); 38 | encodeCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(AES_IV.getBytes(CHARSET))); 39 | } 40 | return encodeCipher; 41 | } 42 | 43 | private static synchronized Cipher getDecodeCipher() throws InvalidKeyException, 44 | NoSuchAlgorithmException, NoSuchPaddingException, 45 | InvalidAlgorithmParameterException, UnsupportedEncodingException { 46 | 47 | if (decodeCipher == null) { 48 | SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(CHARSET), "AES"); 49 | decodeCipher = Cipher.getInstance(AES_ALGORITHM); 50 | decodeCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(AES_IV.getBytes(CHARSET))); 51 | } 52 | return decodeCipher; 53 | 54 | } 55 | 56 | @Nullable 57 | public static synchronized byte[] encode(@NonNull byte[] data) { 58 | try { 59 | return getEncodeCipher().doFinal(data); 60 | } catch (Exception e) { 61 | return null; 62 | } 63 | } 64 | 65 | public static String encodeReplace(@NonNull String data) throws UnsupportedEncodingException { 66 | if (TextUtils.isEmpty(data)) { 67 | return ""; 68 | } 69 | byte[] bytes = encode(data.getBytes(CHARSET)); 70 | if (bytes == null) { 71 | return ""; 72 | } 73 | return Base64.encodeToString(bytes, Base64.NO_WRAP); 74 | } 75 | 76 | @Nullable 77 | private static synchronized byte[] decode(byte[] data) { 78 | try { 79 | return getDecodeCipher().doFinal(data); 80 | } catch (Exception e) { 81 | return null; 82 | } 83 | } 84 | 85 | @Nullable 86 | public static String decodeReplace(@NonNull String data) { 87 | if (TextUtils.isEmpty(data)) { 88 | return ""; 89 | } 90 | try { 91 | byte[] datas = decode(Base64.decode(data, Base64.NO_WRAP)); 92 | return new String(datas, CHARSET); 93 | } catch (Exception e) { 94 | return ""; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/include/openssl/aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #ifndef HEADER_AES_H 11 | # define HEADER_AES_H 12 | 13 | //# include 14 | 15 | # include 16 | # ifdef __cplusplus 17 | extern "C" { 18 | # endif 19 | 20 | # define AES_ENCRYPT 1 21 | # define AES_DECRYPT 0 22 | 23 | /* 24 | * Because array size can't be a const in C, the following two are macros. 25 | * Both sizes are in bytes. 26 | */ 27 | # define AES_MAXNR 14 28 | # define AES_BLOCK_SIZE 16 29 | 30 | /* This should be a hidden type, but EVP requires that the size be known */ 31 | struct aes_key_st { 32 | # ifdef AES_LONG 33 | unsigned long rd_key[4 * (AES_MAXNR + 1)]; 34 | # else 35 | unsigned int rd_key[4 * (AES_MAXNR + 1)]; 36 | # endif 37 | int rounds; 38 | }; 39 | typedef struct aes_key_st AES_KEY; 40 | 41 | const char *AES_options(void); 42 | 43 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits, 44 | AES_KEY *key); 45 | int AES_set_decrypt_key(const unsigned char *userKey, const int bits, 46 | AES_KEY *key); 47 | 48 | void AES_encrypt(const unsigned char *in, unsigned char *out, 49 | const AES_KEY *key); 50 | void AES_decrypt(const unsigned char *in, unsigned char *out, 51 | const AES_KEY *key); 52 | 53 | void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, 54 | const AES_KEY *key, const int enc); 55 | void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, 56 | size_t length, const AES_KEY *key, 57 | unsigned char *ivec, const int enc); 58 | void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, 59 | size_t length, const AES_KEY *key, 60 | unsigned char *ivec, int *num, const int enc); 61 | void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, 62 | size_t length, const AES_KEY *key, 63 | unsigned char *ivec, int *num, const int enc); 64 | void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, 65 | size_t length, const AES_KEY *key, 66 | unsigned char *ivec, int *num, const int enc); 67 | void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, 68 | size_t length, const AES_KEY *key, 69 | unsigned char *ivec, int *num); 70 | /* NB: the IV is _two_ blocks long */ 71 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 72 | size_t length, const AES_KEY *key, 73 | unsigned char *ivec, const int enc); 74 | /* NB: the IV is _four_ blocks long */ 75 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 76 | size_t length, const AES_KEY *key, 77 | const AES_KEY *key2, const unsigned char *ivec, 78 | const int enc); 79 | 80 | int AES_wrap_key(AES_KEY *key, const unsigned char *iv, 81 | unsigned char *out, 82 | const unsigned char *in, unsigned int inlen); 83 | int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, 84 | unsigned char *out, 85 | const unsigned char *in, unsigned int inlen); 86 | 87 | 88 | # ifdef __cplusplus 89 | } 90 | # endif 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/encode/base64.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "base64.h" 3 | 4 | #define convert_bin2ascii(a, table) ((table)[(a)&0x3f]) 5 | 6 | int encodeB64(const unsigned char *in, unsigned char *out, size_t len, bool newLine) { 7 | int i, ret = 0; 8 | unsigned long l; 9 | const unsigned char *table = data_bin2ascii; 10 | int encodedCount = 0; 11 | for (i = len; i > 0; i -= 3) { 12 | if (i >= 3) { 13 | l = (((unsigned long)in[0]) << 16L) |(((unsigned long)in[1]) << 8L) | in[2]; 14 | *(out++) = convert_bin2ascii(l >> 18L, table); 15 | *(out++) = convert_bin2ascii(l >> 12L, table); 16 | *(out++) = convert_bin2ascii(l >> 6L, table); 17 | *(out++) = convert_bin2ascii(l, table); 18 | } else { 19 | l = ((unsigned long)in[0]) << 16L; 20 | if (i == 2) { 21 | l |= ((unsigned long)in[1] << 8L); 22 | } 23 | *(out++) = convert_bin2ascii(l >> 18L, table); 24 | *(out++) = convert_bin2ascii(l >> 12L, table); 25 | *(out++) = (i == 1) ? '=' : convert_bin2ascii(l >> 6L, table); 26 | *(out++) = '='; 27 | } 28 | ret += 4; 29 | in += 3; 30 | encodedCount += 4; 31 | if (newLine && encodedCount % B64_LINE_LENGTH == 0) { 32 | *(out++) = CRLF_LF; 33 | ret++; 34 | } 35 | } 36 | if (newLine && encodedCount % B64_LINE_LENGTH != 0) { 37 | *(out++) = CRLF_LF; 38 | ret++; 39 | } 40 | *out = '\0'; 41 | return ret; 42 | } 43 | 44 | unsigned int calcBase64EncodeBufLen(unsigned int raw_data_len, bool newLine) { 45 | if (raw_data_len <= 0) { 46 | return 0; 47 | } 48 | unsigned int encodeLen, total; 49 | encodeLen = (raw_data_len + 2) / 3 * 4; 50 | if (newLine) { 51 | // 首先计算一共有多少行 52 | unsigned int row; 53 | if (encodeLen % B64_LINE_LENGTH == 0) { 54 | row = encodeLen / B64_LINE_LENGTH; 55 | } else { 56 | row = encodeLen / B64_LINE_LENGTH + 1; 57 | } 58 | total = encodeLen + row + 1; 59 | } else { 60 | // 如果不换行,加1是因为要在编码后的字符串末尾加上一个字符串结束符:'\0' 61 | total = encodeLen + 1; 62 | } 63 | return total; 64 | } 65 | 66 | static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table) { 67 | return table[a]; 68 | } 69 | 70 | size_t decodeB64(const unsigned char *in, unsigned char *out, size_t len) { 71 | size_t outLength = 0; 72 | int groupIndex = 0; 73 | unsigned long l; 74 | const unsigned char *table = data_ascii2bin; 75 | unsigned char group[4]; 76 | unsigned char temp; 77 | for (int i = 0; i < len; i++) { 78 | temp = *(in++); 79 | if (temp == PADDING_CHAR) { 80 | break; 81 | } 82 | if (temp == CRLF_CR || temp == CRLF_LF) { 83 | // 遇到换行,继续 84 | continue; 85 | } 86 | group[groupIndex++] = conv_ascii2bin(temp, table); 87 | if (groupIndex == 4) { 88 | l = ((((unsigned long)group[0]) << 18L) | 89 | (((unsigned long)group[1]) << 12L) | 90 | (((unsigned long)group[2]) << 6L) | (((unsigned long)group[3]))); 91 | *(out++) = (unsigned char)(l >> 16L) & 0xff; 92 | *(out++) = (unsigned char)(l >> 8L) & 0xff; 93 | *(out++) = (unsigned char)(l) & 0xff; 94 | outLength += 3; 95 | groupIndex = 0; 96 | } 97 | } 98 | if (groupIndex > 0) { 99 | l = ((((unsigned long)group[0]) << 18L) | 100 | (((unsigned long)group[1]) << 12L) | 101 | (((unsigned long)group[2]) << 6L) | (((unsigned long)group[3]))); 102 | *(out++) = (unsigned char)(l >> 16L) & 0xff; 103 | if (groupIndex == 3) { 104 | // 代表末尾填充了一个 = 105 | *(out++) = (unsigned char)(l >> 8L) & 0xff; 106 | } 107 | outLength += groupIndex - 1; 108 | } 109 | // 最末尾加一个字符串结束符 110 | *out = '\0'; 111 | return outLength; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/modes/cbc128.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include 11 | #include "modes_local.h" 12 | #include 13 | 14 | #if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) 15 | # define STRICT_ALIGNMENT 0 16 | #endif 17 | 18 | #if defined(__GNUC__) && !STRICT_ALIGNMENT 19 | typedef size_t size_t_aX __attribute((__aligned__(1))); 20 | #else 21 | typedef size_t size_t_aX; 22 | #endif 23 | 24 | void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, 25 | size_t len, const void *key, 26 | unsigned char ivec[16], block128_f block) 27 | { 28 | size_t n; 29 | const unsigned char *iv = ivec; 30 | 31 | if (len == 0) 32 | return; 33 | 34 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 35 | if (STRICT_ALIGNMENT && 36 | ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 37 | while (len >= 16) { 38 | for (n = 0; n < 16; ++n) 39 | out[n] = in[n] ^ iv[n]; 40 | (*block) (out, out, key); 41 | iv = out; 42 | len -= 16; 43 | in += 16; 44 | out += 16; 45 | } 46 | } else { 47 | while (len >= 16) { 48 | for (n = 0; n < 16; n += sizeof(size_t)) 49 | *(size_t_aX *)(out + n) = 50 | *(size_t_aX *)(in + n) ^ *(size_t_aX *)(iv + n); 51 | (*block) (out, out, key); 52 | iv = out; 53 | len -= 16; 54 | in += 16; 55 | out += 16; 56 | } 57 | } 58 | #endif 59 | while (len) { 60 | for (n = 0; n < 16 && n < len; ++n) 61 | out[n] = in[n] ^ iv[n]; 62 | for (; n < 16; ++n) 63 | out[n] = iv[n]; 64 | (*block) (out, out, key); 65 | iv = out; 66 | if (len <= 16) 67 | break; 68 | len -= 16; 69 | in += 16; 70 | out += 16; 71 | } 72 | if (ivec != iv) 73 | memcpy(ivec, iv, 16); 74 | } 75 | 76 | void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, 77 | size_t len, const void *key, 78 | unsigned char ivec[16], block128_f block) 79 | { 80 | size_t n; 81 | union { 82 | size_t t[16 / sizeof(size_t)]; 83 | unsigned char c[16]; 84 | } tmp; 85 | 86 | if (len == 0) 87 | return; 88 | 89 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 90 | if (in != out) { 91 | const unsigned char *iv = ivec; 92 | 93 | if (STRICT_ALIGNMENT && 94 | ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 95 | while (len >= 16) { 96 | (*block) (in, out, key); 97 | for (n = 0; n < 16; ++n) 98 | out[n] ^= iv[n]; 99 | iv = in; 100 | len -= 16; 101 | in += 16; 102 | out += 16; 103 | } 104 | } else if (16 % sizeof(size_t) == 0) { /* always true */ 105 | while (len >= 16) { 106 | size_t_aX *out_t = (size_t_aX *)out; 107 | size_t_aX *iv_t = (size_t_aX *)iv; 108 | 109 | (*block) (in, out, key); 110 | for (n = 0; n < 16 / sizeof(size_t); n++) 111 | out_t[n] ^= iv_t[n]; 112 | iv = in; 113 | len -= 16; 114 | in += 16; 115 | out += 16; 116 | } 117 | } 118 | if (ivec != iv) 119 | memcpy(ivec, iv, 16); 120 | } else { 121 | if (STRICT_ALIGNMENT && 122 | ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { 123 | unsigned char c; 124 | while (len >= 16) { 125 | (*block) (in, tmp.c, key); 126 | for (n = 0; n < 16; ++n) { 127 | c = in[n]; 128 | out[n] = tmp.c[n] ^ ivec[n]; 129 | ivec[n] = c; 130 | } 131 | len -= 16; 132 | in += 16; 133 | out += 16; 134 | } 135 | } else if (16 % sizeof(size_t) == 0) { /* always true */ 136 | while (len >= 16) { 137 | size_t c; 138 | size_t_aX *out_t = (size_t_aX *)out; 139 | size_t_aX *ivec_t = (size_t_aX *)ivec; 140 | const size_t_aX *in_t = (const size_t_aX *)in; 141 | 142 | (*block) (in, tmp.c, key); 143 | for (n = 0; n < 16 / sizeof(size_t); n++) { 144 | c = in_t[n]; 145 | out_t[n] = tmp.t[n] ^ ivec_t[n]; 146 | ivec_t[n] = c; 147 | } 148 | len -= 16; 149 | in += 16; 150 | out += 16; 151 | } 152 | } 153 | } 154 | #endif 155 | while (len) { 156 | unsigned char c; 157 | (*block) (in, tmp.c, key); 158 | for (n = 0; n < 16 && n < len; ++n) { 159 | c = in[n]; 160 | out[n] = tmp.c[n] ^ ivec[n]; 161 | ivec[n] = c; 162 | } 163 | if (len <= 16) { 164 | for (; n < 16; ++n) 165 | ivec[n] = in[n]; 166 | break; 167 | } 168 | len -= 16; 169 | in += 16; 170 | out += 16; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/modes/modes_local.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include 11 | #include "../../include/openssl/modes.h" 12 | 13 | #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) 14 | typedef __int64 i64; 15 | typedef unsigned __int64 u64; 16 | # define U64(C) C##UI64 17 | #elif defined(__arch64__) 18 | typedef long i64; 19 | typedef unsigned long u64; 20 | # define U64(C) C##UL 21 | #else 22 | typedef long long i64; 23 | typedef unsigned long long u64; 24 | # define U64(C) C##ULL 25 | #endif 26 | 27 | typedef unsigned int u32; 28 | typedef unsigned char u8; 29 | 30 | #define STRICT_ALIGNMENT 1 31 | #ifndef PEDANTIC 32 | # if defined(__i386) || defined(__i386__) || \ 33 | defined(__x86_64) || defined(__x86_64__) || \ 34 | defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ 35 | defined(__aarch64__) || \ 36 | defined(__s390__) || defined(__s390x__) 37 | # undef STRICT_ALIGNMENT 38 | # endif 39 | #endif 40 | 41 | #ifndef STRICT_ALIGNMENT 42 | # ifdef __GNUC__ 43 | typedef u32 u32_a1 __attribute((__aligned__(1))); 44 | # else 45 | typedef u32 u32_a1; 46 | # endif 47 | #endif 48 | 49 | #if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 50 | # if defined(__GNUC__) && __GNUC__>=2 51 | # if defined(__x86_64) || defined(__x86_64__) 52 | # define BSWAP8(x) ({ u64 ret_=(x); \ 53 | asm ("bswapq %0" \ 54 | : "+r"(ret_)); ret_; }) 55 | # define BSWAP4(x) ({ u32 ret_=(x); \ 56 | asm ("bswapl %0" \ 57 | : "+r"(ret_)); ret_; }) 58 | # elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) 59 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ 60 | asm ("bswapl %0; bswapl %1" \ 61 | : "+r"(hi_),"+r"(lo_)); \ 62 | (u64)hi_<<32|lo_; }) 63 | # define BSWAP4(x) ({ u32 ret_=(x); \ 64 | asm ("bswapl %0" \ 65 | : "+r"(ret_)); ret_; }) 66 | # elif defined(__aarch64__) 67 | # if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ 68 | __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ 69 | # define BSWAP8(x) ({ u64 ret_; \ 70 | asm ("rev %0,%1" \ 71 | : "=r"(ret_) : "r"(x)); ret_; }) 72 | # define BSWAP4(x) ({ u32 ret_; \ 73 | asm ("rev %w0,%w1" \ 74 | : "=r"(ret_) : "r"(x)); ret_; }) 75 | # endif 76 | # elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) 77 | # define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ 78 | asm ("rev %0,%0; rev %1,%1" \ 79 | : "+r"(hi_),"+r"(lo_)); \ 80 | (u64)hi_<<32|lo_; }) 81 | # define BSWAP4(x) ({ u32 ret_; \ 82 | asm ("rev %0,%1" \ 83 | : "=r"(ret_) : "r"((u32)(x))); \ 84 | ret_; }) 85 | # endif 86 | # elif defined(_MSC_VER) 87 | # if _MSC_VER>=1300 88 | # include 89 | # pragma intrinsic(_byteswap_uint64,_byteswap_ulong) 90 | # define BSWAP8(x) _byteswap_uint64((u64)(x)) 91 | # define BSWAP4(x) _byteswap_ulong((u32)(x)) 92 | # elif defined(_M_IX86) 93 | __inline u32 _bswap4(u32 val) 94 | { 95 | _asm mov eax, val _asm bswap eax} 96 | # define BSWAP4(x) _bswap4(x) 97 | # endif 98 | # endif 99 | #endif 100 | #if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) 101 | # define GETU32(p) BSWAP4(*(const u32_a1 *)(p)) 102 | # define PUTU32(p,v) *(u32_a1 *)(p) = BSWAP4(v) 103 | #else 104 | # define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) 105 | # define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) 106 | #endif 107 | /*- GCM definitions */ typedef struct { 108 | u64 hi, lo; 109 | } u128; 110 | 111 | #ifdef TABLE_BITS 112 | # undef TABLE_BITS 113 | #endif 114 | /* 115 | * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should 116 | * never be set to 8 [or 1]. For further information see gcm128.c. 117 | */ 118 | #define TABLE_BITS 4 119 | 120 | struct gcm128_context { 121 | /* Following 6 names follow names in GCM specification */ 122 | union { 123 | u64 u[2]; 124 | u32 d[4]; 125 | u8 c[16]; 126 | size_t t[16 / sizeof(size_t)]; 127 | } Yi, EKi, EK0, len, Xi, H; 128 | /* 129 | * Relative position of Xi, H and pre-computed Htable is used in some 130 | * assembler modules, i.e. don't change the order! 131 | */ 132 | #if TABLE_BITS==8 133 | u128 Htable[256]; 134 | #else 135 | u128 Htable[16]; 136 | void (*gmult) (u64 Xi[2], const u128 Htable[16]); 137 | void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, 138 | size_t len); 139 | #endif 140 | unsigned int mres, ares; 141 | block128_f block; 142 | void *key; 143 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 144 | unsigned char Xn[48]; 145 | #endif 146 | }; 147 | 148 | struct xts128_context { 149 | void *key1, *key2; 150 | block128_f block1, block2; 151 | }; 152 | 153 | struct ccm128_context { 154 | union { 155 | u64 u[2]; 156 | u8 c[16]; 157 | } nonce, cmac; 158 | u64 blocks; 159 | block128_f block; 160 | void *key; 161 | }; 162 | 163 | #ifndef OPENSSL_NO_OCB 164 | 165 | typedef union { 166 | u64 a[2]; 167 | unsigned char c[16]; 168 | } OCB_BLOCK; 169 | # define ocb_block16_xor(in1,in2,out) \ 170 | ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \ 171 | (out)->a[1]=(in1)->a[1]^(in2)->a[1] ) 172 | # if STRICT_ALIGNMENT 173 | # define ocb_block16_xor_misaligned(in1,in2,out) \ 174 | ocb_block_xor((in1)->c,(in2)->c,16,(out)->c) 175 | # else 176 | # define ocb_block16_xor_misaligned ocb_block16_xor 177 | # endif 178 | 179 | struct ocb128_context { 180 | /* Need both encrypt and decrypt key schedules for decryption */ 181 | block128_f encrypt; 182 | block128_f decrypt; 183 | void *keyenc; 184 | void *keydec; 185 | ocb128_f stream; /* direction dependent */ 186 | /* Key dependent variables. Can be reused if key remains the same */ 187 | size_t l_index; 188 | size_t max_l_index; 189 | OCB_BLOCK l_star; 190 | OCB_BLOCK l_dollar; 191 | OCB_BLOCK *l; 192 | /* Must be reset for each session */ 193 | struct { 194 | u64 blocks_hashed; 195 | u64 blocks_processed; 196 | OCB_BLOCK offset_aad; 197 | OCB_BLOCK sum; 198 | OCB_BLOCK offset; 199 | OCB_BLOCK checksum; 200 | } sess; 201 | }; 202 | #endif /* OPENSSL_NO_OCB */ 203 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/modes/cfb128.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include 11 | #include "modes_local.h" 12 | #include 13 | 14 | #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) 15 | typedef size_t size_t_aX __attribute((__aligned__(1))); 16 | #else 17 | typedef size_t size_t_aX; 18 | #endif 19 | 20 | /* 21 | * The input and output encrypted as though 128bit cfb mode is being used. 22 | * The extra state information to record how much of the 128bit block we have 23 | * used is contained in *num; 24 | */ 25 | void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, 26 | size_t len, const void *key, 27 | unsigned char ivec[16], int *num, 28 | int enc, block128_f block) 29 | { 30 | unsigned int n; 31 | size_t l = 0; 32 | 33 | n = *num; 34 | 35 | if (enc) { 36 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 37 | if (16 % sizeof(size_t) == 0) { /* always true actually */ 38 | do { 39 | while (n && len) { 40 | *(out++) = ivec[n] ^= *(in++); 41 | --len; 42 | n = (n + 1) % 16; 43 | } 44 | # if defined(STRICT_ALIGNMENT) 45 | if (((size_t)in | (size_t)out | (size_t)ivec) % 46 | sizeof(size_t) != 0) 47 | break; 48 | # endif 49 | while (len >= 16) { 50 | (*block) (ivec, ivec, key); 51 | for (; n < 16; n += sizeof(size_t)) { 52 | *(size_t_aX *)(out + n) = 53 | *(size_t_aX *)(ivec + n) 54 | ^= *(size_t_aX *)(in + n); 55 | } 56 | len -= 16; 57 | out += 16; 58 | in += 16; 59 | n = 0; 60 | } 61 | if (len) { 62 | (*block) (ivec, ivec, key); 63 | while (len--) { 64 | out[n] = ivec[n] ^= in[n]; 65 | ++n; 66 | } 67 | } 68 | *num = n; 69 | return; 70 | } while (0); 71 | } 72 | /* the rest would be commonly eliminated by x86* compiler */ 73 | #endif 74 | while (l < len) { 75 | if (n == 0) { 76 | (*block) (ivec, ivec, key); 77 | } 78 | out[l] = ivec[n] ^= in[l]; 79 | ++l; 80 | n = (n + 1) % 16; 81 | } 82 | *num = n; 83 | } else { 84 | #if !defined(OPENSSL_SMALL_FOOTPRINT) 85 | if (16 % sizeof(size_t) == 0) { /* always true actually */ 86 | do { 87 | while (n && len) { 88 | unsigned char c; 89 | *(out++) = ivec[n] ^ (c = *(in++)); 90 | ivec[n] = c; 91 | --len; 92 | n = (n + 1) % 16; 93 | } 94 | # if defined(STRICT_ALIGNMENT) 95 | if (((size_t)in | (size_t)out | (size_t)ivec) % 96 | sizeof(size_t) != 0) 97 | break; 98 | # endif 99 | while (len >= 16) { 100 | (*block) (ivec, ivec, key); 101 | for (; n < 16; n += sizeof(size_t)) { 102 | size_t t = *(size_t_aX *)(in + n); 103 | *(size_t_aX *)(out + n) 104 | = *(size_t_aX *)(ivec + n) ^ t; 105 | *(size_t_aX *)(ivec + n) = t; 106 | } 107 | len -= 16; 108 | out += 16; 109 | in += 16; 110 | n = 0; 111 | } 112 | if (len) { 113 | (*block) (ivec, ivec, key); 114 | while (len--) { 115 | unsigned char c; 116 | out[n] = ivec[n] ^ (c = in[n]); 117 | ivec[n] = c; 118 | ++n; 119 | } 120 | } 121 | *num = n; 122 | return; 123 | } while (0); 124 | } 125 | /* the rest would be commonly eliminated by x86* compiler */ 126 | #endif 127 | while (l < len) { 128 | unsigned char c; 129 | if (n == 0) { 130 | (*block) (ivec, ivec, key); 131 | } 132 | out[l] = ivec[n] ^ (c = in[l]); 133 | ivec[n] = c; 134 | ++l; 135 | n = (n + 1) % 16; 136 | } 137 | *num = n; 138 | } 139 | } 140 | 141 | /* 142 | * This expects a single block of size nbits for both in and out. Note that 143 | * it corrupts any extra bits in the last byte of out 144 | */ 145 | static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out, 146 | int nbits, const void *key, 147 | unsigned char ivec[16], int enc, 148 | block128_f block) 149 | { 150 | int n, rem, num; 151 | unsigned char ovec[16 * 2 + 1]; /* +1 because we dereference (but don't 152 | * use) one byte off the end */ 153 | 154 | if (nbits <= 0 || nbits > 128) 155 | return; 156 | 157 | /* fill in the first half of the new IV with the current IV */ 158 | memcpy(ovec, ivec, 16); 159 | /* construct the new IV */ 160 | (*block) (ivec, ivec, key); 161 | num = (nbits + 7) / 8; 162 | if (enc) /* encrypt the input */ 163 | for (n = 0; n < num; ++n) 164 | out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); 165 | else /* decrypt the input */ 166 | for (n = 0; n < num; ++n) 167 | out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; 168 | /* shift ovec left... */ 169 | rem = nbits % 8; 170 | num = nbits / 8; 171 | if (rem == 0) 172 | memcpy(ivec, ovec + num, 16); 173 | else 174 | for (n = 0; n < 16; ++n) 175 | ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); 176 | 177 | /* it is not necessary to cleanse ovec, since the IV is not secret */ 178 | } 179 | 180 | /* N.B. This expects the input to be packed, MS bit first */ 181 | void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, 182 | size_t bits, const void *key, 183 | unsigned char ivec[16], int *num, 184 | int enc, block128_f block) 185 | { 186 | size_t n; 187 | unsigned char c[1], d[1]; 188 | 189 | for (n = 0; n < bits; ++n) { 190 | c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 191 | cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); 192 | out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) | 193 | ((d[0] & 0x80) >> (unsigned int)(n % 8)); 194 | } 195 | } 196 | 197 | void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, 198 | size_t length, const void *key, 199 | unsigned char ivec[16], int *num, 200 | int enc, block128_f block) 201 | { 202 | size_t n; 203 | 204 | for (n = 0; n < length; ++n) 205 | cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); 206 | } 207 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_ige.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | //#include "internal/cryptlib.h" 11 | 12 | #include 13 | #include "aes_local.h" 14 | 15 | /* XXX: probably some better way to do this */ 16 | #if defined(__i386__) || defined(__x86_64__) 17 | # define UNALIGNED_MEMOPS_ARE_FAST 1 18 | #else 19 | # define UNALIGNED_MEMOPS_ARE_FAST 0 20 | #endif 21 | 22 | #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) 23 | typedef struct { 24 | unsigned long data[N_WORDS]; 25 | #if defined(__GNUC__) && UNALIGNED_MEMOPS_ARE_FAST 26 | } aes_block_t __attribute((__aligned__(1))); 27 | #else 28 | } aes_block_t; 29 | #endif 30 | 31 | #if UNALIGNED_MEMOPS_ARE_FAST 32 | # define load_block(d, s) (d) = *(const aes_block_t *)(s) 33 | # define store_block(d, s) *(aes_block_t *)(d) = (s) 34 | #else 35 | # define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) 36 | # define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) 37 | #endif 38 | 39 | /* N.B. The IV for this mode is _twice_ the block size */ 40 | 41 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, 42 | size_t length, const AES_KEY *key, 43 | unsigned char *ivec, const int enc) 44 | { 45 | size_t n; 46 | size_t len = length; 47 | 48 | if (length == 0) 49 | return; 50 | 51 | /*OPENSSL_assert(in && out && key && ivec); 52 | OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); 53 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);*/ 54 | 55 | len = length / AES_BLOCK_SIZE; 56 | 57 | if (AES_ENCRYPT == enc) { 58 | if (in != out && 59 | (UNALIGNED_MEMOPS_ARE_FAST 60 | || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == 61 | 0)) { 62 | aes_block_t *ivp = (aes_block_t *) ivec; 63 | aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); 64 | 65 | while (len) { 66 | aes_block_t *inp = (aes_block_t *) in; 67 | aes_block_t *outp = (aes_block_t *) out; 68 | 69 | for (n = 0; n < N_WORDS; ++n) 70 | outp->data[n] = inp->data[n] ^ ivp->data[n]; 71 | AES_encrypt((unsigned char *)outp->data, 72 | (unsigned char *)outp->data, key); 73 | for (n = 0; n < N_WORDS; ++n) 74 | outp->data[n] ^= iv2p->data[n]; 75 | ivp = outp; 76 | iv2p = inp; 77 | --len; 78 | in += AES_BLOCK_SIZE; 79 | out += AES_BLOCK_SIZE; 80 | } 81 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); 82 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); 83 | } else { 84 | aes_block_t tmp, tmp2; 85 | aes_block_t iv; 86 | aes_block_t iv2; 87 | 88 | load_block(iv, ivec); 89 | load_block(iv2, ivec + AES_BLOCK_SIZE); 90 | 91 | while (len) { 92 | load_block(tmp, in); 93 | for (n = 0; n < N_WORDS; ++n) 94 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; 95 | AES_encrypt((unsigned char *)tmp2.data, 96 | (unsigned char *)tmp2.data, key); 97 | for (n = 0; n < N_WORDS; ++n) 98 | tmp2.data[n] ^= iv2.data[n]; 99 | store_block(out, tmp2); 100 | iv = tmp2; 101 | iv2 = tmp; 102 | --len; 103 | in += AES_BLOCK_SIZE; 104 | out += AES_BLOCK_SIZE; 105 | } 106 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); 107 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); 108 | } 109 | } else { 110 | if (in != out && 111 | (UNALIGNED_MEMOPS_ARE_FAST 112 | || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == 113 | 0)) { 114 | aes_block_t *ivp = (aes_block_t *) ivec; 115 | aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); 116 | 117 | while (len) { 118 | aes_block_t tmp; 119 | aes_block_t *inp = (aes_block_t *) in; 120 | aes_block_t *outp = (aes_block_t *) out; 121 | 122 | for (n = 0; n < N_WORDS; ++n) 123 | tmp.data[n] = inp->data[n] ^ iv2p->data[n]; 124 | AES_decrypt((unsigned char *)tmp.data, 125 | (unsigned char *)outp->data, key); 126 | for (n = 0; n < N_WORDS; ++n) 127 | outp->data[n] ^= ivp->data[n]; 128 | ivp = inp; 129 | iv2p = outp; 130 | --len; 131 | in += AES_BLOCK_SIZE; 132 | out += AES_BLOCK_SIZE; 133 | } 134 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); 135 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); 136 | } else { 137 | aes_block_t tmp, tmp2; 138 | aes_block_t iv; 139 | aes_block_t iv2; 140 | 141 | load_block(iv, ivec); 142 | load_block(iv2, ivec + AES_BLOCK_SIZE); 143 | 144 | while (len) { 145 | load_block(tmp, in); 146 | tmp2 = tmp; 147 | for (n = 0; n < N_WORDS; ++n) 148 | tmp.data[n] ^= iv2.data[n]; 149 | AES_decrypt((unsigned char *)tmp.data, 150 | (unsigned char *)tmp.data, key); 151 | for (n = 0; n < N_WORDS; ++n) 152 | tmp.data[n] ^= iv.data[n]; 153 | store_block(out, tmp); 154 | iv = tmp2; 155 | iv2 = tmp; 156 | --len; 157 | in += AES_BLOCK_SIZE; 158 | out += AES_BLOCK_SIZE; 159 | } 160 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); 161 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); 162 | } 163 | } 164 | } 165 | 166 | /* 167 | * Note that its effectively impossible to do biIGE in anything other 168 | * than a single pass, so no provision is made for chaining. 169 | */ 170 | 171 | /* N.B. The IV for this mode is _four times_ the block size */ 172 | 173 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, 174 | size_t length, const AES_KEY *key, 175 | const AES_KEY *key2, const unsigned char *ivec, 176 | const int enc) 177 | { 178 | size_t n; 179 | size_t len = length; 180 | unsigned char tmp[AES_BLOCK_SIZE]; 181 | unsigned char tmp2[AES_BLOCK_SIZE]; 182 | unsigned char tmp3[AES_BLOCK_SIZE]; 183 | unsigned char prev[AES_BLOCK_SIZE]; 184 | const unsigned char *iv; 185 | const unsigned char *iv2; 186 | 187 | /*OPENSSL_assert(in && out && key && ivec); 188 | OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); 189 | OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);*/ 190 | 191 | if (AES_ENCRYPT == enc) { 192 | /* 193 | * XXX: Do a separate case for when in != out (strictly should check 194 | * for overlap, too) 195 | */ 196 | 197 | /* First the forward pass */ 198 | iv = ivec; 199 | iv2 = ivec + AES_BLOCK_SIZE; 200 | while (len >= AES_BLOCK_SIZE) { 201 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 202 | out[n] = in[n] ^ iv[n]; 203 | AES_encrypt(out, out, key); 204 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 205 | out[n] ^= iv2[n]; 206 | iv = out; 207 | memcpy(prev, in, AES_BLOCK_SIZE); 208 | iv2 = prev; 209 | len -= AES_BLOCK_SIZE; 210 | in += AES_BLOCK_SIZE; 211 | out += AES_BLOCK_SIZE; 212 | } 213 | 214 | /* And now backwards */ 215 | iv = ivec + AES_BLOCK_SIZE * 2; 216 | iv2 = ivec + AES_BLOCK_SIZE * 3; 217 | len = length; 218 | while (len >= AES_BLOCK_SIZE) { 219 | out -= AES_BLOCK_SIZE; 220 | /* 221 | * XXX: reduce copies by alternating between buffers 222 | */ 223 | memcpy(tmp, out, AES_BLOCK_SIZE); 224 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 225 | out[n] ^= iv[n]; 226 | /* 227 | * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); 228 | */ 229 | AES_encrypt(out, out, key); 230 | /* 231 | * hexdump(stdout,"enc", out, AES_BLOCK_SIZE); 232 | */ 233 | /* 234 | * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); 235 | */ 236 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 237 | out[n] ^= iv2[n]; 238 | /* 239 | * hexdump(stdout,"out", out, AES_BLOCK_SIZE); 240 | */ 241 | iv = out; 242 | memcpy(prev, tmp, AES_BLOCK_SIZE); 243 | iv2 = prev; 244 | len -= AES_BLOCK_SIZE; 245 | } 246 | } else { 247 | /* First backwards */ 248 | iv = ivec + AES_BLOCK_SIZE * 2; 249 | iv2 = ivec + AES_BLOCK_SIZE * 3; 250 | in += length; 251 | out += length; 252 | while (len >= AES_BLOCK_SIZE) { 253 | in -= AES_BLOCK_SIZE; 254 | out -= AES_BLOCK_SIZE; 255 | memcpy(tmp, in, AES_BLOCK_SIZE); 256 | memcpy(tmp2, in, AES_BLOCK_SIZE); 257 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 258 | tmp[n] ^= iv2[n]; 259 | AES_decrypt(tmp, out, key); 260 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 261 | out[n] ^= iv[n]; 262 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 263 | iv = tmp3; 264 | iv2 = out; 265 | len -= AES_BLOCK_SIZE; 266 | } 267 | 268 | /* And now forwards */ 269 | iv = ivec; 270 | iv2 = ivec + AES_BLOCK_SIZE; 271 | len = length; 272 | while (len >= AES_BLOCK_SIZE) { 273 | memcpy(tmp, out, AES_BLOCK_SIZE); 274 | memcpy(tmp2, out, AES_BLOCK_SIZE); 275 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 276 | tmp[n] ^= iv2[n]; 277 | AES_decrypt(tmp, out, key); 278 | for (n = 0; n < AES_BLOCK_SIZE; ++n) 279 | out[n] ^= iv[n]; 280 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); 281 | iv = tmp3; 282 | iv2 = out; 283 | len -= AES_BLOCK_SIZE; 284 | in += AES_BLOCK_SIZE; 285 | out += AES_BLOCK_SIZE; 286 | } 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/include/openssl/modes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | #ifndef HEADER_MODES_H 11 | # define HEADER_MODES_H 12 | 13 | # include 14 | 15 | # ifdef __cplusplus 16 | extern "C" { 17 | # endif 18 | typedef void (*block128_f) (const unsigned char in[16], 19 | unsigned char out[16], const void *key); 20 | 21 | typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, 22 | size_t len, const void *key, 23 | unsigned char ivec[16], int enc); 24 | 25 | typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, 26 | size_t blocks, const void *key, 27 | const unsigned char ivec[16]); 28 | 29 | typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, 30 | size_t blocks, const void *key, 31 | const unsigned char ivec[16], 32 | unsigned char cmac[16]); 33 | 34 | void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, 35 | size_t len, const void *key, 36 | unsigned char ivec[16], block128_f block); 37 | void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, 38 | size_t len, const void *key, 39 | unsigned char ivec[16], block128_f block); 40 | 41 | void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, 42 | size_t len, const void *key, 43 | unsigned char ivec[16], 44 | unsigned char ecount_buf[16], unsigned int *num, 45 | block128_f block); 46 | 47 | void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, 48 | size_t len, const void *key, 49 | unsigned char ivec[16], 50 | unsigned char ecount_buf[16], 51 | unsigned int *num, ctr128_f ctr); 52 | 53 | void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, 54 | size_t len, const void *key, 55 | unsigned char ivec[16], int *num, 56 | block128_f block); 57 | 58 | void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, 59 | size_t len, const void *key, 60 | unsigned char ivec[16], int *num, 61 | int enc, block128_f block); 62 | void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, 63 | size_t length, const void *key, 64 | unsigned char ivec[16], int *num, 65 | int enc, block128_f block); 66 | void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, 67 | size_t bits, const void *key, 68 | unsigned char ivec[16], int *num, 69 | int enc, block128_f block); 70 | 71 | size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, 72 | unsigned char *out, size_t len, 73 | const void *key, unsigned char ivec[16], 74 | block128_f block); 75 | size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, 76 | size_t len, const void *key, 77 | unsigned char ivec[16], cbc128_f cbc); 78 | size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, 79 | unsigned char *out, size_t len, 80 | const void *key, unsigned char ivec[16], 81 | block128_f block); 82 | size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, 83 | size_t len, const void *key, 84 | unsigned char ivec[16], cbc128_f cbc); 85 | 86 | size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, 87 | unsigned char *out, size_t len, 88 | const void *key, 89 | unsigned char ivec[16], 90 | block128_f block); 91 | size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, 92 | size_t len, const void *key, 93 | unsigned char ivec[16], cbc128_f cbc); 94 | size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, 95 | unsigned char *out, size_t len, 96 | const void *key, 97 | unsigned char ivec[16], 98 | block128_f block); 99 | size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, 100 | size_t len, const void *key, 101 | unsigned char ivec[16], cbc128_f cbc); 102 | 103 | typedef struct gcm128_context GCM128_CONTEXT; 104 | 105 | GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); 106 | void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); 107 | void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, 108 | size_t len); 109 | int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, 110 | size_t len); 111 | int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, 112 | const unsigned char *in, unsigned char *out, 113 | size_t len); 114 | int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, 115 | const unsigned char *in, unsigned char *out, 116 | size_t len); 117 | int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, 118 | const unsigned char *in, unsigned char *out, 119 | size_t len, ctr128_f stream); 120 | int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, 121 | const unsigned char *in, unsigned char *out, 122 | size_t len, ctr128_f stream); 123 | int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, 124 | size_t len); 125 | void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); 126 | void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); 127 | 128 | typedef struct ccm128_context CCM128_CONTEXT; 129 | 130 | void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, 131 | unsigned int M, unsigned int L, void *key, 132 | block128_f block); 133 | int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, 134 | size_t nlen, size_t mlen); 135 | void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, 136 | size_t alen); 137 | int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, 138 | unsigned char *out, size_t len); 139 | int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, 140 | unsigned char *out, size_t len); 141 | int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, 142 | unsigned char *out, size_t len, 143 | ccm128_f stream); 144 | int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, 145 | unsigned char *out, size_t len, 146 | ccm128_f stream); 147 | size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); 148 | 149 | typedef struct xts128_context XTS128_CONTEXT; 150 | 151 | int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, 152 | const unsigned char iv[16], 153 | const unsigned char *inp, unsigned char *out, 154 | size_t len, int enc); 155 | 156 | size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, 157 | unsigned char *out, 158 | const unsigned char *in, size_t inlen, 159 | block128_f block); 160 | 161 | size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, 162 | unsigned char *out, 163 | const unsigned char *in, size_t inlen, 164 | block128_f block); 165 | size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, 166 | unsigned char *out, const unsigned char *in, 167 | size_t inlen, block128_f block); 168 | size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, 169 | unsigned char *out, const unsigned char *in, 170 | size_t inlen, block128_f block); 171 | 172 | # ifndef OPENSSL_NO_OCB 173 | typedef struct ocb128_context OCB128_CONTEXT; 174 | 175 | typedef void (*ocb128_f) (const unsigned char *in, unsigned char *out, 176 | size_t blocks, const void *key, 177 | size_t start_block_num, 178 | unsigned char offset_i[16], 179 | const unsigned char L_[][16], 180 | unsigned char checksum[16]); 181 | 182 | OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec, 183 | block128_f encrypt, block128_f decrypt, 184 | ocb128_f stream); 185 | int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec, 186 | block128_f encrypt, block128_f decrypt, 187 | ocb128_f stream); 188 | int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src, 189 | void *keyenc, void *keydec); 190 | int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv, 191 | size_t len, size_t taglen); 192 | int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad, 193 | size_t len); 194 | int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, const unsigned char *in, 195 | unsigned char *out, size_t len); 196 | int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, const unsigned char *in, 197 | unsigned char *out, size_t len); 198 | int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, 199 | size_t len); 200 | int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len); 201 | void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx); 202 | # endif /* OPENSSL_NO_OCB */ 203 | 204 | # ifdef __cplusplus 205 | } 206 | # endif 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/NativeUtil.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "encode/base64.h" 9 | 10 | static const char *PACKAGE_NAME = "com.jni.encrypt.test"; 11 | static const char *RELEASE_SIGN = "308202e4308201cc020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b30090603550406130255533020170d3230303333313132353835325a180f32303530303332343132353835325a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b300906035504061302555330820122300d06092a864886f70d01010105000382010f003082010a0282010100829a027cf7e1e42097fe3904423fc2ca7063b15764da55032192d237f1a9f636030dc94b91692f9387e164d86ebadf302142ccfa404d28dabf5822d0346080ebb88f965ba5f6d5021d397e9420365a8880f79e8fa0fb60c40b967d731429180dc4a0046dc611d16d956ebd6b7e7c8ad2603c7ff96c0856c24eb908af81c7759067dad905672be01a54da805b9652ce2e5fc909852efec5eefd2eaec6ad680f088cfd6ff14e412015aa24b3a19a6ddfc03f4ef52811f949bd187dd5787b3c1337fd28736e24fa9ba51853a072bbd8a4c901907ac0da14338e71a678137dfc7dabd7fc850505ff2497278797f4649a061184b40a944b7a1da92367e62cb3e08ddb0203010001300d06092a864886f70d01010505000382010100133a66505b18e02561795578244b223edff324bb6d0e9f40815290ff7d37bb8854a747a89d1c1d7944340f95fb530be86734d47c38db1b338783774875bc50b4426846dce0dceb47b5d33401ec21c2bd46cce3f627eecd6a093c164bf74456f183c459f5408a964a74472912f9f06d4637d3a10e97caf3a7a0872aaceb45f33b3e29e0d4f1c884eeb6828db80ff22b9311c5f9722fdf5a7c6b07eb0c911139992f35f93c99ed96a513665edf9c389ddd3342d8efa6d19f0b82dd7e96662f8861bd8360eb6c4d53ab82e9d92cd42bd77fd7eda14f5866a18fad103329a51cbdc2cf8224ddf852ba51f94e0efa924452c068af1fd231b183249c8212f1e82a4ff8"; 12 | 13 | static const unsigned char password[] = "ynadcc@p$abw0rdcdbttye$38949!@$@"; 14 | static const int pwdBitsLength = 256; 15 | static const unsigned char iv[] = "=o&g%m,*o?dL~def"; 16 | static bool initSuccess = false; 17 | 18 | /** 19 | * 加密之前进行填充 20 | * @param buf 输入数据 21 | * @param size 输入数据长度 22 | * @param final_size 填充后的数据长度 23 | * @return 填充后的数据 24 | */ 25 | unsigned char *padding_buf(const char *buf, size_t size, size_t *final_size) { 26 | unsigned char *ret = NULL; 27 | size_t padding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE); 28 | size_t i; 29 | *final_size = size + padding_size; 30 | ret = (unsigned char *) malloc(*final_size + 1); 31 | memcpy(ret, buf, size); 32 | const unsigned char paddingChar = (unsigned char) padding_size; 33 | for (i = size; i < *final_size; i++) { 34 | // zero padding算法: 35 | // ret[i] = 0; 36 | // or PKCS7Padding算法 37 | ret[i] = paddingChar; 38 | } 39 | ret[*final_size] = '\0'; 40 | return ret; 41 | } 42 | 43 | unsigned char *getIv() { 44 | size_t len = strlen((char *) iv); 45 | unsigned char *ivCopy = (unsigned char *) malloc(len); 46 | memcpy(ivCopy, iv, len); 47 | return ivCopy; 48 | } 49 | 50 | AES_KEY *getAesKey() { 51 | AES_KEY *aes_key = (AES_KEY *) malloc(sizeof(AES_KEY)); 52 | AES_set_encrypt_key(password, pwdBitsLength, aes_key); 53 | return aes_key; 54 | } 55 | 56 | extern "C" 57 | JNIEXPORT jstring JNICALL nativeEncrypt( 58 | JNIEnv *env, jclass /* this */, jstring plainText) { 59 | bool newLine = false; 60 | const char *inChars = (env->GetStringUTFChars(plainText, JNI_FALSE)); 61 | const size_t originalLength = strlen(inChars); 62 | size_t paddedLength = 0; 63 | unsigned char *in = padding_buf(inChars, originalLength, &paddedLength); 64 | env->ReleaseStringUTFChars(plainText, inChars); 65 | unsigned char *encryptOut = (unsigned char *) malloc((paddedLength) * sizeof(unsigned char)); 66 | int num = 0; 67 | unsigned char *ivec = getIv(); 68 | AES_KEY *aes_key = getAesKey(); 69 | AES_cfb128_encrypt(in, encryptOut, paddedLength, aes_key, ivec, &num, AES_ENCRYPT); 70 | free(in); 71 | free(ivec); 72 | free(aes_key); 73 | /* 74 | * //十六进制字符串转换 75 | * char *result = (char *) malloc((paddedLength * 2 + 1) * sizeof(char)); 76 | convert_hex(out, paddedLength, result); 77 | */ 78 | unsigned char *base64OutBuf = static_cast(malloc(sizeof(unsigned char) * calcBase64EncodeBufLen(paddedLength, newLine))); 79 | encodeB64(encryptOut, base64OutBuf, paddedLength, newLine); 80 | free(encryptOut); 81 | jstring tmp = env->NewStringUTF(reinterpret_cast(base64OutBuf)); 82 | free(base64OutBuf); 83 | return tmp; 84 | } 85 | 86 | extern "C" 87 | JNIEXPORT jstring JNICALL nativeDecrypt( 88 | JNIEnv *env, jclass /* this */, jstring encryptText) { 89 | const char *inChars = (env->GetStringUTFChars(encryptText, JNI_FALSE)); 90 | const size_t dataLen = strlen(inChars); 91 | unsigned char *in = static_cast(malloc(sizeof(unsigned char) * dataLen / 4 * 3)); 92 | const size_t outPaddedLength = decodeB64(reinterpret_cast(inChars), in, dataLen); 93 | env->ReleaseStringUTFChars(encryptText, inChars); 94 | /* 95 | * //十六进制字符串转换 96 | * unsigned char *in = (unsigned char *) malloc( 97 | (outPaddedLength + 1) * sizeof(unsigned char)); 98 | hexConvertToUnsignedChar((unsigned char *) inChars, outPaddedLength, in); 99 | */ 100 | unsigned char *out = (unsigned char *) malloc((outPaddedLength) * sizeof(unsigned char)); 101 | int num = 0; 102 | unsigned char *ivec = getIv(); 103 | AES_KEY *aes_key = getAesKey(); 104 | AES_cfb128_encrypt(in, out, outPaddedLength, aes_key, ivec, &num, AES_DECRYPT); 105 | free(in); 106 | free(aes_key); 107 | free(ivec); 108 | const int pad = (int) out[outPaddedLength - 1]; 109 | out[outPaddedLength - pad] = '\0'; 110 | jstring tmp = env->NewStringUTF((char *) out); 111 | free(out); 112 | return tmp; 113 | } 114 | 115 | extern "C" 116 | JNIEXPORT jstring JNICALL base64Encode( 117 | JNIEnv *env, 118 | jclass /* this */, jstring plainText, jboolean doNewLine) { 119 | const char *inChars = (env->GetStringUTFChars(plainText, JNI_FALSE)); 120 | size_t rawDataSize = strlen(inChars); 121 | if (rawDataSize <= 0) { 122 | env->ReleaseStringUTFChars(plainText, inChars); 123 | return plainText; 124 | } 125 | unsigned char *out = (unsigned char *) malloc((calcBase64EncodeBufLen(rawDataSize, doNewLine)) * sizeof(unsigned char)); 126 | encodeB64((const unsigned char *) inChars, out, rawDataSize, doNewLine); 127 | env->ReleaseStringUTFChars(plainText, inChars); 128 | jstring tmp = env->NewStringUTF(reinterpret_cast(out)); 129 | free(out); 130 | return tmp; 131 | } 132 | 133 | extern "C" 134 | JNIEXPORT jstring JNICALL base64Decode( 135 | JNIEnv *env, 136 | jclass /* this */, jstring encodedText) { 137 | const char *inChars = (env->GetStringUTFChars(encodedText, JNI_FALSE)); 138 | const size_t dataLen = strlen(inChars); 139 | if (dataLen <= 0) { 140 | env->ReleaseStringUTFChars(encodedText, inChars); 141 | return encodedText; 142 | } 143 | unsigned char *outBuf = static_cast(malloc(sizeof(unsigned char) * dataLen / 4 * 3)); 144 | decodeB64(reinterpret_cast(inChars), outBuf, dataLen); 145 | env->ReleaseStringUTFChars(encodedText, inChars); 146 | jstring tmp = env->NewStringUTF(reinterpret_cast(outBuf)); 147 | free(outBuf); 148 | return tmp; 149 | } 150 | 151 | /** 152 | * 初始化,验证使用so库应用的合法性 153 | */ 154 | extern "C" 155 | JNIEXPORT jboolean JNICALL initNative(JNIEnv *env, 156 | jclass /* this */, jobject appContext) { 157 | jclass appContextCls = env->FindClass("android/content/Context"); 158 | jmethodID getPackageManager = env->GetMethodID(appContextCls, "getPackageManager", "()Landroid/content/pm/PackageManager;"); 159 | jmethodID getPackageName = env->GetMethodID(appContextCls, "getPackageName", "()Ljava/lang/String;"); 160 | jstring packageName = static_cast(env->CallObjectMethod(appContext, getPackageName)); 161 | const char *packageNameChar = env->GetStringUTFChars(packageName, JNI_FALSE); 162 | const bool packageNameSame = strcmp(PACKAGE_NAME, packageNameChar) == 0; 163 | env->ReleaseStringUTFChars(packageName, packageNameChar); 164 | 165 | if (!packageNameSame) { 166 | env->DeleteLocalRef(appContextCls); 167 | env->DeleteLocalRef(packageName); 168 | initSuccess = false; 169 | return initSuccess; 170 | } 171 | 172 | jclass pmCls = env->FindClass("android/content/pm/PackageManager"); 173 | jmethodID getPackageInfo = env->GetMethodID(pmCls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); 174 | jclass signatureCls = env->FindClass("android/content/pm/Signature"); 175 | jmethodID toCharsString = env->GetMethodID(signatureCls, "toCharsString", "()Ljava/lang/String;"); 176 | jclass packageInfoCls = env->FindClass("android/content/pm/PackageInfo"); 177 | jfieldID signatures = env->GetFieldID(packageInfoCls, "signatures", "[Landroid/content/pm/Signature;"); 178 | 179 | jobject packageManager = env->CallObjectMethod(appContext, getPackageManager); 180 | 181 | jobject packageInfo = env->CallObjectMethod(packageManager, getPackageInfo, packageName, 64); 182 | jobjectArray signatureArray = static_cast(env->GetObjectField(packageInfo, 183 | signatures)); 184 | jobject firstSignature = env->GetObjectArrayElement(signatureArray, 0); 185 | jstring sign = static_cast(env->CallObjectMethod(firstSignature, toCharsString)); 186 | 187 | env->DeleteLocalRef(appContextCls); 188 | env->DeleteLocalRef(pmCls); 189 | env->DeleteLocalRef(signatureCls); 190 | env->DeleteLocalRef(packageInfoCls); 191 | env->DeleteLocalRef(packageManager); 192 | env->DeleteLocalRef(packageName); 193 | env->DeleteLocalRef(packageInfo); 194 | env->DeleteLocalRef(signatureArray); 195 | env->DeleteLocalRef(firstSignature); 196 | 197 | const char *signChar = env->GetStringUTFChars(sign, JNI_FALSE); 198 | initSuccess = strcmp(RELEASE_SIGN, signChar) == 0; 199 | env->ReleaseStringUTFChars(sign, signChar); 200 | env->DeleteLocalRef(sign); 201 | return initSuccess; 202 | } 203 | 204 | static const char* const nativeUtilPath = "com/jni/encrypt/NativeUtil"; 205 | static const JNINativeMethod nativeMethods[] = { 206 | {"encrypt", "(Ljava/lang/String;)Ljava/lang/String;", (void *)nativeEncrypt}, 207 | {"decrypt","(Ljava/lang/String;)Ljava/lang/String;",(void *)nativeDecrypt}, 208 | {"base64Encode","(Ljava/lang/String;Z)Ljava/lang/String;",(void *)base64Encode}, 209 | {"base64Decode","(Ljava/lang/String;)Ljava/lang/String;",(void *)base64Decode}, 210 | {"init","(Landroid/content/Context;)Z",(void *)initNative} 211 | }; 212 | 213 | extern "C" 214 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { 215 | const jint error = JNI_ERR; 216 | JNIEnv *env = nullptr; 217 | if (jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_4) != JNI_OK) { 218 | return error; 219 | } 220 | jclass nativeUtilCls = env->FindClass(nativeUtilPath); 221 | if (nativeUtilCls == nullptr) { 222 | printf("cannot find class: %s\n", nativeUtilPath); 223 | return error; 224 | } 225 | const jint reg = env->RegisterNatives(nativeUtilCls, nativeMethods, 226 | sizeof(nativeMethods) / sizeof(nativeMethods[0])); 227 | env->DeleteLocalRef(nativeUtilCls); 228 | if (reg < 0) { 229 | printf("register native method failed!\n"); 230 | return error; 231 | } 232 | return JNI_VERSION_1_4; 233 | } 234 | -------------------------------------------------------------------------------- /NativeEncrypt/src/main/cpp/crypto/aes/aes_x86core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. 3 | * 4 | * Licensed under the OpenSSL license (the "License"). You may not use 5 | * this file except in compliance with the License. You can obtain a copy 6 | * in the file LICENSE in the source distribution or at 7 | * https://www.openssl.org/source/license.html 8 | */ 9 | 10 | /* 11 | * This is experimental x86[_64] derivative. It assumes little-endian 12 | * byte order and expects CPU to sustain unaligned memory references. 13 | * It is used as playground for cache-time attack mitigations and 14 | * serves as reference C implementation for x86[_64] as well as some 15 | * other assembly modules. 16 | */ 17 | 18 | /** 19 | * rijndael-alg-fst.c 20 | * 21 | * @version 3.0 (December 2000) 22 | * 23 | * Optimised ANSI C code for the Rijndael cipher (now AES) 24 | * 25 | * @author Vincent Rijmen 26 | * @author Antoon Bosselaers 27 | * @author Paulo Barreto 28 | * 29 | * This code is hereby placed in the public domain. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS 32 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 33 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 35 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 36 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 38 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 39 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 40 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 41 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 | */ 43 | 44 | 45 | #include 46 | 47 | #include 48 | #include 49 | #include "aes_local.h" 50 | 51 | /* 52 | * These two parameters control which table, 256-byte or 2KB, is 53 | * referenced in outer and respectively inner rounds. 54 | */ 55 | #define AES_COMPACT_IN_OUTER_ROUNDS 56 | #ifdef AES_COMPACT_IN_OUTER_ROUNDS 57 | /* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while 58 | * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further* 59 | * by factor of ~2. */ 60 | # undef AES_COMPACT_IN_INNER_ROUNDS 61 | #endif 62 | 63 | #if 1 64 | static void prefetch256(const void *table) 65 | { 66 | volatile unsigned long *t=(void *)table,ret; 67 | unsigned long sum; 68 | int i; 69 | 70 | /* 32 is common least cache-line size */ 71 | for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0])) sum ^= t[i]; 72 | 73 | ret = sum; 74 | } 75 | #else 76 | # define prefetch256(t) 77 | #endif 78 | 79 | #undef GETU32 80 | #define GETU32(p) (*((u32*)(p))) 81 | 82 | #if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) 83 | typedef unsigned __int64 u64; 84 | #define U64(C) C##UI64 85 | #elif defined(__arch64__) 86 | typedef unsigned long u64; 87 | #define U64(C) C##UL 88 | #else 89 | typedef unsigned long long u64; 90 | #define U64(C) C##ULL 91 | #endif 92 | 93 | #undef ROTATE 94 | #if defined(_MSC_VER) 95 | # define ROTATE(a,n) _lrotl(a,n) 96 | #elif defined(__ICC) 97 | # define ROTATE(a,n) _rotl(a,n) 98 | #elif defined(__GNUC__) && __GNUC__>=2 99 | # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) 100 | # define ROTATE(a,n) ({ register unsigned int ret; \ 101 | asm ( \ 102 | "roll %1,%0" \ 103 | : "=r"(ret) \ 104 | : "I"(n), "0"(a) \ 105 | : "cc"); \ 106 | ret; \ 107 | }) 108 | # endif 109 | #endif 110 | /*- 111 | Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03]; 112 | Te0[x] = S [x].[02, 01, 01, 03]; 113 | Te1[x] = S [x].[03, 02, 01, 01]; 114 | Te2[x] = S [x].[01, 03, 02, 01]; 115 | Te3[x] = S [x].[01, 01, 03, 02]; 116 | */ 117 | #define Te0 (u32)((u64*)((u8*)Te+0)) 118 | #define Te1 (u32)((u64*)((u8*)Te+3)) 119 | #define Te2 (u32)((u64*)((u8*)Te+2)) 120 | #define Te3 (u32)((u64*)((u8*)Te+1)) 121 | /*- 122 | Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b]; 123 | Td0[x] = Si[x].[0e, 09, 0d, 0b]; 124 | Td1[x] = Si[x].[0b, 0e, 09, 0d]; 125 | Td2[x] = Si[x].[0d, 0b, 0e, 09]; 126 | Td3[x] = Si[x].[09, 0d, 0b, 0e]; 127 | Td4[x] = Si[x].[01]; 128 | */ 129 | #define Td0 (u32)((u64*)((u8*)Td+0)) 130 | #define Td1 (u32)((u64*)((u8*)Td+3)) 131 | #define Td2 (u32)((u64*)((u8*)Td+2)) 132 | #define Td3 (u32)((u64*)((u8*)Td+1)) 133 | 134 | static const u64 Te[256] = { 135 | U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8), 136 | U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6), 137 | U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6), 138 | U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591), 139 | U64(0x5030306050303060), U64(0x0301010203010102), 140 | U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56), 141 | U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5), 142 | U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec), 143 | U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f), 144 | U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa), 145 | U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2), 146 | U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb), 147 | U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3), 148 | U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45), 149 | U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453), 150 | U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b), 151 | U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1), 152 | U64(0xae93933dae93933d), U64(0x6a26264c6a26264c), 153 | U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e), 154 | U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83), 155 | U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551), 156 | U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9), 157 | U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab), 158 | U64(0x5331316253313162), U64(0x3f15152a3f15152a), 159 | U64(0x0c0404080c040408), U64(0x52c7c79552c7c795), 160 | U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d), 161 | U64(0x2818183028181830), U64(0xa1969637a1969637), 162 | U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f), 163 | U64(0x0907070e0907070e), U64(0x3612122436121224), 164 | U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df), 165 | U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e), 166 | U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea), 167 | U64(0x1b0909121b090912), U64(0x9e83831d9e83831d), 168 | U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34), 169 | U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc), 170 | U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b), 171 | U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76), 172 | U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d), 173 | U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd), 174 | U64(0x712f2f5e712f2f5e), U64(0x9784841397848413), 175 | U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9), 176 | U64(0x0000000000000000), U64(0x2cededc12cededc1), 177 | U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3), 178 | U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6), 179 | U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d), 180 | U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972), 181 | U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98), 182 | U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85), 183 | U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5), 184 | U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed), 185 | U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a), 186 | U64(0x5533336655333366), U64(0x9485851194858511), 187 | U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9), 188 | U64(0x0602020406020204), U64(0x817f7ffe817f7ffe), 189 | U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78), 190 | U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b), 191 | U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d), 192 | U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05), 193 | U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21), 194 | U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1), 195 | U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677), 196 | U64(0x75dadaaf75dadaaf), U64(0x6321214263212142), 197 | U64(0x3010102030101020), U64(0x1affffe51affffe5), 198 | U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf), 199 | U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18), 200 | U64(0x3513132635131326), U64(0x2fececc32fececc3), 201 | U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735), 202 | U64(0xcc444488cc444488), U64(0x3917172e3917172e), 203 | U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755), 204 | U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a), 205 | U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba), 206 | U64(0x2b1919322b191932), U64(0x957373e6957373e6), 207 | U64(0xa06060c0a06060c0), U64(0x9881811998818119), 208 | U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3), 209 | U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54), 210 | U64(0xab90903bab90903b), U64(0x8388880b8388880b), 211 | U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7), 212 | U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428), 213 | U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc), 214 | U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad), 215 | U64(0x3be0e0db3be0e0db), U64(0x5632326456323264), 216 | U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14), 217 | U64(0xdb494992db494992), U64(0x0a06060c0a06060c), 218 | U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8), 219 | U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd), 220 | U64(0xefacac43efacac43), U64(0xa66262c4a66262c4), 221 | U64(0xa8919139a8919139), U64(0xa4959531a4959531), 222 | U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2), 223 | U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b), 224 | U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda), 225 | U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1), 226 | U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949), 227 | U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac), 228 | U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf), 229 | U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4), 230 | U64(0xe9aeae47e9aeae47), U64(0x1808081018080810), 231 | U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0), 232 | U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c), 233 | U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657), 234 | U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697), 235 | U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1), 236 | U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e), 237 | U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61), 238 | U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f), 239 | U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c), 240 | U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc), 241 | U64(0xd8484890d8484890), U64(0x0503030605030306), 242 | U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c), 243 | U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a), 244 | U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969), 245 | U64(0x9186861791868617), U64(0x58c1c19958c1c199), 246 | U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27), 247 | U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb), 248 | U64(0xb398982bb398982b), U64(0x3311112233111122), 249 | U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9), 250 | U64(0x898e8e07898e8e07), U64(0xa7949433a7949433), 251 | U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c), 252 | U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9), 253 | U64(0x49cece8749cece87), U64(0xff5555aaff5555aa), 254 | U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5), 255 | U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159), 256 | U64(0x8089890980898909), U64(0x170d0d1a170d0d1a), 257 | U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7), 258 | U64(0xc6424284c6424284), U64(0xb86868d0b86868d0), 259 | U64(0xc3414182c3414182), U64(0xb0999929b0999929), 260 | U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e), 261 | U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8), 262 | U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c) 263 | }; 264 | 265 | static const u8 Te4[256] = { 266 | 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, 267 | 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, 268 | 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, 269 | 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, 270 | 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, 271 | 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, 272 | 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, 273 | 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, 274 | 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, 275 | 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, 276 | 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, 277 | 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, 278 | 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, 279 | 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, 280 | 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, 281 | 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, 282 | 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, 283 | 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, 284 | 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, 285 | 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, 286 | 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, 287 | 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, 288 | 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, 289 | 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, 290 | 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, 291 | 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, 292 | 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, 293 | 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, 294 | 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, 295 | 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, 296 | 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, 297 | 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U 298 | }; 299 | 300 | static const u64 Td[256] = { 301 | U64(0x50a7f45150a7f451), U64(0x5365417e5365417e), 302 | U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a), 303 | U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f), 304 | U64(0xab58faacab58faac), U64(0x9303e34b9303e34b), 305 | U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad), 306 | U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5), 307 | U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5), 308 | U64(0x8044352680443526), U64(0x8fa362b58fa362b5), 309 | U64(0x495ab1de495ab1de), U64(0x671bba25671bba25), 310 | U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d), 311 | U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81), 312 | U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b), 313 | U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215), 314 | U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295), 315 | U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458), 316 | U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e), 317 | U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4), 318 | U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927), 319 | U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0), 320 | U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d), 321 | U64(0x184adf63184adf63), U64(0x82311ae582311ae5), 322 | U64(0x6033519760335197), U64(0x457f5362457f5362), 323 | U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb), 324 | U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9), 325 | U64(0x5868487058684870), U64(0x19fd458f19fd458f), 326 | U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52), 327 | U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72), 328 | U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566), 329 | U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f), 330 | U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3), 331 | U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23), 332 | U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed), 333 | U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7), 334 | U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e), 335 | U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506), 336 | U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4), 337 | U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2), 338 | U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4), 339 | U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040), 340 | U64(0x069f715e069f715e), U64(0x51106ebd51106ebd), 341 | U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96), 342 | U64(0xae053eddae053edd), U64(0x46bde64d46bde64d), 343 | U64(0xb58d5491b58d5491), U64(0x055dc471055dc471), 344 | U64(0x6fd406046fd40604), U64(0xff155060ff155060), 345 | U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6), 346 | U64(0xcc434089cc434089), U64(0x779ed967779ed967), 347 | U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907), 348 | U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879), 349 | U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c), 350 | U64(0xc91e84f8c91e84f8), U64(0x0000000000000000), 351 | U64(0x8386800983868009), U64(0x48ed2b3248ed2b32), 352 | U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c), 353 | U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f), 354 | U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36), 355 | U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68), 356 | U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624), 357 | U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793), 358 | U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b), 359 | U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61), 360 | U64(0x694b775a694b775a), U64(0x161a121c161a121c), 361 | U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0), 362 | U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12), 363 | U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2), 364 | U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14), 365 | U64(0x8519f1578519f157), U64(0x4c0775af4c0775af), 366 | U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3), 367 | U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c), 368 | U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b), 369 | U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb), 370 | U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8), 371 | U64(0xcadc31d7cadc31d7), U64(0x1085634210856342), 372 | U64(0x4022971340229713), U64(0x2011c6842011c684), 373 | U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2), 374 | U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7), 375 | U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc), 376 | U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177), 377 | U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9), 378 | U64(0xfa489411fa489411), U64(0x2264e9472264e947), 379 | U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0), 380 | U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322), 381 | U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9), 382 | U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498), 383 | U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5), 384 | U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f), 385 | U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850), 386 | U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54), 387 | U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890), 388 | U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382), 389 | U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069), 390 | U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf), 391 | U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810), 392 | U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb), 393 | U64(0x097826cd097826cd), U64(0xf418596ef418596e), 394 | U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83), 395 | U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa), 396 | U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef), 397 | U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a), 398 | U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029), 399 | U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a), 400 | U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235), 401 | U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc), 402 | U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733), 403 | U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41), 404 | U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117), 405 | U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43), 406 | U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4), 407 | U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c), 408 | U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546), 409 | U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01), 410 | U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb), 411 | U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92), 412 | U64(0x335610e9335610e9), U64(0x1347d66d1347d66d), 413 | U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137), 414 | U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb), 415 | U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7), 416 | U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a), 417 | U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255), 418 | U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773), 419 | U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f), 420 | U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478), 421 | U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9), 422 | U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2), 423 | U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc), 424 | U64(0x8b493c288b493c28), U64(0x41950dff41950dff), 425 | U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08), 426 | U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664), 427 | U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5), 428 | U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0) 429 | }; 430 | static const u8 Td4[256] = { 431 | 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 432 | 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, 433 | 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 434 | 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, 435 | 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 436 | 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, 437 | 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 438 | 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, 439 | 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 440 | 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, 441 | 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 442 | 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, 443 | 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 444 | 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, 445 | 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 446 | 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, 447 | 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 448 | 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, 449 | 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 450 | 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, 451 | 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 452 | 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, 453 | 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 454 | 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, 455 | 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 456 | 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, 457 | 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 458 | 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, 459 | 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 460 | 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, 461 | 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 462 | 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU 463 | }; 464 | 465 | static const u32 rcon[] = { 466 | 0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U, 467 | 0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U, 468 | 0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ 469 | }; 470 | 471 | /** 472 | * Expand the cipher key into the encryption key schedule. 473 | */ 474 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits, 475 | AES_KEY *key) 476 | { 477 | 478 | u32 *rk; 479 | int i = 0; 480 | u32 temp; 481 | 482 | if (!userKey || !key) 483 | return -1; 484 | if (bits != 128 && bits != 192 && bits != 256) 485 | return -2; 486 | 487 | rk = key->rd_key; 488 | 489 | if (bits==128) 490 | key->rounds = 10; 491 | else if (bits==192) 492 | key->rounds = 12; 493 | else 494 | key->rounds = 14; 495 | 496 | rk[0] = GETU32(userKey ); 497 | rk[1] = GETU32(userKey + 4); 498 | rk[2] = GETU32(userKey + 8); 499 | rk[3] = GETU32(userKey + 12); 500 | if (bits == 128) { 501 | while (1) { 502 | temp = rk[3]; 503 | rk[4] = rk[0] ^ 504 | ((u32)Te4[(temp >> 8) & 0xff] ) ^ 505 | ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ 506 | ((u32)Te4[(temp >> 24) ] << 16) ^ 507 | ((u32)Te4[(temp ) & 0xff] << 24) ^ 508 | rcon[i]; 509 | rk[5] = rk[1] ^ rk[4]; 510 | rk[6] = rk[2] ^ rk[5]; 511 | rk[7] = rk[3] ^ rk[6]; 512 | if (++i == 10) { 513 | return 0; 514 | } 515 | rk += 4; 516 | } 517 | } 518 | rk[4] = GETU32(userKey + 16); 519 | rk[5] = GETU32(userKey + 20); 520 | if (bits == 192) { 521 | while (1) { 522 | temp = rk[ 5]; 523 | rk[ 6] = rk[ 0] ^ 524 | ((u32)Te4[(temp >> 8) & 0xff] ) ^ 525 | ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ 526 | ((u32)Te4[(temp >> 24) ] << 16) ^ 527 | ((u32)Te4[(temp ) & 0xff] << 24) ^ 528 | rcon[i]; 529 | rk[ 7] = rk[ 1] ^ rk[ 6]; 530 | rk[ 8] = rk[ 2] ^ rk[ 7]; 531 | rk[ 9] = rk[ 3] ^ rk[ 8]; 532 | if (++i == 8) { 533 | return 0; 534 | } 535 | rk[10] = rk[ 4] ^ rk[ 9]; 536 | rk[11] = rk[ 5] ^ rk[10]; 537 | rk += 6; 538 | } 539 | } 540 | rk[6] = GETU32(userKey + 24); 541 | rk[7] = GETU32(userKey + 28); 542 | if (bits == 256) { 543 | while (1) { 544 | temp = rk[ 7]; 545 | rk[ 8] = rk[ 0] ^ 546 | ((u32)Te4[(temp >> 8) & 0xff] ) ^ 547 | ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ 548 | ((u32)Te4[(temp >> 24) ] << 16) ^ 549 | ((u32)Te4[(temp ) & 0xff] << 24) ^ 550 | rcon[i]; 551 | rk[ 9] = rk[ 1] ^ rk[ 8]; 552 | rk[10] = rk[ 2] ^ rk[ 9]; 553 | rk[11] = rk[ 3] ^ rk[10]; 554 | if (++i == 7) { 555 | return 0; 556 | } 557 | temp = rk[11]; 558 | rk[12] = rk[ 4] ^ 559 | ((u32)Te4[(temp ) & 0xff] ) ^ 560 | ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ 561 | ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ 562 | ((u32)Te4[(temp >> 24) ] << 24); 563 | rk[13] = rk[ 5] ^ rk[12]; 564 | rk[14] = rk[ 6] ^ rk[13]; 565 | rk[15] = rk[ 7] ^ rk[14]; 566 | 567 | rk += 8; 568 | } 569 | } 570 | return 0; 571 | } 572 | 573 | /** 574 | * Expand the cipher key into the decryption key schedule. 575 | */ 576 | int AES_set_decrypt_key(const unsigned char *userKey, const int bits, 577 | AES_KEY *key) 578 | { 579 | 580 | u32 *rk; 581 | int i, j, status; 582 | u32 temp; 583 | 584 | /* first, start with an encryption schedule */ 585 | status = AES_set_encrypt_key(userKey, bits, key); 586 | if (status < 0) 587 | return status; 588 | 589 | rk = key->rd_key; 590 | 591 | /* invert the order of the round keys: */ 592 | for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { 593 | temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; 594 | temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; 595 | temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; 596 | temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; 597 | } 598 | /* apply the inverse MixColumn transform to all round keys but the first and the last: */ 599 | for (i = 1; i < (key->rounds); i++) { 600 | rk += 4; 601 | #if 1 602 | for (j = 0; j < 4; j++) { 603 | u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; 604 | 605 | tp1 = rk[j]; 606 | m = tp1 & 0x80808080; 607 | tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ 608 | ((m - (m >> 7)) & 0x1b1b1b1b); 609 | m = tp2 & 0x80808080; 610 | tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ 611 | ((m - (m >> 7)) & 0x1b1b1b1b); 612 | m = tp4 & 0x80808080; 613 | tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ 614 | ((m - (m >> 7)) & 0x1b1b1b1b); 615 | tp9 = tp8 ^ tp1; 616 | tpb = tp9 ^ tp2; 617 | tpd = tp9 ^ tp4; 618 | tpe = tp8 ^ tp4 ^ tp2; 619 | #if defined(ROTATE) 620 | rk[j] = tpe ^ ROTATE(tpd,16) ^ 621 | ROTATE(tp9,8) ^ ROTATE(tpb,24); 622 | #else 623 | rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 624 | (tp9 >> 24) ^ (tp9 << 8) ^ 625 | (tpb >> 8) ^ (tpb << 24); 626 | #endif 627 | } 628 | #else 629 | rk[0] = 630 | Td0[Te2[(rk[0] ) & 0xff] & 0xff] ^ 631 | Td1[Te2[(rk[0] >> 8) & 0xff] & 0xff] ^ 632 | Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^ 633 | Td3[Te2[(rk[0] >> 24) ] & 0xff]; 634 | rk[1] = 635 | Td0[Te2[(rk[1] ) & 0xff] & 0xff] ^ 636 | Td1[Te2[(rk[1] >> 8) & 0xff] & 0xff] ^ 637 | Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^ 638 | Td3[Te2[(rk[1] >> 24) ] & 0xff]; 639 | rk[2] = 640 | Td0[Te2[(rk[2] ) & 0xff] & 0xff] ^ 641 | Td1[Te2[(rk[2] >> 8) & 0xff] & 0xff] ^ 642 | Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^ 643 | Td3[Te2[(rk[2] >> 24) ] & 0xff]; 644 | rk[3] = 645 | Td0[Te2[(rk[3] ) & 0xff] & 0xff] ^ 646 | Td1[Te2[(rk[3] >> 8) & 0xff] & 0xff] ^ 647 | Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^ 648 | Td3[Te2[(rk[3] >> 24) ] & 0xff]; 649 | #endif 650 | } 651 | return 0; 652 | } 653 | 654 | /* 655 | * Encrypt a single block 656 | * in and out can overlap 657 | */ 658 | void AES_encrypt(const unsigned char *in, unsigned char *out, 659 | const AES_KEY *key) 660 | { 661 | 662 | const u32 *rk; 663 | u32 s0, s1, s2, s3, t[4]; 664 | int r; 665 | 666 | assert(in && out && key); 667 | rk = key->rd_key; 668 | 669 | /* 670 | * map byte array block to cipher state 671 | * and add initial round key: 672 | */ 673 | s0 = GETU32(in ) ^ rk[0]; 674 | s1 = GETU32(in + 4) ^ rk[1]; 675 | s2 = GETU32(in + 8) ^ rk[2]; 676 | s3 = GETU32(in + 12) ^ rk[3]; 677 | 678 | #if defined(AES_COMPACT_IN_OUTER_ROUNDS) 679 | prefetch256(Te4); 680 | 681 | t[0] = (u32)Te4[(s0 ) & 0xff] ^ 682 | (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ 683 | (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ 684 | (u32)Te4[(s3 >> 24) ] << 24; 685 | t[1] = (u32)Te4[(s1 ) & 0xff] ^ 686 | (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ 687 | (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ 688 | (u32)Te4[(s0 >> 24) ] << 24; 689 | t[2] = (u32)Te4[(s2 ) & 0xff] ^ 690 | (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ 691 | (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ 692 | (u32)Te4[(s1 >> 24) ] << 24; 693 | t[3] = (u32)Te4[(s3 ) & 0xff] ^ 694 | (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ 695 | (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ 696 | (u32)Te4[(s2 >> 24) ] << 24; 697 | 698 | /* now do the linear transform using words */ 699 | { int i; 700 | u32 r0, r1, r2; 701 | 702 | for (i = 0; i < 4; i++) { 703 | r0 = t[i]; 704 | r1 = r0 & 0x80808080; 705 | r2 = ((r0 & 0x7f7f7f7f) << 1) ^ 706 | ((r1 - (r1 >> 7)) & 0x1b1b1b1b); 707 | #if defined(ROTATE) 708 | t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^ 709 | ROTATE(r0,16) ^ ROTATE(r0,8); 710 | #else 711 | t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ 712 | (r0 << 16) ^ (r0 >> 16) ^ 713 | (r0 << 8) ^ (r0 >> 24); 714 | #endif 715 | t[i] ^= rk[4+i]; 716 | } 717 | } 718 | #else 719 | t[0] = Te0[(s0 ) & 0xff] ^ 720 | Te1[(s1 >> 8) & 0xff] ^ 721 | Te2[(s2 >> 16) & 0xff] ^ 722 | Te3[(s3 >> 24) ] ^ 723 | rk[4]; 724 | t[1] = Te0[(s1 ) & 0xff] ^ 725 | Te1[(s2 >> 8) & 0xff] ^ 726 | Te2[(s3 >> 16) & 0xff] ^ 727 | Te3[(s0 >> 24) ] ^ 728 | rk[5]; 729 | t[2] = Te0[(s2 ) & 0xff] ^ 730 | Te1[(s3 >> 8) & 0xff] ^ 731 | Te2[(s0 >> 16) & 0xff] ^ 732 | Te3[(s1 >> 24) ] ^ 733 | rk[6]; 734 | t[3] = Te0[(s3 ) & 0xff] ^ 735 | Te1[(s0 >> 8) & 0xff] ^ 736 | Te2[(s1 >> 16) & 0xff] ^ 737 | Te3[(s2 >> 24) ] ^ 738 | rk[7]; 739 | #endif 740 | s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; 741 | 742 | /* 743 | * Nr - 2 full rounds: 744 | */ 745 | for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) { 746 | #if defined(AES_COMPACT_IN_INNER_ROUNDS) 747 | t[0] = (u32)Te4[(s0 ) & 0xff] ^ 748 | (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ 749 | (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ 750 | (u32)Te4[(s3 >> 24) ] << 24; 751 | t[1] = (u32)Te4[(s1 ) & 0xff] ^ 752 | (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ 753 | (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ 754 | (u32)Te4[(s0 >> 24) ] << 24; 755 | t[2] = (u32)Te4[(s2 ) & 0xff] ^ 756 | (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ 757 | (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ 758 | (u32)Te4[(s1 >> 24) ] << 24; 759 | t[3] = (u32)Te4[(s3 ) & 0xff] ^ 760 | (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ 761 | (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ 762 | (u32)Te4[(s2 >> 24) ] << 24; 763 | 764 | /* now do the linear transform using words */ 765 | { 766 | int i; 767 | u32 r0, r1, r2; 768 | 769 | for (i = 0; i < 4; i++) { 770 | r0 = t[i]; 771 | r1 = r0 & 0x80808080; 772 | r2 = ((r0 & 0x7f7f7f7f) << 1) ^ 773 | ((r1 - (r1 >> 7)) & 0x1b1b1b1b); 774 | #if defined(ROTATE) 775 | t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^ 776 | ROTATE(r0,16) ^ ROTATE(r0,8); 777 | #else 778 | t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ 779 | (r0 << 16) ^ (r0 >> 16) ^ 780 | (r0 << 8) ^ (r0 >> 24); 781 | #endif 782 | t[i] ^= rk[i]; 783 | } 784 | } 785 | #else 786 | t[0] = Te0[(s0 ) & 0xff] ^ 787 | Te1[(s1 >> 8) & 0xff] ^ 788 | Te2[(s2 >> 16) & 0xff] ^ 789 | Te3[(s3 >> 24) ] ^ 790 | rk[0]; 791 | t[1] = Te0[(s1 ) & 0xff] ^ 792 | Te1[(s2 >> 8) & 0xff] ^ 793 | Te2[(s3 >> 16) & 0xff] ^ 794 | Te3[(s0 >> 24) ] ^ 795 | rk[1]; 796 | t[2] = Te0[(s2 ) & 0xff] ^ 797 | Te1[(s3 >> 8) & 0xff] ^ 798 | Te2[(s0 >> 16) & 0xff] ^ 799 | Te3[(s1 >> 24) ] ^ 800 | rk[2]; 801 | t[3] = Te0[(s3 ) & 0xff] ^ 802 | Te1[(s0 >> 8) & 0xff] ^ 803 | Te2[(s1 >> 16) & 0xff] ^ 804 | Te3[(s2 >> 24) ] ^ 805 | rk[3]; 806 | #endif 807 | s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; 808 | } 809 | /* 810 | * apply last round and 811 | * map cipher state to byte array block: 812 | */ 813 | #if defined(AES_COMPACT_IN_OUTER_ROUNDS) 814 | prefetch256(Te4); 815 | 816 | *(u32*)(out+0) = 817 | (u32)Te4[(s0 ) & 0xff] ^ 818 | (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ 819 | (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ 820 | (u32)Te4[(s3 >> 24) ] << 24 ^ 821 | rk[0]; 822 | *(u32*)(out+4) = 823 | (u32)Te4[(s1 ) & 0xff] ^ 824 | (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ 825 | (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ 826 | (u32)Te4[(s0 >> 24) ] << 24 ^ 827 | rk[1]; 828 | *(u32*)(out+8) = 829 | (u32)Te4[(s2 ) & 0xff] ^ 830 | (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ 831 | (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ 832 | (u32)Te4[(s1 >> 24) ] << 24 ^ 833 | rk[2]; 834 | *(u32*)(out+12) = 835 | (u32)Te4[(s3 ) & 0xff] ^ 836 | (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ 837 | (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ 838 | (u32)Te4[(s2 >> 24) ] << 24 ^ 839 | rk[3]; 840 | #else 841 | *(u32*)(out+0) = 842 | (Te2[(s0 ) & 0xff] & 0x000000ffU) ^ 843 | (Te3[(s1 >> 8) & 0xff] & 0x0000ff00U) ^ 844 | (Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^ 845 | (Te1[(s3 >> 24) ] & 0xff000000U) ^ 846 | rk[0]; 847 | *(u32*)(out+4) = 848 | (Te2[(s1 ) & 0xff] & 0x000000ffU) ^ 849 | (Te3[(s2 >> 8) & 0xff] & 0x0000ff00U) ^ 850 | (Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^ 851 | (Te1[(s0 >> 24) ] & 0xff000000U) ^ 852 | rk[1]; 853 | *(u32*)(out+8) = 854 | (Te2[(s2 ) & 0xff] & 0x000000ffU) ^ 855 | (Te3[(s3 >> 8) & 0xff] & 0x0000ff00U) ^ 856 | (Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^ 857 | (Te1[(s1 >> 24) ] & 0xff000000U) ^ 858 | rk[2]; 859 | *(u32*)(out+12) = 860 | (Te2[(s3 ) & 0xff] & 0x000000ffU) ^ 861 | (Te3[(s0 >> 8) & 0xff] & 0x0000ff00U) ^ 862 | (Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^ 863 | (Te1[(s2 >> 24) ] & 0xff000000U) ^ 864 | rk[3]; 865 | #endif 866 | } 867 | 868 | /* 869 | * Decrypt a single block 870 | * in and out can overlap 871 | */ 872 | void AES_decrypt(const unsigned char *in, unsigned char *out, 873 | const AES_KEY *key) 874 | { 875 | 876 | const u32 *rk; 877 | u32 s0, s1, s2, s3, t[4]; 878 | int r; 879 | 880 | assert(in && out && key); 881 | rk = key->rd_key; 882 | 883 | /* 884 | * map byte array block to cipher state 885 | * and add initial round key: 886 | */ 887 | s0 = GETU32(in ) ^ rk[0]; 888 | s1 = GETU32(in + 4) ^ rk[1]; 889 | s2 = GETU32(in + 8) ^ rk[2]; 890 | s3 = GETU32(in + 12) ^ rk[3]; 891 | 892 | #if defined(AES_COMPACT_IN_OUTER_ROUNDS) 893 | prefetch256(Td4); 894 | 895 | t[0] = (u32)Td4[(s0 ) & 0xff] ^ 896 | (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ 897 | (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ 898 | (u32)Td4[(s1 >> 24) ] << 24; 899 | t[1] = (u32)Td4[(s1 ) & 0xff] ^ 900 | (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ 901 | (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ 902 | (u32)Td4[(s2 >> 24) ] << 24; 903 | t[2] = (u32)Td4[(s2 ) & 0xff] ^ 904 | (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ 905 | (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ 906 | (u32)Td4[(s3 >> 24) ] << 24; 907 | t[3] = (u32)Td4[(s3 ) & 0xff] ^ 908 | (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ 909 | (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ 910 | (u32)Td4[(s0 >> 24) ] << 24; 911 | 912 | /* now do the linear transform using words */ 913 | { 914 | int i; 915 | u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; 916 | 917 | for (i = 0; i < 4; i++) { 918 | tp1 = t[i]; 919 | m = tp1 & 0x80808080; 920 | tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ 921 | ((m - (m >> 7)) & 0x1b1b1b1b); 922 | m = tp2 & 0x80808080; 923 | tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ 924 | ((m - (m >> 7)) & 0x1b1b1b1b); 925 | m = tp4 & 0x80808080; 926 | tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ 927 | ((m - (m >> 7)) & 0x1b1b1b1b); 928 | tp9 = tp8 ^ tp1; 929 | tpb = tp9 ^ tp2; 930 | tpd = tp9 ^ tp4; 931 | tpe = tp8 ^ tp4 ^ tp2; 932 | #if defined(ROTATE) 933 | t[i] = tpe ^ ROTATE(tpd,16) ^ 934 | ROTATE(tp9,8) ^ ROTATE(tpb,24); 935 | #else 936 | t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 937 | (tp9 >> 24) ^ (tp9 << 8) ^ 938 | (tpb >> 8) ^ (tpb << 24); 939 | #endif 940 | t[i] ^= rk[4+i]; 941 | } 942 | } 943 | #else 944 | t[0] = Td0[(s0 ) & 0xff] ^ 945 | Td1[(s3 >> 8) & 0xff] ^ 946 | Td2[(s2 >> 16) & 0xff] ^ 947 | Td3[(s1 >> 24) ] ^ 948 | rk[4]; 949 | t[1] = Td0[(s1 ) & 0xff] ^ 950 | Td1[(s0 >> 8) & 0xff] ^ 951 | Td2[(s3 >> 16) & 0xff] ^ 952 | Td3[(s2 >> 24) ] ^ 953 | rk[5]; 954 | t[2] = Td0[(s2 ) & 0xff] ^ 955 | Td1[(s1 >> 8) & 0xff] ^ 956 | Td2[(s0 >> 16) & 0xff] ^ 957 | Td3[(s3 >> 24) ] ^ 958 | rk[6]; 959 | t[3] = Td0[(s3 ) & 0xff] ^ 960 | Td1[(s2 >> 8) & 0xff] ^ 961 | Td2[(s1 >> 16) & 0xff] ^ 962 | Td3[(s0 >> 24) ] ^ 963 | rk[7]; 964 | #endif 965 | s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; 966 | 967 | /* 968 | * Nr - 2 full rounds: 969 | */ 970 | for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) { 971 | #if defined(AES_COMPACT_IN_INNER_ROUNDS) 972 | t[0] = (u32)Td4[(s0 ) & 0xff] ^ 973 | (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ 974 | (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ 975 | (u32)Td4[(s1 >> 24) ] << 24; 976 | t[1] = (u32)Td4[(s1 ) & 0xff] ^ 977 | (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ 978 | (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ 979 | (u32)Td4[(s2 >> 24) ] << 24; 980 | t[2] = (u32)Td4[(s2 ) & 0xff] ^ 981 | (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ 982 | (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ 983 | (u32)Td4[(s3 >> 24) ] << 24; 984 | t[3] = (u32)Td4[(s3 ) & 0xff] ^ 985 | (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ 986 | (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ 987 | (u32)Td4[(s0 >> 24) ] << 24; 988 | 989 | /* now do the linear transform using words */ 990 | { 991 | int i; 992 | u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; 993 | 994 | for (i = 0; i < 4; i++) { 995 | tp1 = t[i]; 996 | m = tp1 & 0x80808080; 997 | tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ 998 | ((m - (m >> 7)) & 0x1b1b1b1b); 999 | m = tp2 & 0x80808080; 1000 | tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ 1001 | ((m - (m >> 7)) & 0x1b1b1b1b); 1002 | m = tp4 & 0x80808080; 1003 | tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ 1004 | ((m - (m >> 7)) & 0x1b1b1b1b); 1005 | tp9 = tp8 ^ tp1; 1006 | tpb = tp9 ^ tp2; 1007 | tpd = tp9 ^ tp4; 1008 | tpe = tp8 ^ tp4 ^ tp2; 1009 | #if defined(ROTATE) 1010 | t[i] = tpe ^ ROTATE(tpd,16) ^ 1011 | ROTATE(tp9,8) ^ ROTATE(tpb,24); 1012 | #else 1013 | t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 1014 | (tp9 >> 24) ^ (tp9 << 8) ^ 1015 | (tpb >> 8) ^ (tpb << 24); 1016 | #endif 1017 | t[i] ^= rk[i]; 1018 | } 1019 | } 1020 | #else 1021 | t[0] = Td0[(s0 ) & 0xff] ^ 1022 | Td1[(s3 >> 8) & 0xff] ^ 1023 | Td2[(s2 >> 16) & 0xff] ^ 1024 | Td3[(s1 >> 24) ] ^ 1025 | rk[0]; 1026 | t[1] = Td0[(s1 ) & 0xff] ^ 1027 | Td1[(s0 >> 8) & 0xff] ^ 1028 | Td2[(s3 >> 16) & 0xff] ^ 1029 | Td3[(s2 >> 24) ] ^ 1030 | rk[1]; 1031 | t[2] = Td0[(s2 ) & 0xff] ^ 1032 | Td1[(s1 >> 8) & 0xff] ^ 1033 | Td2[(s0 >> 16) & 0xff] ^ 1034 | Td3[(s3 >> 24) ] ^ 1035 | rk[2]; 1036 | t[3] = Td0[(s3 ) & 0xff] ^ 1037 | Td1[(s2 >> 8) & 0xff] ^ 1038 | Td2[(s1 >> 16) & 0xff] ^ 1039 | Td3[(s0 >> 24) ] ^ 1040 | rk[3]; 1041 | #endif 1042 | s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; 1043 | } 1044 | /* 1045 | * apply last round and 1046 | * map cipher state to byte array block: 1047 | */ 1048 | prefetch256(Td4); 1049 | 1050 | *(u32*)(out+0) = 1051 | ((u32)Td4[(s0 ) & 0xff]) ^ 1052 | ((u32)Td4[(s3 >> 8) & 0xff] << 8) ^ 1053 | ((u32)Td4[(s2 >> 16) & 0xff] << 16) ^ 1054 | ((u32)Td4[(s1 >> 24) ] << 24) ^ 1055 | rk[0]; 1056 | *(u32*)(out+4) = 1057 | ((u32)Td4[(s1 ) & 0xff]) ^ 1058 | ((u32)Td4[(s0 >> 8) & 0xff] << 8) ^ 1059 | ((u32)Td4[(s3 >> 16) & 0xff] << 16) ^ 1060 | ((u32)Td4[(s2 >> 24) ] << 24) ^ 1061 | rk[1]; 1062 | *(u32*)(out+8) = 1063 | ((u32)Td4[(s2 ) & 0xff]) ^ 1064 | ((u32)Td4[(s1 >> 8) & 0xff] << 8) ^ 1065 | ((u32)Td4[(s0 >> 16) & 0xff] << 16) ^ 1066 | ((u32)Td4[(s3 >> 24) ] << 24) ^ 1067 | rk[2]; 1068 | *(u32*)(out+12) = 1069 | ((u32)Td4[(s3 ) & 0xff]) ^ 1070 | ((u32)Td4[(s2 >> 8) & 0xff] << 8) ^ 1071 | ((u32)Td4[(s1 >> 16) & 0xff] << 16) ^ 1072 | ((u32)Td4[(s0 >> 24) ] << 24) ^ 1073 | rk[3]; 1074 | } 1075 | --------------------------------------------------------------------------------