diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..eca4d23 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,48 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.example.test6' + compileSdk 33 + + defaultConfig { + applicationId "com.example.test6" + minSdk 30 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.22.1' + } + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'com.google.android.material:material:1.5.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.3' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java new file mode 100644 index 0000000..f2304b9 --- /dev/null +++ b/app/src/androidTest/java/com/example/test6/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.test6; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.test6", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e2a9db8 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..2c898fe --- /dev/null +++ b/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,53 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.22.1) + +# Declares and names the project. + +project("chip") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +add_library( # Sets the name of the library. + chip + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + chip.cpp + GPIOControl.cpp + NrsecPort.cpp + SpiPort.cpp + native-lib.cpp + ) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + chip + + # Links the target library to the log library + # included in the NDK. + ${log-lib}) \ No newline at end of file diff --git a/app/src/main/cpp/GPIOControl.cpp b/app/src/main/cpp/GPIOControl.cpp new file mode 100644 index 0000000..187f7e3 --- /dev/null +++ b/app/src/main/cpp/GPIOControl.cpp @@ -0,0 +1,134 @@ +// +// Created by Matthew on 2023/12/27. +// + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "GPIOControl.h" + +#ifdef _DEBUG +#include +#endif + +#define IOT_PARAM_WRITE 0xAE +#define IOT_PARAM_READ 0xAF +#define MAX_STRING_LEN 32 + +typedef struct +{ + int cmd; + int value; + int result; + long value2; + char str[MAX_STRING_LEN]; +}IOT_PARAM; + +void GpioControl::setInt(int cmd, int value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value = value; + // LOGE("set_int fd=%d,cmd=%d,value=%d\r\n",fd, cmd, value); + if( fd > 0 ) + { + int res = ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_int22 cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); + close(fd); + } + return; +} + +int GpioControl::getInt(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_int fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); +#ifdef _DEBUG + ALOGI("getInt cmd=%d,value=%d,result=%d\r\n",param.cmd, param.value, param.result); +#endif + close(fd); + return param.value; + } + return -1; +} + +void GpioControl::setLong(int cmd, long value) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + IOT_PARAM param; + param.cmd = cmd; + param.value2 = value; + // LOGE("set_long fd=%d,cmd=%d,value2=%ld\r\n",fd, param.cmd, param.value2); + + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + } +} + +long GpioControl::getLong(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_long fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_long22 cmd=%d,value2=%ld,result=%d\r\n",param.cmd, param.value2, param.result); + close(fd); + return param.value2; + } + return -1; +} + +void GpioControl::setString(int cmd, const std::string& value) +{ + IOT_PARAM param; + // char *pval = jstringToChars(env, value); + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + int len = MAX_STRING_LEN < value.size() ? MAX_STRING_LEN : value.size(); + + param.cmd = cmd; + memset(param.str, 0, MAX_STRING_LEN); + memcpy(param.str, value.c_str(), len); + // LOGE("set_string fd=%d,cmd=%d,str=%s\r\n",fd, param.cmd, param.str); + if( fd > 0 ) + { + ioctl(fd, IOT_PARAM_WRITE, ¶m); + // LOGE("set_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + } + return; +} + +std::string GpioControl::getString(int cmd) +{ + int fd = open("/dev/mtkgpioctrl", O_RDONLY); + // LOGE("get_string fd=%d,cmd=%d\r\n",fd, cmd); + if( fd > 0 ) + { + IOT_PARAM param; + param.cmd = cmd; + ioctl(fd, IOT_PARAM_READ, ¶m); + // LOGE("get_string22 cmd=%d,str=%s,result=%d\r\n",param.cmd, param.str, param.result); + close(fd); + return std::string(param.str); + } + return ""; +} diff --git a/app/src/main/cpp/GPIOControl.h b/app/src/main/cpp/GPIOControl.h new file mode 100644 index 0000000..83e5a29 --- /dev/null +++ b/app/src/main/cpp/GPIOControl.h @@ -0,0 +1,166 @@ +// +// Created by Matthew on 2023/12/27. +// + +#ifndef MICROPHOTO_GPIOCONTROL_H +#define MICROPHOTO_GPIOCONTROL_H + +#include + +#define CMD_GET_LIGHT_ADC 101 +#define CMD_SET_LIGHT_ADC 102 +#define CMD_GET_KEY_LOCKSTATE 103 +#define CMD_GET_BAT_ADC 104 +#define CMD_SET_FLASH_LED 105 +#define CMD_SET_NETWORK_STATE 106 +#define CMD_SET_OTG_STATE 107 +#define CMD_GET_OTG_STATE 108 +#define CMD_GET_CHARGING_VOL_STATE 110 +#define CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE 111 +#define CMD_GET_CHARGING_BUS_VOLTAGE_STATE 112 +#define CMD_GET_CHARGING_POWER_STATE 113 +#define CMD_GET_CHARGING_CURRENT_STATE 114 +#define CMD_GET_BAT_VOL_STATE 115 +#define CMD_GET_BAT_SHUNT_VOLTAGE_STATE 116 +#define CMD_GET_BAT_BUS_VOLTAGE_STATE 117 +#define CMD_GET_BAT_POWER_STATE 118 +#define CMD_GET_BAT_CURRENT_STATE 119 +#define CMD_SET_485_STATE 121 +#define CMD_SET_SPI_MODE 123 +#define CMD_SET_SPI_BITS_PER_WORD 124 +#define CMD_SET_SPI_MAXSPEEDHZ 125 +#define CMD_SET_PWM_BEE_STATE 126 +#define CMD_SET_ALM_MODE 128 +#define CMD_SET_SPI_POWER 129 +#define CMD_SET_485_EN_STATE 131 +#define CMD_SET_CAM_3V3_EN_STATE 132 +#define CMD_SET_12V_EN_STATE 133 +#define CMD_SET_SYSTEM_RESET 202 + +class GpioControl +{ +public: + + static void setInt(int cmd, int value); + static int getInt(int cmd); + static void setLong(int cmd, long value); + static long getLong(int cmd); + static void setString(int cmd, const std::string& value); + static std::string getString(int cmd); + + static void setOtgState(bool on) + { + setInt(CMD_SET_OTG_STATE, on ? 1 : 0); + } + + static bool getOtgState() + { + return getInt(CMD_SET_OTG_STATE) != 0; + } + + static void setCam3V3Enable(bool enabled) + { + setInt(CMD_SET_CAM_3V3_EN_STATE, enabled ? 1 : 0); + } + + static void reboot() + { + setInt(CMD_SET_SYSTEM_RESET, 1); + } + + static void setLightAdc(int i) + { + setInt(CMD_SET_LIGHT_ADC, i); + } + + static int getLightAdc() + { + return getInt(CMD_GET_LIGHT_ADC); + } + + static int getChargingVoltage() + { + return getInt(CMD_GET_CHARGING_VOL_STATE); + } + + static int getChargingShuntVoltage() + { + return getInt(CMD_GET_CHARGING_SHUNT_VOLTAGE_STATE); + } + + static int getChargingBusVoltage() { + return getInt(CMD_GET_CHARGING_BUS_VOLTAGE_STATE); + } + + static int getChargingPower() { + return getInt(CMD_GET_CHARGING_POWER_STATE); + } + + static int getChargingCurrent() { + return getInt(CMD_GET_CHARGING_CURRENT_STATE); + } + + static int getBatteryVoltage() { + return getInt(CMD_GET_BAT_VOL_STATE); + } + + static int getBatteryShuntVoltage() { + return getInt(CMD_GET_BAT_SHUNT_VOLTAGE_STATE); + } + + static int getBatteryBusVoltage() { + return getInt(CMD_GET_BAT_BUS_VOLTAGE_STATE); + } + + static int getBatteryPower() { + return getInt(CMD_GET_BAT_POWER_STATE); + } + + static int getBatteryCurrent() { + return getInt(CMD_GET_BAT_CURRENT_STATE); + } + + static void set485WriteMode() { + setInt(CMD_SET_485_STATE, 1); + } + + static void set485ReadMode() { + setInt(CMD_SET_485_STATE, 0); + } + + static void setSpiMode(int i) { + setInt(CMD_SET_SPI_MODE, i); + } + + static void setSpiBitsPerWord(int i) { + setInt(CMD_SET_SPI_BITS_PER_WORD, i); + } + + static void setSpiMaxSpeedHz(long j) { + setLong(CMD_SET_SPI_MAXSPEEDHZ, j); + } + + static void setBeeOn(bool z) { + setInt(CMD_SET_PWM_BEE_STATE, z ? 1 : 0); + } + + static void setJidianqiState(bool z) { + setInt(CMD_SET_ALM_MODE, z ? 1 : 0); + } + + static void setSpiPower(bool on) { + setInt(CMD_SET_SPI_POWER, on ? 1 : 0); + } + + static void setRS485Enable(bool z) { + setInt(CMD_SET_485_EN_STATE, z ? 1 : 0); + } + + static void set12VEnable(bool z) { + setInt(CMD_SET_12V_EN_STATE, z ? 1 : 0); + } + +}; + + +#endif //MICROPHOTO_GPIOCONTROL_H diff --git a/app/src/main/cpp/NrsecPort.cpp b/app/src/main/cpp/NrsecPort.cpp new file mode 100644 index 0000000..5f1eb64 --- /dev/null +++ b/app/src/main/cpp/NrsecPort.cpp @@ -0,0 +1,1310 @@ +#include "NrsecPort.h" +#ifdef __ANDROID__ +#include +#endif + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + +#define TAG_SPI "SPI" + +const uint8_t EK_CMD[5] = { 0x80,0xd4,0x01,0x00,0x10 }; +const uint8_t AK_CMD[5] = { 0x80,0xd4,0x02,0x00,0x10 }; +const uint8_t IV_CMD[5] = { 0x80,0xd4,0x04,0x00,0x10 }; +uint8_t SM1Encrypt_CMD[5] = { 0xa0,0xe0,0x80,0xff,0xff }; +uint8_t SM1decoder_CMD[5] = { 0xa0,0xe0,0x81,0xff,0xff }; +uint8_t SM2Keypair_CMD[5] = { 0x80,0xb2,0x00,0xff,0x00 }; +uint8_t SM2OutPub_CMD[5] = { 0x80,0xb8,0x01,0xff,0x40 }; +uint8_t SM2OutPri_CMD[5] = { 0x80,0xb8,0x02,0xff,0x20 }; +uint8_t SM2InPub_CMD[5] = { 0x80,0xba,0x01,0xff,0x40 }; +uint8_t SM2InPri_CMD[5] = { 0x80,0xba,0x02,0xff,0x20 }; +uint8_t SM3Hash_CMD[5] = { 0x80,0xb5,0x00,0xff,0xff }; +uint8_t SM2Sign_CMD[5] = { 0x80,0xb4,0x00,0xff,0x20 }; +uint8_t SM2VerifySign_CMD[5] = { 0x80,0xb6,0x00,0xff,0x60 }; +uint8_t SM2encrypt_CMD[5] = { 0x80,0xb3,0x01,0xff,0x20 }; +uint8_t SM2decoder_CMD[5] = { 0x80,0xb3,0x81,0xff,0x80 }; +uint8_t SM2cert_CMD[5] = { 0x80,0xb7,0xff,0xff,0xff }; +uint8_t Random_CMD[5] = { 0x00,0x84,0x00,0x00,0xff }; +const uint8_t Version_CMD[5] = { 0x00,0x5b,0x00,0x00,0x40 }; +const uint8_t Indentify_CMD[5] = { 0x80,0xb3,0x01,0x04,0x20 }; + +uint8_t NrsecPort::CalcCRC7(const uint8_t *buff, int len) +{ + const static uint8_t crc7_table[256] = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, + 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, + 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e, + 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, + 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45, + 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, + 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c, + 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, + 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13, + 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, + 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a, + 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, + 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21, + 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, + 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38, + 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, + 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36, + 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, + 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f, + 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, + 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, + 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d, + 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, + 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52, + 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, + 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b, + 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, + 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60, + 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, + 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79 + }; + + uint8_t crc7_accum = 0; + int i; + + for (i = 0; i < len; i++) { + crc7_accum = + crc7_table[(crc7_accum << 1) ^ buff[i]]; + } + return crc7_accum; +} + +void NrsecPort::SendCMD(uint8_t* cmd, uint8_t* rxbuf) +{ + int i = 0; + int retval; + +#if defined (CONFIG_ATMEL_SPI_DEBUG) + printf("tx %1d bytes: ", CMD_HEAD_SIZE); + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + printf(" %02x", cmd[i]); + } + printf("\n"); +#endif + + /* send five command header */ + for (i = 0; i < CMD_HEAD_SIZE; i++) + { + retval = spi_transfer(cmd + i, rxbuf + i, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "cmd[%d]=%x,rxbuf[%d]=%x", i, *(cmd + i), i, *(rxbuf + i)); +#endif + delay(20); + } + + cmd[0] = 0xaa; //for response +} + +void NrsecPort::RcvINS(uint8_t* txbuf, uint8_t* buf, uint8_t ins) +{ + int retval; + int cnt = 5000; + /* receive ins */ +INS: + txbuf[0] = 0xaa; + //delay(1000); + while (cnt--) + { + retval = spi_transfer(txbuf, buf, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RcvINS txbuf=%x,buf=%x", *txbuf, *buf); +#endif + if (*buf == ins) + { + return; + break; + } + else + { + delay(1000); + } + } +} + +void NrsecPort::RcvLEN(uint8_t* txbuf, uint8_t* buf, uint8_t len) +{ + int retval; + /* receive length */ +LEN: + for (int i = 0; i < len; i++) { + txbuf[0] = 0xaa; + retval = spi_transfer(txbuf, buf + i, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RecvLEN txbuf=%x,rxbuf=%x", *txbuf, *(buf + i)); +#endif + } +} + +//Rcvdata +void NrsecPort::RcvData(uint8_t*txbuf, uint8_t* buf) +{ + int len = *(buf - 1); + RcvData(txbuf, buf, len); +} + +void NrsecPort::RcvData(uint8_t*txbuf, uint8_t*buf, int len) +{ + int i; + int retval; + + for (i = 0; i < len; i++) + { + *(txbuf + i) = 0xaa; + } + + /* receive data and crc */ + for (i = 0; i < len; i++) + { + retval = spi_transfer(txbuf, buf + i, 1); + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RcvData data[%d]=%x", i, *(buf + i)); + } + +} + +//RcvSW +bool NrsecPort::RcvSW(uint8_t*txbuf, uint8_t*buf, uint8_t sw) +{ + int i; + int retval; + int cnt = 3000; + bool flag =false; + + +SW90: + /* receive state word */ + delay(1000);//20 + while (cnt--) + { + retval = spi_transfer(txbuf, buf, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "RecvSW txbuf=%x,buf=%x", *txbuf, *buf); +#endif + if (*buf != sw) + { + goto SW90; + } + else{ + flag = true; + break; + } + } + retval = spi_transfer(txbuf, buf + 1, 1); + return flag; + +} + +void NrsecPort::SendEnd(uint8_t* txbuf, uint8_t* buf) +{ + int retval; + txbuf[0] = 0xaa; + retval = spi_transfer(txbuf, buf, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendEnd txbuf=%x,rxbuf=%hhu", *txbuf, *buf); +#endif +} + +void NrsecPort::SendId(uint8_t* txbuf, uint8_t* buf, uint8_t id) +{ + int retval; + txbuf[0] = id; + retval = spi_transfer(txbuf, buf, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendID txbuf=%x,rxbuf=%hhu", *txbuf, *buf); +#endif +} + +void NrsecPort::SendData(uint8_t* data, uint8_t* rxbuf, int data_size) +{ + int i = 0; + int retval; + uint8_t crc[1]; + crc[0] = CalcCRC7(data, data_size); + + for (i = 0; i < data_size; i++) + { + retval = spi_transfer(data + i, rxbuf + i, 1); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "SendData i=%d,txbuf=%x,rxbuf=%x", i, *(data + i), *(rxbuf + i)); +#endif + delay(20); + } + retval = spi_transfer(crc, rxbuf, 1); +} + +int NrsecPort::SM1ImportKey(const uint8_t* ek, const uint8_t* ak) +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + int ret=0; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + CMD_RESEND: + + memcpy(txbuf, (const void *)EK_CMD, sizeof(EK_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, ek, 16); +// txbuf[16] = CalcCRC7(ek, 16); + + SendData(txbuf, rxbuf, 16); + + if (!RcvSW(txbuf, rxbuf, 0x90)) + { + return 0; + } + + memcpy(txbuf, (const void *)AK_CMD, sizeof(AK_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, ak, 16); +// txbuf[16] = CalcCRC7(ak, 16); + + SendData(txbuf, rxbuf, 16);//senddata函数中已经包含crc了 + + SendEnd(txbuf, rxbuf); + + ret = RcvSW(txbuf, rxbuf, 0x90); + + return ret; +} + +int NrsecPort::ImportIV(const uint8_t* iv, uint8_t ivLength) +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + int ret=0; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + +CMD_RESEND: + + memcpy(txbuf, (const void *)IV_CMD, sizeof(IV_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, iv, ivLength); +// txbuf[ivLength] = CalcCRC7(iv, ivLength); + + SendData(txbuf, rxbuf, ivLength); + + SendEnd(txbuf, rxbuf); + + ret = RcvSW(txbuf, rxbuf, 0x90); + + return ret; +} + +int NrsecPort::SM1Encrypt(const uint8_t* data, uint16_t dataLen, uint8_t* encryptedData, uint16_t* bufferLen) +{ + int i; + int cnt; + uint8_t txbuf[2048]; + uint8_t rxbuf[2048]; + + int retval; + int msglen; + + int ret=0; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + + CMD_RESEND: + + memcpy(txbuf, (const void *)SM1Encrypt_CMD, sizeof(SM1Encrypt_CMD)); + + txbuf[3] = dataLen >> 8; + txbuf[4] = dataLen & 0xFF; + + SendCMD(txbuf, rxbuf); + + //SendEnd(txbuf,rxbuf);//遇到长度的0xe0数据 + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf,data,dataLen); + + SendData(txbuf,rxbuf,dataLen); + + SendEnd(txbuf,rxbuf); + + RcvINS(txbuf,rxbuf,0xe0); + + RcvLEN(txbuf, rxbuf + 1, 2); //长度 多加一个字节的 CRC + +// uint8_t len = *(rxbuf + 1); + uint16_t len =(*(rxbuf+1)<<8) + (*(rxbuf+2)); + + RcvData(txbuf, rxbuf + 3, len); + + ret = RcvSW(txbuf, rxbuf + 3 + len, 0x90); + + if(ret == 1) + { + //计算接收到数据的CRC + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Calcac = %x", CalcCRC7(rxbuf + 3, len-1)); + if (CalcCRC7(rxbuf + 3, len-1) != rxbuf[len + 2]) + { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + ret =0; + printf("ERROR\n"); + return ret; + } + } + + // printf("rx %1d bytes: ", rxbuf[1] + 4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + + memcpy(encryptedData, rxbuf + 3, len-1); + //memcpy(&bufferLen, &len-1, 1); + * bufferLen = len -1; + } + return ret; +} + +int NrsecPort::SM1Decrypt(const uint8_t* encryptedData, uint16_t encryptedDataLen, uint8_t* data, uint16_t* bufferLen) +{ + int i; + int cnt; + uint8_t txbuf[2048];//256 + uint8_t rxbuf[2048];//256 + + int retval; + int msglen; + + int ret =0; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + + CMD_RESEND: + + memcpy(txbuf, (const void *)SM1decoder_CMD, sizeof(SM1decoder_CMD)); + + txbuf[3] = encryptedDataLen >> 8; + txbuf[4] = encryptedDataLen & 0xFF; + + SendCMD(txbuf, rxbuf); + + //SendEnd(txbuf,rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf,encryptedData,encryptedDataLen); + + SendData(txbuf,rxbuf,encryptedDataLen); + + SendEnd(txbuf,rxbuf); + + RcvINS(txbuf,rxbuf,0xe0); + + RcvLEN(txbuf, rxbuf + 1, 2); //长度 多加一个字节的 CRC + +// uint8_t len = *(rxbuf + 1); + uint16_t len =(*(rxbuf+1)<<8) + (*(rxbuf+2)); + + RcvData(txbuf, rxbuf + 3, len); + + ret = RcvSW(txbuf, rxbuf + 3 + len, 0x90); + + if(ret == 1) + { + //计算接收到数据的CRC + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Calcac = %x", CalcCRC7(rxbuf + 3, len-1)); + if (CalcCRC7(rxbuf + 3, len-1) != rxbuf[len + 2]) + { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + ret = 0; + printf("ERROR\n"); + return ret; + } + } + + // printf("rx %1d bytes: ", rxbuf[1] + 4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + + memcpy(data, rxbuf + 3, len-1); + //memcpy(&bufferLen, &len-1, 1); + * bufferLen = len -1; + } + + return ret; +} + +int NrsecPort::Random(uint8_t* output, uint8_t length) +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + int ret = 0; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)Random_CMD, sizeof(Random_CMD)); + + txbuf[4] = length; + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC + + uint8_t len = *(rxbuf + 1); + + RcvData(txbuf, rxbuf + 2, len); + + ret = RcvSW(txbuf, rxbuf + 2 + len, 0x90); + + if(ret ==1) + { + //计算接收到数据的CRC + if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1]) + { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + ret=0; + return ret; + } + } + + // printf("rx %1d bytes: ", rxbuf[1] + 4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + memcpy(output, rxbuf + 2, len-1); + } + + return ret; +} + +std::string NrsecPort::Version() +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, Version_CMD, sizeof(Version_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + // txbuf[4] = 0xAA; + RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC + + int dataLen = *(rxbuf + 1); + + RcvData(txbuf, rxbuf + 2, dataLen); + + RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //计算接收到数据的CRC + if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1]) + { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + //printf("rx %1d bytes: ", rxbuf[1]+4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + std::string version = ""; + char output[16] = { 0 }; + for (i = 0; i < dataLen-1; i++) { + if (*(rxbuf + 2 + i) == 0) { + break; + } + snprintf(output, sizeof(output), "%c", *(rxbuf + 2 + i)); + version += output; + } +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "Version: %s", version.c_str()); +#endif + //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf); + // printf("\n"); + + + return version; +} + +int NrsecPort::SM2keypair(int index)//产生密钥 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + SM2Keypair_CMD[3] = index; + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2Keypair_CMD, sizeof(SM2Keypair_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvSW(txbuf, rxbuf, 0x90); + + + + return 0; +} + +int NrsecPort::SM2ExportPublicKey(int index, uint8_t result[], uint8_t * len)//导出公钥 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int ret=0; + + int retval; + int msglen; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + SM2OutPub_CMD[3] = index; + + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2OutPub_CMD, sizeof(SM2OutPub_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC + + RcvData(txbuf, rxbuf + 2); + + ret = RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + if(ret == 1) { + //计算接收到数据的CRC + if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1]) { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } else { + ret = 0; + printf("ERROR\n"); + return ret; + } + } + + + //printf("rx %1d bytes: ", rxbuf[1]+4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + memcpy(result, rxbuf + 2, rxbuf[1] - 1); + *len = rxbuf[1] - 1; + } + return ret; +} + +int NrsecPort::SM2ExportPrivateKey(int index, uint8_t result[],uint8_t * len)//导出私钥 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + cnt = 0; + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + SM2OutPri_CMD[3] = index; + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, TAG_SPI, "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2OutPri_CMD, sizeof(SM2OutPri_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + RcvLEN(txbuf, rxbuf + 1, 1); //长度 多加一个字节的 CRC + + RcvData(txbuf, rxbuf + 2); + + RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //计算接收到数据的CRC + if (CalcCRC7(rxbuf + 2, rxbuf[1] - 1) != rxbuf[rxbuf[1] + 1]) + { + //CRC Error 命令重发,超过3次,结束 + if (cnt < 3) + { + cnt++; + goto CMD_RESEND; + printf("cnt over\n"); + } + else + { + printf("ERROR\n"); + } + } + + //printf("rx %1d bytes: ", rxbuf[1]+4); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + + memcpy(result, rxbuf + 2, rxbuf[1]-1); + * len = rxbuf[1]-1; + return 0; +} + +int NrsecPort::SM2ImportPublicKey(int index, const uint8_t new_key[])//外部公钥导入存放在01 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + SM2InPub_CMD[3] = index; + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2InPub_CMD, sizeof(SM2InPub_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, new_key, 64); + + SendData(txbuf, rxbuf, 64); + + SendEnd(txbuf, rxbuf); + + RcvSW(txbuf, rxbuf + 1, 0x90); + + std::string result = "InPub: success"; +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s", result.c_str()); +#endif + //__android_log_print(ANDROID_LOG_INFO, "SPi", "%s", rxbuf); + // printf("\n"); + + + return 0; +} + +int NrsecPort::SM2ImportPrivateKey(int index, const uint8_t new_key[])//导入私钥 没测试 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + SM2InPri_CMD[3] = index; + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2InPri_CMD, sizeof(SM2InPri_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); // 指令 + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, new_key, 32); + + SendData(txbuf, rxbuf, 32); + + SendEnd(txbuf, rxbuf); + + RcvSW(txbuf, rxbuf + 1, 0x90); + + std::string result = "InPri: success"; +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s", result.c_str()); +#endif + + + return 0; +} + +int NrsecPort::SM3Hash(uint8_t *to_hash, int len, uint8_t *out_hash)//原始哈希 跑通了,没有验证 +{ + int i; + int cnt; + uint8_t txbuf[1536]; + uint8_t rxbuf[1536]; + + int retval; + int msglen; + + int ret=0; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + + SM3Hash_CMD[3] = len >> 8; + SM3Hash_CMD[4] = len & 0xFF; + +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, "len", "len=%x", len); +#endif + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM3Hash_CMD, sizeof(SM3Hash_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, to_hash, len); + + SendData(txbuf, rxbuf, len); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM3Hash_CMD, sizeof(SM3Hash_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 1); + + RcvData(txbuf, rxbuf + 2); + + ret = RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + + if(ret ==1) + { + memcpy(out_hash, rxbuf + 2, rxbuf[1]-1); + } + return ret; +} + +int NrsecPort::SM3Hash(uint8_t *in, int inl, uint8_t *out, uint8_t *pubkey, uint8_t* pucID, int idl) +{ + int nRet, l; + uint8_t *Z = NULL; + int entl = 0; + uint8_t tmpm[32]; + uint8_t abxy[32 * 4] = { + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, /* a */ + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFC, + 0x28,0xE9,0xFA,0x9E,0x9D,0x9F,0x5E,0x34,0x4D,0x5A,/* b */ + 0x9E,0x4B,0xCF,0x65,0x09,0xA7,0xF3,0x97,0x89,0xF5, + 0x15,0xAB,0x8F,0x92,0xDD,0xBC,0xBD,0x41,0x4D,0x94, + 0x0E,0x93, + 0x32,0xC4,0xAE,0x2C,0x1F,0x19,0x81,0x19,0x5F,0x99,/* x */ + 0x04,0x46,0x6A,0x39,0xC9,0x94,0x8F,0xE3,0x0B,0xBF, + 0xF2,0x66,0x0B,0xE1,0x71,0x5A,0x45,0x89,0x33,0x4C, + 0x74,0xC7, + 0xBC,0x37,0x36,0xA2,0xF4,0xF6,0x77,0x9C,0x59,0xBD,/* y */ + 0xCE,0xE3,0x6B,0x69,0x21,0x53,0xD0,0xA9,0x87,0x7C, + 0xC6,0x2A,0x47,0x40,0x02,0xDF,0x32,0xE5,0x21,0x39, + 0xF0,0xA0 + }; + l = 2 + idl + 32 * 6; + Z = (uint8_t *)malloc(l); + if (!Z) + return -1; + entl = idl * 8; + memset(Z + 1, entl & 0xFF, 1); + entl >>= 8; + memset(Z, entl & 0xFF, 1); + memcpy(Z + 2, pucID, idl); + memcpy(Z + 2 + idl, abxy, 32 * 4); + memcpy(Z + 2 + idl + 4 * 32, pubkey, 32); + memcpy(Z + 2 + idl + 5 * 32, pubkey + 32, 32); + nRet = SM3Hash(Z, l, tmpm); + if (nRet == 0) + goto quit; + free(Z); + l = inl + 32; + Z = (uint8_t *)malloc(l); + if (!Z) { + nRet = -1; + goto quit; + } + memcpy(Z, tmpm, 32); + memcpy(Z + 32, in, inl); + nRet = SM3Hash(Z, l, out); +quit: + if (Z) + free(Z); + return nRet; +}//用于签名的处理哈希值,用户标识01*16 + +int NrsecPort::SM2Sign(int index, const uint8_t *to_sign, uint8_t *out_sign)//SM2签名 所使用的哈希值应该来源于sm3hash_tosm2 +{ + int i; + int cnt; + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + + int ret=0; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2Sign_CMD[3] = index; + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, to_sign, 32); + + SendData(txbuf, rxbuf, 32); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM2Sign_CMD, sizeof(SM2Sign_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 1); + + RcvData(txbuf, rxbuf + 2); + + ret=RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "rx %1d bytes:", rxbuf[1] + 4); +#endif + if(ret == 1) + { + memcpy(out_sign, rxbuf + 2, rxbuf[1]-1); + } + return ret; +} + +int NrsecPort::SM2VerifySign(int index, uint8_t *hash, uint8_t *vs)//SM2验签 +{ + uint8_t txbuf[256]; + uint8_t rxbuf[256]; + + int retval; + int msglen; + int ret=0; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2VerifySign_CMD[3] = index; + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2VerifySign_CMD, sizeof(SM2VerifySign_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, hash, 32); + memcpy(txbuf + 32, vs, 64); + + SendData(txbuf, rxbuf, 96); + + SendEnd(txbuf, rxbuf); + + ret=RcvSW(txbuf, rxbuf, 0x90); +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1] + 4); +#endif + + return ret; +} + +int NrsecPort::SM2Encrypt(int index, uint8_t *to_encrypt, uint8_t *out_encrypt)//加密 +{ + int i; + int cnt; + uint8_t txbuf[512]; + uint8_t rxbuf[512]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2encrypt_CMD[3] = index; + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, to_encrypt, 32); + + SendData(txbuf, rxbuf, 32); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM2encrypt_CMD, sizeof(SM2encrypt_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 1); + + RcvData(txbuf, rxbuf + 2); + + RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + memcpy(out_encrypt, rxbuf + 2, rxbuf[1]-1); + + return 0; +} +int NrsecPort::SM2Decrypt(int index, uint8_t *to_decoder, uint8_t *out_decoder)//解密 +{ + int i; + int cnt; + uint8_t txbuf[512]; + uint8_t rxbuf[512]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + SM2decoder_CMD[3] = index; + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, to_decoder, 128); + + SendData(txbuf, rxbuf, 128); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 1); + + RcvData(txbuf, rxbuf + 2); + + RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + memcpy(out_decoder, rxbuf + 2, rxbuf[1]-1); + + return 0; +} + +int NrsecPort::SM2cert(int type, int index, string cert, uint8_t *out_cert, uint16_t *len)//证书 +{ + int i; + int cnt; + uint8_t txbuf[512]; + uint8_t rxbuf[1024]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + + int certlen = cert.length(); + + SM2cert_CMD[2] = type; + SM2cert_CMD[3] = index; + SM2cert_CMD[4] = certlen; + +CMD_RESEND: + + memcpy(txbuf, (const void *)SM2cert_CMD, sizeof(SM2cert_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, cert.c_str(), certlen); + + SendData(txbuf, rxbuf, certlen); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM2cert_CMD, sizeof(SM2cert_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 2); + + uint16_t outlen =(*(rxbuf+1)<<8)+(*(rxbuf+2)); + + RcvData(txbuf, rxbuf + 3, outlen); + + RcvSW(txbuf, rxbuf + 3 + outlen, 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + + memcpy(out_cert, rxbuf + 3, outlen-1); + + *len =outlen -1; + + return 0; +} +int NrsecPort::Indentify(uint8_t *to_idt, uint8_t *out_idt)//安全认证 +{ + int i; + int cnt; + uint8_t txbuf[512]; + uint8_t rxbuf[512]; + + int retval; + int msglen; + + msglen = 5; + memset(rxbuf, 0, sizeof(rxbuf)); + memset(txbuf, 0, sizeof(txbuf)); + + //printf("tx %1d bytes: ", msglen); + //__android_log_print(ANDROID_LOG_INFO, "SPi", "tx %1d bytes", msglen); + +CMD_RESEND: + + memcpy(txbuf, (const void *)Indentify_CMD, sizeof(Indentify_CMD)); + + SendCMD(txbuf, rxbuf); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + SendId(txbuf, rxbuf, 0x55); + + memcpy(txbuf, to_idt, 32); + + SendData(txbuf, rxbuf, 32); + + SendEnd(txbuf, rxbuf); + + memcpy(txbuf, (const void *)SM2decoder_CMD, sizeof(SM2decoder_CMD)); + + RcvINS(txbuf, rxbuf, txbuf[1]); + + RcvLEN(txbuf, rxbuf + 1, 1); + + RcvData(txbuf, rxbuf + 2); + + RcvSW(txbuf, rxbuf + 2 + rxbuf[1], 0x90); + + //__android_log_print(ANDROID_LOG_INFO, "SPi", "rx %1d bytes:", rxbuf[1]+4); + memcpy(out_idt, rxbuf + 2, rxbuf[1]-1); + + return 0; +} diff --git a/app/src/main/cpp/NrsecPort.h b/app/src/main/cpp/NrsecPort.h new file mode 100644 index 0000000..71a5828 --- /dev/null +++ b/app/src/main/cpp/NrsecPort.h @@ -0,0 +1,58 @@ +#ifndef __NRSECPORT_H__ +#define __NRSECPORT_H__ + +#include "SpiPort.h" +#include + + +#define CMD_HEAD_SIZE 5 +using namespace std; +typedef uint8_t uint8_t; + +class NrsecPort : public SpiPort { +public: + + int SM1ImportKey(const uint8_t* ek, const uint8_t* ak); + int ImportIV(const uint8_t* iv, uint8_t ivLength); + + int SM1Encrypt(const uint8_t* data, uint16_t dataLen, uint8_t* encryptedData, uint16_t *bufferLen); + int SM1Decrypt(const uint8_t* encryptedData, uint16_t encryptedDataLen, uint8_t* data, uint16_t* bufferLen); + + int Random(uint8_t* output, uint8_t length); + std::string Version(); + int Indentify(uint8_t *to_idt, uint8_t *out_idt); + int SM2keypair(int index); + int SM2ExportPublicKey(int index, uint8_t result[] ,uint8_t * len); + int SM2ExportPrivateKey(int index, uint8_t result[] ,uint8_t * len); + int SM2ImportPublicKey(int index, const uint8_t new_key[]); + int SM2ImportPrivateKey(int index, const uint8_t new_key[]); + int SM3Hash(uint8_t *to_hash, int len, uint8_t *out_hash); + int SM3Hash(uint8_t *in, int inl, uint8_t *out, uint8_t *pubkey, uint8_t *pucID, int idl); + int SM2Sign(int index, const uint8_t *to_sign, uint8_t *out_sign); + int SM2VerifySign(int index, uint8_t *hash, uint8_t * vs); + int SM2Encrypt(int index, uint8_t *to_encrypt, uint8_t * out_encrypt); + int SM2Decrypt(int index, uint8_t *to_decoder, uint8_t *out_decoder); + int SM2cert(int type, int index, string cert, uint8_t *out_cert, uint16_t *len); + +protected: + + uint8_t CalcCRC7(const uint8_t *buff, int len); + void SendCMD(uint8_t *cmd, uint8_t *rxbuf); + void RcvINS(uint8_t *txbuf, uint8_t *buf, uint8_t ins); + void RcvLEN(uint8_t *txbuf, uint8_t *buf, uint8_t len); + void RcvData(uint8_t *txbuf, uint8_t *buf); + void RcvData(uint8_t *txbuf, uint8_t *buf, int len); + bool RcvSW(uint8_t *txbuf, uint8_t *buf, uint8_t sw); + void SendEnd(uint8_t *txbuf, uint8_t *buf); + void SendId(uint8_t *txbuf, uint8_t *buf, uint8_t id); + void SendData(uint8_t *data, uint8_t *rxbuf, int data_size); + +protected: + std::mutex m_mutex; + +}; + + + + +#endif // __NRSECPORT_H__ diff --git a/app/src/main/cpp/SpiPort.cpp b/app/src/main/cpp/SpiPort.cpp new file mode 100644 index 0000000..5cb529e --- /dev/null +++ b/app/src/main/cpp/SpiPort.cpp @@ -0,0 +1,207 @@ +#include "SpiPort.h" +#ifdef _WIN32 +#include +#include +#endif +#include +#include +#include +#include +#include +#ifdef __ANDROID__ +#include +#include +#include +#include + +#include +#include + +#include +#endif + +//typedef unsigned char u8; + +#define RE_SUC 0x01 +#define RE_ERROR 0x00 + +#define TAG_SPI "SPI" + +SpiPort::SpiPort() +#ifdef _WIN32 +#ifdef TERMINAL_SERVER + : m_fd(INVALID_HANDLE_VALUE) +#endif +#else + : m_fd(0) +#endif +{ +} + +SpiPort::~SpiPort() +{ + Close(); +} + +bool SpiPort::Open(const char *path) +{ + m_path = path; +#ifdef _WIN32 +#ifdef TERMINAL_SERVER + CW2T utf8Path(CA2W(path, CP_UTF8)); + // m_fd = _open(path, O_RDWR); + m_fd = CreateFile(utf8Path, //port name + GENERIC_READ | GENERIC_WRITE, //Read/Write + 0, // No Sharing + NULL, // No Security + OPEN_EXISTING,// Open existing port only + 0, // Non Overlapped I/O + NULL); // Null for Comm Devices + if (m_fd == INVALID_HANDLE_VALUE) + { + return false; + } +#endif + return false; +#else + m_fd = open(path, O_RDWR); + + if (m_fd < 0) { + perror("open"); + return false; + } +#endif + spi_master_init(); + + return true; +} + +void SpiPort::Close() +{ +#ifdef _WIN32 +#ifdef TERMINAL_SERVER + if (m_fd != INVALID_HANDLE_VALUE) + { + CloseHandle(m_fd); + m_fd = INVALID_HANDLE_VALUE; + } +#endif +#else + if (m_fd > 0) + { + close(m_fd); + m_fd = 0; + } +#endif +} + +bool SpiPort::IsOpened() const +{ +#ifdef _WIN32 +#ifdef TERMINAL_SERVER + return m_fd != INVALID_HANDLE_VALUE; +#else + return false; +#endif +#else + return m_fd > 0; +#endif +} + +int SpiPort::spi_transfer(uint8_t *txbuf, uint8_t *rxbuf, int bytes) +{ + int status = 0; + +#ifdef _WIN32 + + // BOOL res = DeviceIoControl(); + // status = res ? 0 : -1; +#else + +#if 0 + struct spi_ioc_transfer xfer[2]; + memset(xfer, 0, sizeof(xfer)); + xfer[0].tx_buf = (__u64)txbuf; + xfer[0].rx_buf = (__u64)rxbuf; + xfer[0].len = bytes; + xfer[0].delay_usecs = 2; + + status = ioctl(m_fd, SPI_IOC_MESSAGE(1), xfer); +#else + struct spi_ioc_transfer xfer; + memset(&xfer, 0, sizeof(xfer)); + xfer.tx_buf = (__u64)txbuf; + xfer.rx_buf = (__u64)rxbuf; + xfer.len = bytes; + xfer.delay_usecs = 2; + + status = ioctl(m_fd, SPI_IOC_MESSAGE(1), &xfer); +#endif + if (status < 0) + { + perror("SPI_IOC_MESSAGE"); + return -1; + } +#endif + + return status; +} + +void SpiPort::spi_master_init() +{ + uint8_t mode = 3; + uint8_t lsb = 0; + uint8_t bits = 8; + //uint32_t speed = 30000000; + uint32_t speed = 2000000; + //uint32_t speed = 2000000; + //uint32_t speed = 33000000; + + // SPI_IOC_WR_MODE + int res = 0; + +#ifdef __ANDROID__ + res = ioctl(m_fd, SPI_IOC_WR_MODE, &mode); + res = ioctl(m_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + res = ioctl(m_fd, SPI_IOC_WR_LSB_FIRST, &lsb); + + if (ioctl(m_fd, SPI_IOC_RD_MODE, &mode) < 0) + { + perror("SPI rd_mode"); + return; + } + + if (ioctl(m_fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) + { + perror("SPI rd_lsb_fist"); + return; + } + + if (ioctl(m_fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) + { + perror("SPI rd bits_per_word"); + return; + } + + if (ioctl(m_fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) + { + perror("SPI rd max_speed_hz"); + return; + } + + __android_log_print(ANDROID_LOG_INFO, TAG_SPI, "%s: spi mode %d, %d bits %sper word, %d Hz max\n", m_path.c_str(), mode, bits, lsb ? "(lsb first) " : "", speed); +#endif + + //printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", + // name, mode, bits, lsb ? "(lsb first) " : "", speed); +} + +int SpiPort::delay(int x) +{ +#ifdef _WIN32 + std::this_thread::sleep_for(std::chrono::milliseconds(x)); +#else + usleep(x); +#endif + return 0; +} diff --git a/app/src/main/cpp/SpiPort.h b/app/src/main/cpp/SpiPort.h new file mode 100644 index 0000000..a04f6d5 --- /dev/null +++ b/app/src/main/cpp/SpiPort.h @@ -0,0 +1,44 @@ +#ifndef TESTCOMM_SPIPORT_H +#define TESTCOMM_SPIPORT_H + +#ifdef _WIN32 +#ifdef TERMINAL_SERVER +#include +#include +#endif +#else +#include +#endif +#include +using namespace std; + +class SpiPort { +public: + + SpiPort(); + virtual ~SpiPort(); + + bool Open(const char* path); + void Close(); + bool IsOpened() const; + + int spi_transfer(uint8_t *txbuf, uint8_t *rxbuf, int bytes); + void spi_master_init(); + static int delay(int x); + +protected: + std::string m_path; + +#ifdef _WIN32 +#ifdef TERMINAL_SERVER + HANDLE m_fd; +#endif +#else + int m_fd; +#endif +}; + + + + +#endif //TESTCOMM_SPIPORT_H diff --git a/app/src/main/cpp/chip.cpp b/app/src/main/cpp/chip.cpp new file mode 100644 index 0000000..ee7f9f8 --- /dev/null +++ b/app/src/main/cpp/chip.cpp @@ -0,0 +1,153 @@ +#include "chip.h" +#include "NrsecPort.h" +#include "GPIOControl.h" + +/* 生成动态库名称为libchip.so*/ + +#define SPI_NODE "/dev/spidev0.0" +NrsecPort m_nrsec; +bool nrsec_flag= false; +/* + * 打开设备,初始化资源... + * 成功返回1,错误返回0 + */ + +int chip_init() +{ + GpioControl::setCam3V3Enable(true); + GpioControl::setSpiPower(true); + if(nrsec_flag==false) + { + bool ret = m_nrsec.Open(SPI_NODE); + if (ret == 1) + { + nrsec_flag = true; + } + return ret; + + } + else{ + return 0; + } +} + +/* + * 关闭设备,释放资源... + */ +void chip_finish() +{ + m_nrsec.Close(); + GpioControl::setSpiPower(false); + GpioControl::setCam3V3Enable(false); + nrsec_flag=false; +} + +/* + * 调用芯片完成sm2签名运算,输入32字节,已HASH,输出64字节 + * 成功返回1,错误返回0 + */ +int chip_sm2_sign(unsigned char *from, unsigned int flen, + unsigned char *to, unsigned int *tlen) +{ + int ret = m_nrsec.SM2Sign(0,from,to); + if(ret ==1) + { + *tlen =64; + } + else{ + *tlen =0; + } + return ret; +} + +/* + * 调用芯片完成sm2验签运算,输入from 32字节,已HASH,输入sig 64字节 + * 成功返回1,错误返回0 + */ +int chip_sm2_verify(unsigned char *from, unsigned int flen, + unsigned char *sig, unsigned int siglen) +{ + int ret =m_nrsec.SM2VerifySign(0,from,sig); + + return ret; +} + +/* + * 调用芯片完成sm3运算,输入d,输入长度n,输出md,32字节 + * 成功返回1,错误返回0 + */ +int chip_sm3(const unsigned char *d, unsigned int n, unsigned char *md) +{ + uint8_t * cert = NULL; + uint8_t len = 0; + cert = (uint8_t *) malloc(64); + memset(cert,0,64); + int ret = m_nrsec.SM2ExportPublicKey(0,cert,&len); + if( ret == 0) + { + free(cert); + return ret; + } + uint8_t * pucID = NULL; + pucID = (uint8_t *) malloc(16); + memset(pucID,0,16); + memset(pucID,1,16); + + ret = m_nrsec.SM3Hash((uint8_t*)d,len,md,cert,pucID,16); + + free(pucID); + free(cert); + return ret; +} + +/* + * 调用芯片生成随机数,输入n,表示需要生成的随机数的长度,输出random + * 成功返回1,错误返回0 + */ +int chip_rand(unsigned int n, unsigned char *random) +{ + int ret =m_nrsec.Random(random,n); + + return ret; +} + +/* + * 调用芯片完成sm1运算,加解密模式CBC + * 输入key 16字节,输入iv 16字节, + * 输入enc,1表示加密,0表示解密 + * 输入in,16倍数,输入长度inlen,输出out + * 成功返回1,错误返回0 + */ +int chip_sm1(unsigned char *key, unsigned char *iv, int enc, + unsigned char *in, unsigned int inlen, unsigned char *out) +{ + unsigned char ak[16]={0}; + int ret =m_nrsec.SM1ImportKey(key,ak); + if(ret == 0) + { + return ret; + } + ret =m_nrsec.ImportIV(iv,16); + if(ret == 0) + { + return ret; + } + uint16_t outlen; + if(enc==1) + { + ret = m_nrsec.SM1Encrypt(in,inlen,out, &outlen); + if(ret == 0) + { + return ret; + } + + } + else{ + ret = m_nrsec.SM1Decrypt(in,inlen,out, &outlen); + if(ret == 0) + { + return ret; + } + } + return ret; +} \ No newline at end of file diff --git a/app/src/main/cpp/chip.h b/app/src/main/cpp/chip.h new file mode 100644 index 0000000..e4d2224 --- /dev/null +++ b/app/src/main/cpp/chip.h @@ -0,0 +1,64 @@ +#ifndef __CHIP_H__ +#define __CHIP_H__ + +/* 生成动态库名称为libchip.so*/ +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ +/* + * 打开设备,初始化资源... + * 成功返回1,错误返回0 + */ +int chip_init(); + +/* + * 关闭设备,释放资源... + */ +void chip_finish(); + +/* + * 调用芯片完成sm2签名运算,输入32字节,已HASH,输出64字节 + * 成功返回1,错误返回0 + */ +int chip_sm2_sign(unsigned char *from, unsigned int flen, + unsigned char *to, unsigned int *tlen); + +/* + * 调用芯片完成sm2验签运算,输入from 32字节,已HASH,输入sig 64字节 + * 成功返回1,错误返回0 + */ +int chip_sm2_verify(unsigned char *from, unsigned int flen, + unsigned char *sig, unsigned int siglen); + +/* + * 调用芯片完成sm3运算,输入d,输入长度n,输出md,32字节 + * 成功返回1,错误返回0 + */ +int chip_sm3(const unsigned char *d, unsigned int n, unsigned char *md); + +/* + * 调用芯片生成随机数,输入n,表示需要生成的随机数的长度,输出random + * 成功返回1,错误返回0 + */ +int chip_rand(unsigned int n, unsigned char *random); + +/* + * 调用芯片完成sm1运算,加解密模式CBC + * 输入key 16字节,输入iv 16字节, + * 输入enc,1表示加密,0表示解密 + * 输入in,16倍数,输入长度inlen,输出out + * 成功返回1,错误返回0 + */ +int chip_sm1(unsigned char *key, unsigned char *iv, int enc, + unsigned char *in, unsigned int inlen, unsigned char *out); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + + +#endif /* __DS_NRSEC_STRUCT_H__ */ diff --git a/app/src/main/cpp/native-lib.cpp b/app/src/main/cpp/native-lib.cpp new file mode 100644 index 0000000..e690488 --- /dev/null +++ b/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,73 @@ +#include +#include +#include "chip.h" +#include +#include +#include + +#define TAG_Test "TESTCHIP" + +using namespace std; + +extern "C" JNIEXPORT jstring JNICALL +Java_com_example_test3_MainActivity_stringFromJNI( + JNIEnv* env, + jobject /* this */) { + + int ret = chip_init(); + __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_init status %d", ret); + + sleep(1); + + vector data(32,1); + vector hash(32,1); + vector sign(64,0); + //uint8_t pbdata[64]={0x64,0x3c,0xd1,0x20,0x7f,0x42,0xcd,0xc7,0xac,0xa1,0xe8,0x12,0x92,0x24,0x58,0x76,0x2f,0x40,0xc5,0x1f,0xd8,0x18,0x78,0x69,0x2b,0xca,0x4c,0x8a,0x8e,0x75,0xcb,0xda,0xda,0x22,0x2f,0xb9,0x7d,0xb8,0x67,0x16,0x0d,0x81,0x39,0x8d,0xf1,0x09,0x4f,0xcf,0x51,0xf9,0xdc,0x71,0x20,0x40,0xe5,0x4d,0x52,0xb5,0xc5,0x74,0x85,0xe6,0xbb,0x65}; + vector pucid(16,1); + + unsigned int len=1; + + ret = chip_sm3(&data[0],32,&hash[0]); + __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm3_all status %d ", ret); + sleep(1); + + + ret = chip_sm2_sign(&hash[0],32,&sign[0],&len); + __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm2_sign status %d,len=%d", ret,len); + for(int i=0;i data(16,0); + //ret = chip_rand(16,&data[0]); + //__android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_rand %d", ret); + + vector DK(16,1); + vector IV(16,1); + data.clear(); + data.resize(16,2); + vector edata(16,0); + ret = chip_sm1(&DK[0],&IV[0],1,&data[0],16,&edata[0]); + + sleep(1); + vector edata2(16,0); + ret = chip_sm1(&DK[0],&IV[0],0,&edata[0],16,&edata2[0]); + + for(int i=0;i<16;i++) + { + __android_log_print(ANDROID_LOG_INFO, TAG_Test, "chip_sm1 %d value %d ", i, edata2[i]); + } + + + + chip_finish(); + + std::string hello = "Hello from C++"; + return env->NewStringUTF(hello.c_str()); +} \ No newline at end of file diff --git a/app/src/main/java/com/example/test6/MainActivity.java b/app/src/main/java/com/example/test6/MainActivity.java new file mode 100644 index 0000000..cb261b4 --- /dev/null +++ b/app/src/main/java/com/example/test6/MainActivity.java @@ -0,0 +1,36 @@ +package com.example.test6; + +import androidx.appcompat.app.AppCompatActivity; + +import android.os.Bundle; +import android.widget.TextView; + +import com.example.test6.databinding.ActivityMainBinding; + +public class MainActivity extends AppCompatActivity { + + // Used to load the 'test6' library on application startup. + static { + System.loadLibrary("test6"); + } + + private ActivityMainBinding binding; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + // Example of a call to a native method + TextView tv = binding.sampleText; + tv.setText(stringFromJNI()); + } + + /** + * A native method that is implemented by the 'test6' native library, + * which is packaged with this application. + */ + public native String stringFromJNI(); +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..0fdf985 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..68a771f --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..5ae26d2 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + test6 + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..a95bd39 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..fa0f996 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..9ee9997 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/example/test6/ExampleUnitTest.java b/app/src/test/java/com/example/test6/ExampleUnitTest.java new file mode 100644 index 0000000..f798211 --- /dev/null +++ b/app/src/test/java/com/example/test6/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.example.test6; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..41532d1 --- /dev/null +++ b/build.gradle @@ -0,0 +1,5 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id 'com.android.application' version '8.0.0' apply false + id 'com.android.library' version '8.0.0' apply false +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3e927b1 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..02a7256 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Aug 01 15:31:22 CST 2024 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..4b75153 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } + maven { url 'https://maven.aliyun.com/repository/google' } + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +rootProject.name = "test6" +include ':app'