1. 程式人生 > >加密IC 在android 機子上的簡單應用

加密IC 在android 機子上的簡單應用

原理:

產生一個組隨機機,寫入加密IC ,再從IC 中讀出來一組數,經演算法計算後,判斷之前的隨機數和計算的結果一樣,就證明此IC 為加密 IC ..因為加密演算法保密和隨機性比較大,防止抄板效果不錯。

kernel 層:

保證 i2c 通就行。不需要額外驅動。

hardware 層,通用程式碼如下。如果判斷沒有此 IC ,就重啟機子。此程式碼裡 隨機數就用的當前的時間

#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include <linux/if.h>
#include <sys/ioctl.h>
#include <netinet/ether.h>
#include <pthread.h>
#include <signal.h>
#include <utils/Log.h>
#include <cutils/log.h>
#include <hardware/hardware.h>  
#include <fcntl.h>  
#include <errno.h>  
#include <cutils/atomic.h> 
#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <time.h>
#include <sys/reboot.h>

#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "encrypt_ic"
#endif

#define DEVICE_NAME "/dev/i2c-4"  
#define MODULE_NAME "iic"  
#define MODULE_AUTHOR "
[email protected]
" #define I2C_RETRIES 0x0701/* number of times a device address should be polled when not acknowledging */ #define I2C_TIMEOUT 0x0702/* set timeout in units of 10 ms */ #define I2C_RDWR 0x0707 int fd; /*********定義struct i2c_rdwr_ioctl_data和struct i2c_msg,要和核心一致*******/ struct i2c_msg { __u16 addr; /* slave address */ __u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_RD 0x0001 /* read data, from slave to master */ #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ __u16 len; /* msg length */ __u8 *buf; /* pointer to msg data */ __u32 scl_rate; /* add by kfx */ }; /* This is the structure as used in the I2C_RDWR ioctl call */ struct i2c_rdwr_ioctl_data { struct i2c_msg *msgs;/* pointers to i2c_msgs */ int nmsgs; /* number of i2c_msgs */ }; struct i2c_rdwr_ioctl_data iic_data; int ret; static int iic_write(unsigned char* dataBuf, unsigned char slaveAddr, unsigned char subAddr, int len) { int count = 0; unsigned char data[9]; unsigned char bytes; data[0] = subAddr; memcpy(&data[1], dataBuf, 8); iic_data.nmsgs=1; (iic_data.msgs[0]).len=len; //寫入地址位和資料長度 (iic_data.msgs[0]).addr=slaveAddr;// 裝置地址0x50 (iic_data.msgs[0]).flags=0; //write (iic_data.msgs[0]).scl_rate = 100000; (iic_data.msgs[0]).buf=data; ret=ioctl(fd,I2C_RDWR,(unsigned long)&iic_data); if(ret<0){ ALOGI("IIC HAL ioctl error"); } return 0; } static int iic_read(unsigned char* dataBuf, unsigned char slaveAddr, unsigned char subAddr, int len) { iic_data.nmsgs=2; (iic_data.msgs[0]).len=1; (iic_data.msgs[0]).addr=slaveAddr; // 裝置地址 (iic_data.msgs[0]).flags=0;//write (iic_data.msgs[0]).buf= &subAddr; (iic_data.msgs[0]).scl_rate = 100000; (iic_data.msgs[1]).len=len; (iic_data.msgs[1]).addr=slaveAddr; // 裝置地址 (iic_data.msgs[1]).flags=I2C_M_RD;//read (iic_data.msgs[1]).buf= dataBuf; (iic_data.msgs[1]).scl_rate = 100000; if(ioctl(fd, I2C_RDWR,(unsigned long)&iic_data)<0){ ALOGE("ioctl read error"); } ALOGI("IIC read HAL: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", dataBuf[0], dataBuf[1], dataBuf[2], dataBuf[3], dataBuf[4], dataBuf[5], dataBuf[6], dataBuf[7], dataBuf[8], dataBuf[9]); return 0; } int main(int argc, char *argv[]) { unsigned char write_data[8]; unsigned char read_data[10]; unsigned char tx_data[10]; unsigned char rx_data[8]; struct tm *time_now; time_t time_second; time(&time_second); time_now = localtime(&time_second); memset(write_data, 0x68, 8); write_data[0] = time_now->tm_sec; write_data[1] = time_now->tm_min; write_data[2] = time_now->tm_hour; write_data[3] = time_now->tm_mday; write_data[4] = time_now->tm_mon; write_data[5] = time_now->tm_year; write_data[6] = time_now->tm_wday; if((fd = open(DEVICE_NAME, O_RDWR)) == -1) { ALOGE("iic Stub hal: failed to open /dev/i2c-1 -- %s.", strerror(errno)); return -EFAULT; }else{ ALOGV("iic Stub hal: open %s successfully.", DEVICE_NAME); iic_data.nmsgs=2; iic_data.msgs=(struct i2c_msg*)malloc(iic_data.nmsgs*sizeof(struct i2c_msg)); if(!iic_data.msgs){ ALOGE("malloc error"); close(fd); exit(1); } ioctl(fd, I2C_TIMEOUT, 2);//設定超時時間 ioctl(fd, I2C_RETRIES, 1);//設定重發次數 } iic_write(write_data, 0x60, 0xa0, 9); iic_read(read_data,0x60,0xa0, 10); //copy the encrypt ic data to soft input memcpy(tx_data, read_data, 10); EDesEn_Crypt(tx_data, rx_data); //ALOGI("is soft we get the data: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", rx_data[0], rx_data[1], rx_data[2], rx_data[3], rx_data[4], rx_data[5], rx_data[6], rx_data[7]); ALOGI("is soft we get the data: %d, %d, %d, %d, %d, %d, %d, %d", rx_data[0], rx_data[1], rx_data[2], rx_data[3], rx_data[4], rx_data[5], rx_data[6], rx_data[7]); if(memcmp(write_data, rx_data, 8) == 0 ) ALOGD("read encrypt ic OKay & the devices is hello"); else { ALOGD("read encrypt ic the devices is not hello, so reboot"); sync(); // 同步磁碟資料,將快取資料回寫到硬碟,以防資料丟失[luther.gliethttp] return reboot(RB_AUTOBOOT); } return 0; }

