加密IC 在android 机子上的简单应用

9 篇文章 0 订阅
3 篇文章 0 订阅

原理:

产生一个组随机机,写入加密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 "pcwung@163.com"  


#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 个字节的方法


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值