Android.mk 如下, licsc.a 為演算法庫。mm 後產生一個 i2c_write 的檔案在 /system/bin/
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
#LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := i2c_command.c
# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := \
	  libutils libc libcutils

LOCAL_LDFLAGS = $(LOCAL_PATH)/libsc.a
LOCAL_MODULE := i2c_write
include $(BUILD_EXECUTABLE)


以上檔案編譯好後,手動可以在板子上敲命令 ./i2c_write 可以檢視

I/encrypt_ic( 6299): IIC read HAL: 0xff, 0x31, 0xe7, 0xd3, 0x3f, 0x4e, 0x88, 0x2a, 0xa7, 0x5b
I/encrypt_ic( 6299): is soft we get the data: 33, 0, 13, 1, 0, 111, 6, 104
D/encrypt_ic( 6299): read encrypt ic OKay & the devices is hello

---------------------------------------------------------------------------------

測試OK 後,把其功能加到系統。

由於 android 可以定製。決定在 bootanimation 通過 init.rc 這裡進行判斷。

程式碼 

--- a/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
+++ b/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
@@ -43,6 +43,8 @@ int main(int argc, char** argv)
 #if defined(HAVE_PTHREADS)
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
 #endif
+    ALOGE("!!!!!!!!!!!!!! Now check the ic encrypt . if the IC check fail .the system will be reboot");
+    property_set("ctl.start", "ic_encrypt");
 
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sf.nobootanimation", value, "0");

--- a/device/rockchip/rk3288/init.rc
+++ b/device/rockchip/rk3288/init.rc
@@ -642,3 +642,11 @@ service drawpath /system/bin/drawpath
        class main
        disabled
        oneshot
+
+ 
+service ic_encrypt /system/bin/i2c_write
+       class main
+       disabled
+       oneshot     
+
+

編譯刷機後,經驗證:在沒有 加密ic 或者 ic 讀寫出錯 的機子上,機子啟動不了,會不斷重啟 
read encrypt ic the devices is not hello, so reboot

在有對應加密演算法會正常重啟。

log 就會看到 

ead encrypt ic OKay & the devices is hello

備註:

此 i2c 用的是連續寫 8個位元組 和 讀 10 個位元組的方法