[Feature][ZXW-130]merge P50U02 version

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I4f29ec5bb7c59385f23738d2b7ca84e67c100f69
diff --git a/ap/lib/libatext/ext_amt_func.c b/ap/lib/libatext/ext_amt_func.c
index d5470d5..4460b51 100755
--- a/ap/lib/libatext/ext_amt_func.c
+++ b/ap/lib/libatext/ext_amt_func.c
@@ -36,6 +36,7 @@
 #include "nv_api.h"

 #include "amtnv.h"

 #include <linux/soc/zte/efuse/efuse_zx.h>

+#include <linux/soc/zte/otp/otp_zx.h>

 #include "NvParam_drv.h"

 #include "libkey.h"

 

@@ -1924,6 +1925,134 @@
     return AT_END;

 }

 

+

+#define SHA256_ROTL(a,b) (((a>>(32-b))&(0x7fffffff>>(31-b)))|(a<<b))

+#define SHA256_SR(a,b) ((a>>b)&(0x7fffffff>>(b-1)))

+#define SHA256_Ch(x,y,z) ((x&y)^((~x)&z))

+#define SHA256_Maj(x,y,z) ((x&y)^(x&z)^(y&z))

+#define SHA256_E0(x) (SHA256_ROTL(x,30)^SHA256_ROTL(x,19)^SHA256_ROTL(x,10))

+#define SHA256_E1(x) (SHA256_ROTL(x,26)^SHA256_ROTL(x,21)^SHA256_ROTL(x,7))

+#define SHA256_O0(x) (SHA256_ROTL(x,25)^SHA256_ROTL(x,14)^SHA256_SR(x,3))

+#define SHA256_O1(x) (SHA256_ROTL(x,15)^SHA256_ROTL(x,13)^SHA256_SR(x,10))

+

+

+/**

+ * @brief ¼ÆËãSHA-256

+ * @param[in,out] str     ÐèÒª¼ÆËãSHA-256 hashÖµµÄÂëÁ÷Ö¸Õë

+ * @param[in,out] length  ÂëÁ÷³¤¶È

+ * @param[in,out] sha256  ÓÃÓÚ±£´æSHA-256µÄÖ¸Õë

+ * @return ³É¹¦·µ»Øsha256£¬Ê§°Ü·µ»Ø0

+ * @note

+ * @see 

+ */

+

+unsigned char* StrSHA256(const unsigned char* str, long long length, unsigned char* sha256)

+{

+    /*

+    ¼ÆËã×Ö·û´®SHA-256

+    ²ÎÊý˵Ã÷£º

+    str         ×Ö·û´®Ö¸Õë

+    length      ×Ö·û´®³¤¶È

+    sha256         ÓÃÓÚ±£´æSHA-256µÄ×Ö·û´®Ö¸Õë

+    ·µ»ØÖµÎª²ÎÊýsha256

+    */

+    unsigned char *pp, *ppend;

+    long l, i, W[64], T1, T2, A, B, C, D, E, F, G, H, H0, H1, H2, H3, H4, H5, H6, H7;

+    H0 = 0x6a09e667, H1 = 0xbb67ae85, H2 = 0x3c6ef372, H3 = 0xa54ff53a;

+    H4 = 0x510e527f, H5 = 0x9b05688c, H6 = 0x1f83d9ab, H7 = 0x5be0cd19;

+    long K[64] = {

+        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,

+        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,

+        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,

+        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,

+        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,

+        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,

+        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,

+        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,

+    };

+    l = length + ((length % 64 >= 56) ? (128 - length % 64) : (64 - length % 64));

+    if (!(pp = (unsigned char*)malloc((unsigned long)l))) return 0;

+    for (i = 0; i < length; pp[i + 3 - 2 * (i % 4)] = str[i], i++);

+    for (pp[i + 3 - 2 * (i % 4)] = 128, i++; i < l; pp[i + 3 - 2 * (i % 4)] = 0, i++);

+    *((long*)(pp + l - 4)) = length << 3;

+    *((long*)(pp + l - 8)) = length >> 29;

+    for (ppend = pp + l; pp < ppend; pp += 64){

+        for (i = 0; i < 16; W[i] = ((long*)pp)[i], i++);

+        for (i = 16; i < 64; W[i] = (SHA256_O1(W[i - 2]) + W[i - 7] + SHA256_O0(W[i - 15]) + W[i - 16]), i++);

+        A = H0, B = H1, C = H2, D = H3, E = H4, F = H5, G = H6, H = H7;

+        for (i = 0; i < 64; i++){

+            T1 = H + SHA256_E1(E) + SHA256_Ch(E, F, G) + K[i] + W[i];

+            T2 = SHA256_E0(A) + SHA256_Maj(A, B, C);

+            H = G, G = F, F = E, E = D + T1, D = C, C = B, B = A, A = T1 + T2;

+        }

+        H0 += A, H1 += B, H2 += C, H3 += D, H4 += E, H5 += F, H6 += G, H7 += H;

+    }

+    free(pp - l);

+    memcpy(sha256,&H0,sizeof(H0));

+	memcpy(sha256 + sizeof(H0),&H1,sizeof(H1));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1),&H2,sizeof(H2));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1) + sizeof(H2),&H3,sizeof(H3));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1) + sizeof(H2) + sizeof(H3),&H4,sizeof(H4));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1) + sizeof(H2) + sizeof(H3) + sizeof(H4),&H5,sizeof(H5));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1) + sizeof(H2) + sizeof(H3) + sizeof(H4) + sizeof(H5),&H6,sizeof(H6));

+	memcpy(sha256 + sizeof(H0) + sizeof(H1) + sizeof(H2) + sizeof(H3) + sizeof(H4) + sizeof(H5) + sizeof(H6),&H7,sizeof(H7));

+    return sha256;

+}

+

+static int IsEnhancedSecurity()

+{

+    #define CMDLINE_MAX_SIZE   (4*1024)

+    int cmdline_fd = -1;

+	char*cmdline_buf = malloc(CMDLINE_MAX_SIZE);

+	char*temp = NULL;

+	int ret_size = 0;

+	if(cmdline_buf == NULL)

+	{

+	    at_print(AT_ERR,"malloc cmdline_buf fail.\n");

+		return -1;

+	}

+    //²éÕÒcmdlineÖеÄEnhancedSecurityÊÇ·ñ´æÔÚ

+	cmdline_fd = open("/proc/cmdline", O_RDONLY);

+	if (cmdline_fd < 0) {

+		at_print(AT_ERR,"open %s fail.\n","/proc/cmdline");

+		return -1;

+	}

+	ret_size = read(cmdline_fd, cmdline_buf, CMDLINE_MAX_SIZE);

+	if(ret_size <= 0)

+	{

+		at_print(AT_ERR,"read /proc/cmdline fail.\n");

+		close(cmdline_fd);

+		return -1;

+	}

+	close(cmdline_fd);

+    temp = strstr(cmdline_buf,"EnhancedSecurity=");

+	if(temp == NULL)

+	{

+    	at_print(AT_ERR,"can not find EnhancedSecurity=\n");

+		return -1;

+	}

+	temp = temp + strlen("EnhancedSecurity=");

+	if(temp == NULL)

+	{

+    	at_print(AT_ERR,"temp = NULL\n");

+		return -1;

+	}

+	if(*temp == '0')

+	{

+		return 0;

+	}

+	else if(*temp == '1')

+	{

+	    at_print(AT_ERR,"EnhancedSecurity=1\n");

+		return 1;

+	}

+	else

+	{

+		return -1;

+	}

+}

+

+

 int write_security_info(int at_fd, char *at_paras, void **res_msg, int *res_msglen)

 {

     UINT32 pubKeyHash[4] = {0};

@@ -1934,8 +2063,23 @@
     md5_ctx stStc;

     int i;

 	int efuse_fd = -1;

-	//int ret = -1;

 

+	UINT32 pubKeyHash_otp[8] = {0};

+	UINT32 secureFlag_otp = 0x00;

+	T_ZDrvOtp_Secure otpInfo = {{0}};

+	int otp_fd = -1;

+	int is_Enhanced_Security = -1;

+

+	is_Enhanced_Security = IsEnhancedSecurity();

+	at_print(AT_ERR,"is_Enhanced_Security = %d.\n",is_Enhanced_Security);

+	if(is_Enhanced_Security == -1)

+	{

+		at_print(AT_ERR,"IsEnhancedSecurity() fail.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		return AT_END;

+	}

+   

     /*************************»ñÈ¡¹«Ô¿hash**************************/

     // »ñÈ¡¹«Ô¿

 	efuse_fd = open("/dev/efuse", O_RDWR);

@@ -1946,6 +2090,8 @@
 		return AT_END;

 	}

 

+	at_print(AT_ERR,"open %s success.\n","/dev/efuse");

+

 	if(ioctl(efuse_fd , EFUSE_GET_DATA, &efuseInfo)!= 0)

 	{

 	    at_print(AT_ERR,"ioctl: EFUSE_GET_DATA fail.\n");

@@ -1954,7 +2100,81 @@
 		close(efuse_fd);

 		return AT_END;

 	}

-	at_print(AT_NORMAL, "security flag in efuse: %08X\r", efuseInfo.secureFlag);

+	at_print(AT_ERR, "security flag in efuse: %08X\n", efuseInfo.secureFlag);

+

+	//ÅжÏefuseÀïÃæµÄ¹«Ô¿ÊÇ·ñºÏ·¨£¬Èç¹ûÊÇÈ«0£¬Ö±½ÓÍ˳ö

+	for (i = 0; i < sizeof(efuseInfo.pubKeyRsaE)/sizeof(UINT32); i++)

+    {

+    	if(efuseInfo.pubKeyRsaE[i] != 0)

+    	{

+    		break;

+		}

+	}

+	if(i == sizeof(efuseInfo.pubKeyRsaE)/sizeof(UINT32))

+	{

+		at_print(AT_ERR,"efuse pubkey E is all zero.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		close(efuse_fd);

+		return AT_END;

+	}

+

+	for (i = 0; i < sizeof(efuseInfo.pubKeyRsaN)/sizeof(UINT32); i++)

+    {

+    	if(efuseInfo.pubKeyRsaN[i] != 0)

+    	{

+    		break;

+		}

+	}

+	if(i == sizeof(efuseInfo.pubKeyRsaN)/sizeof(UINT32))

+	{

+		at_print(AT_ERR,"efuse pubkey N is all zero.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		close(efuse_fd);

+		return AT_END;

+	}

+

+

+	   // ´òÓ¡¹«Ô¿

+		#if 1

+		strLog[0] = '\0';

+		for (i = 0; i < 16; i++)

+		{

+			sprintf(strValue, "%08lX", efuseInfo.pubKeyRsaE[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "efuse Pubkey E1: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 16; i < 32; i++)

+		{

+			sprintf(strValue, "%08lX", efuseInfo.pubKeyRsaE[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "efuse Pubkey E2: %s\n", strLog);

+		

+        memset(strLog, 0, sizeof(strLog));

+	    for (i = 0; i < 16; i++)

+		{

+			sprintf(strValue, "%08lX", efuseInfo.pubKeyRsaN[i]);

+			strcat(strLog, strValue);

+		}

+	

+		at_print(AT_ERR, "efuse Pubkey N1: %s\n", strLog);

+	

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 16; i < 32; i++)

+		{

+			sprintf(strValue, "%08lX", efuseInfo.pubKeyRsaN[i]);

+			strcat(strLog, strValue);

+		}

+	

+		at_print(AT_ERR, "efuse Pubkey N2: %s\n", strLog);

+		#endif

+	

 	

     // ¼ÆË㹫ԿhashÖµ

     md5_init(&stStc);

@@ -1975,16 +2195,16 @@
         strcat(strLog, strValue);

     }

 

-    at_print(AT_NORMAL, "Public key hash: %s\r", strLog);

+    at_print(AT_ERR, "Public key hash: %s\n", strLog);

 	

 	/*************************½«°²È«ÐÅϢдÈëefuse**************************/

-	

+	#if 1

 	if (memcmp(efuseInfo.pubKeyHash, pubKeyHash, sizeof(pubKeyHash)) != 0)

 	{

 		// ¹«Ô¿hashֵдÈëefuse

 		if (ioctl(efuse_fd , EFUSE_SET_PUB_KEY_HASH, pubKeyHash) != 0)

 		{

-	    	at_print(AT_ERR, "Write public key hash to efuse fail!\r");

+	    	at_print(AT_ERR, "Write public key hash to efuse fail!\n");

 			*res_msg = at_err_build(ATERR_PROC_FAILED);

 			*res_msglen = strlen(*res_msg);

 			close(efuse_fd);

@@ -1992,13 +2212,37 @@
 		}

 		else

 		{

-			at_print(AT_NORMAL, "Write public key hash to efuse success!\r");

+			at_print(AT_ERR, "Write public key hash to efuse success!\n");

 		}

     }

 	else

 	{

-		at_print(AT_NORMAL, "Public key's hash value already exists!\r");

+		at_print(AT_ERR, "Public key's hash value already exists!\n");

 	}

+

+    /*************************ÅжÏдÈëµÄ¹«Ô¿hashÖµÊÇ·ñÕýÈ·**************************/

+	// ´Óefuse¶ÁÈ¡

+    memset(&efuseInfo, 0, sizeof(efuseInfo));

+    if(ioctl(efuse_fd , EFUSE_GET_DATA, &efuseInfo)!= 0)

+    {

+        at_print(AT_ERR,"ioctl: EFUSE_GET_DATA fail.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		close(efuse_fd);

+		return AT_END;

+    }

+	if (memcmp(efuseInfo.pubKeyHash, pubKeyHash, sizeof(pubKeyHash)) != 0)

+    {

+        at_print(AT_ERR, "Public key hash is not consistent!\n");

+        *res_msg = at_err_build(ATERR_PROC_FAILED);

+        *res_msglen = strlen(*res_msg);

+		close(efuse_fd);

+        return AT_END;

+    }

+	#endif

+

+	#if 1

+

 	/*efuseInfo.secureFlagÇ°Ãæ3¸ö×Ö½ÚÊÇchip flag,×îºóÒ»¸ö×Ö½ÚÊǰ²È«Ê¹ÄܱêÖ¾*/

 	

     if ((efuseInfo.secureFlag&0xff) != secureFlag)

@@ -2043,21 +2287,321 @@
 		close(efuse_fd);

         return AT_END;

     }

+	#endif

+    close(efuse_fd);

+	

+	if(is_Enhanced_Security == 0)

+	{

+		*res_msg = at_query_result_build("write security infomation", NULL);

+    	*res_msglen = strlen(*res_msg);

+	     return AT_END;

+	}

+	

+	if(is_Enhanced_Security == 1)

+	{

+		/*************************»ñÈ¡¹«Ô¿hash**************************/

+	    // »ñÈ¡¹«Ô¿

+		otp_fd = open("/dev/otp", O_RDWR);

+		if (otp_fd < 0) {

+			at_print(AT_ERR,"open %s fail.\n","/dev/otp");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			return AT_END;

+		}

+		at_print(AT_ERR,"open %s success.\n","/dev/otp");

 

-    if (memcmp(efuseInfo.pubKeyHash, pubKeyHash, sizeof(pubKeyHash)) != 0)

-    {

-        at_print(AT_ERR, "Public key hash is not consistent!\r");

-        *res_msg = at_err_build(ATERR_PROC_FAILED);

-        *res_msglen = strlen(*res_msg);

-		close(efuse_fd);

-        return AT_END;

-    }

+		if(ioctl(otp_fd , OTP_GET_DATA, &otpInfo)!= 0)

+		{

+		    at_print(AT_ERR,"ioctl: OTP_GET_DATA fail.\n");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			close(otp_fd);

+			return AT_END;

+		}

+	

+		at_print(AT_ERR, "security flag in otp: %08X\n", otpInfo.secureFlag);

 

-    *res_msg = at_query_result_build("write security infomation", NULL);

-    *res_msglen = strlen(*res_msg);

-	close(efuse_fd);

-    return AT_END;

+		// ´òÓ¡¹«Ô¿

+		#if 1

+		strLog[0] = '\0';

+		for (i = 0; i < 16; i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key1: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 16; i < 32; i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key2: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 32; i < 48; i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key3: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 48; i < 64; i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key4: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 64; i < 80; i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key5: %s\n", strLog);

+

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 80; i < sizeof(otpInfo.pubKey)/sizeof(UINT32); i++)

+		{

+			sprintf(strValue, "%08lX", otpInfo.pubKey[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key6: %s\n", strLog);

+		#endif

+		//¼ÆË㹫ԿhashÖµ

+	    StrSHA256((const unsigned char*)otpInfo.pubKey, sizeof(otpInfo.pubKey), (unsigned char*)pubKeyHash_otp);

+	    // ´òÓ¡¹«Ô¿hash

+		memset(strLog, 0, sizeof(strLog));

+		for (i = 0; i < sizeof(pubKeyHash_otp)/sizeof(UINT32); i++)

+		{

+			sprintf(strValue, "%08lX", pubKeyHash_otp[i]);

+			strcat(strLog, strValue);

+		}

+

+		at_print(AT_ERR, "OTP Public key hash: %s\n", strLog);

+

+		#if 1

+		

+		/*************************½«°²È«ÐÅϢдÈëotp**************************/

+		

+		if (memcmp(otpInfo.pubKeyHash, pubKeyHash_otp, sizeof(pubKeyHash_otp)) != 0)

+		{

+			// ¹«Ô¿hashֵдÈëotp

+			if (ioctl(otp_fd , OTP_SET_PUB_KEY_HASH, pubKeyHash_otp) != 0)

+			{

+		    	at_print(AT_ERR, "Write public key hash to otp fail!\n");

+				*res_msg = at_err_build(ATERR_PROC_FAILED);

+				*res_msglen = strlen(*res_msg);

+				close(otp_fd);

+				return AT_END;

+			}

+			else

+			{

+				at_print(AT_NORMAL, "Write public key hash to otp success!\n");

+			}

+	    }

+		else

+		{

+			at_print(AT_NORMAL, "Public key's hash value in otp already exists!\n");

+		}

+

+		/*************************ÅжÏдÈëµÄ¹«Ô¿hashÖµÊÇ·ñÕýÈ·**************************/

+	    // ´Óotp¶ÁÈ¡

+		memset(&otpInfo, 0, sizeof(otpInfo));

+	    if(ioctl(otp_fd , OTP_GET_DATA, &otpInfo)!= 0)

+		{

+			at_print(AT_ERR,"ioctl: OTP_GET_DATA fail.\n");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			close(otp_fd);

+			return AT_END;

+		}

+		 //±£Ö¤Ç°Ã湫Կhashֵд³É¹¦ÁË£¬ÔÙдÈ밲ȫboot flag

+		if (memcmp(otpInfo.pubKeyHash, pubKeyHash_otp, sizeof(pubKeyHash_otp)) != 0)

+	    {

+	        at_print(AT_ERR, "Public key hash in otp is not consistent!\n");

+	        *res_msg = at_err_build(ATERR_PROC_FAILED);

+	        *res_msglen = strlen(*res_msg);

+			close(otp_fd);

+	        return AT_END;

+	    }

+		#endif

+

+		#if 1

+		

+		/*efuseInfo.secureFlagÇ°Ãæ3¸ö×Ö½ÚÊÇchip flag,×îºóÒ»¸ö×Ö½ÚÊǰ²È«Ê¹ÄܱêÖ¾*/

+		

+	    if ((otpInfo.secureFlag&0xff) != secureFlag_otp)

+	    {

+	        // ʹÄܱêʶλдÈëotp

+	        if (ioctl(otp_fd , OTP_SET_SECURE_EN, &secureFlag_otp) != 0)

+	        {

+	            at_print(AT_ERR, "Write security flag to otp fail!\n");

+	            *res_msg = at_err_build(ATERR_PROC_FAILED);

+	            *res_msglen = strlen(*res_msg);

+				close(otp_fd);

+	            return AT_END;

+	        }

+	        else

+	        {

+	            at_print(AT_NORMAL, "Write security flag to otp success!\n");

+	        }

+	    }

+		else

+	    {

+	        at_print(AT_NORMAL, "Secure flag already exists!\n");

+	    }

+		

+	    /*************************ÅжÏдÈëµÄsecure flagÊÇ·ñÕýÈ·**************************/

+	    // ´Óotp¶ÁÈ¡

+	    memset(&otpInfo, 0, sizeof(otpInfo));

+	    if(ioctl(otp_fd , OTP_GET_DATA, &otpInfo)!= 0)

+	    {

+	        at_print(AT_ERR,"ioctl: OTP_GET_DATA fail.\n");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			close(otp_fd);

+			return AT_END;

+	    }

+

+	    if ((otpInfo.secureFlag&0xff) != secureFlag_otp)

+	    {

+	        at_print(AT_ERR, "Security flag(%#08X) is not consistent!\n", otpInfo.secureFlag);

+	        *res_msg = at_err_build(ATERR_PROC_FAILED);

+	        *res_msglen = strlen(*res_msg);

+			close(otp_fd);

+	        return AT_END;

+	    }

+

+		#endif

+

+	    *res_msg = at_query_result_build("write security infomation", NULL);

+	    *res_msglen = strlen(*res_msg);

+		close(otp_fd);

+	    return AT_END;

+     

+	}

 }

+

+int read_security_info(int at_fd, char *at_paras, void **res_msg, int *res_msglen)

+{

+    char strValue[16];

+    char strLog[256] = {0};

+    int i;

+	int ret = 0;

+	T_ZDrvEfuse_Secure efuseInfo = {{0}};

+	int efuse_fd = -1;

+    

+	T_ZDrvOtp_Secure otpInfo = {{0}};

+	int otp_fd = -1;

+    int is_Enhanced_Security = -1;

+

+	is_Enhanced_Security = IsEnhancedSecurity();

+	at_print(AT_ERR,"is_Enhanced_Security = %d.\n",is_Enhanced_Security);

+	if(is_Enhanced_Security == -1)

+	{

+		at_print(AT_ERR,"IsEnhancedSecurity() fail.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		return AT_END;

+	}

+	

+    efuse_fd = open("/dev/efuse", O_RDWR);

+	if (efuse_fd < 0) 

+	{

+		at_print(AT_ERR,"open %s fail.\n","/dev/efuse");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		return AT_END;

+	}

+

+	at_print(AT_ERR,"open %s success.\n","/dev/efuse");

+

+	 // ´Óefuse¶ÁÈ¡

+    if(ioctl(efuse_fd , EFUSE_GET_DATA, &efuseInfo)!= 0)

+    {

+        at_print(AT_ERR,"ioctl: EFUSE_GET_DATA fail.\n");

+		*res_msg = at_err_build(ATERR_PROC_FAILED);

+		*res_msglen = strlen(*res_msg);

+		close(efuse_fd);

+		return AT_END;

+    }

+	else

+	{	

+	    at_print(AT_ERR,"ioctl: EFUSE_GET_DATA success.\n");

+		strLog[0] = '\0';

+		sprintf(strValue, "%02X,", efuseInfo.secureFlag&0xFF);

+		strcat(strLog, strValue);

+    	for (i = 0; i < sizeof(efuseInfo.pubKeyHash)/sizeof(UINT32); i++)

+    	{

+    	    sprintf(strValue, "%08lX", efuseInfo.pubKeyHash[i]);

+        	strcat(strLog, strValue);

+    	}

+		at_print(AT_ERR, "Secure Flag,Public key hash: %s\n", strLog);

+		close(efuse_fd);

+		if(is_Enhanced_Security == 0)

+		{

+			*res_msg = at_query_result_build("read security information", strLog);

+            *res_msglen = strlen(*res_msg);

+		    return AT_END;

+		}

+	} 

+

+	#if 1

+	

+    if(is_Enhanced_Security == 1)

+    {

+		otp_fd = open("/dev/otp", O_RDWR);

+		if (otp_fd < 0) 

+		{

+			at_print(AT_ERR,"open %s fail.\n","/dev/otp");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			return AT_END;

+		}

+

+		at_print(AT_ERR,"open %s success.\n","/dev/otp");

+

+		 // ´Óotp¶ÁÈ¡

+	    if(ioctl(otp_fd , OTP_GET_DATA, &otpInfo)!= 0)

+	    {

+	        at_print(AT_ERR,"ioctl: OTP_GET_DATA fail.\n");

+			*res_msg = at_err_build(ATERR_PROC_FAILED);

+			*res_msglen = strlen(*res_msg);

+			close(otp_fd);

+			return AT_END;

+	    }

+		else

+		{		

+			memset(strLog, 0, sizeof(strLog));

+			sprintf(strValue, "%02X,", efuseInfo.secureFlag&0xFF);

+			strcat(strLog, strValue);

+	    	for (i = 0; i < sizeof(otpInfo.pubKeyHash)/sizeof(UINT32); i++)

+	    	{

+	    	    sprintf(strValue, "%08lX", otpInfo.pubKeyHash[i]);

+	        	strcat(strLog, strValue);

+	    	}

+			at_print(AT_ERR, "Secure Flag,Public key hash: %s\n", strLog);

+			*res_msg = at_query_result_build("read security information", strLog);

+	        *res_msglen = strlen(*res_msg);

+			close(otp_fd);

+		    return AT_END;

+		} 

+    }

+	#endif

+	

+}

+

+

 /*

 int auth_device_key(int at_fd, char *at_paras,void ** res_msg, int *res_msglen)

 {

@@ -2130,5 +2674,7 @@
     register_serv_func2("zmode=",0,0,0,zmodeSet_act_func,NULL); 

 	//mdlÓû§Ä£Ê½ÇÐÑз¢Ä£Ê½¼øÈ¨AT+ZAUTH=KEY

 	//register_serv_func2("ZAUTH=",0,0,0,auth_device_key,NULL);

+    register_serv_func2("RSCYINFO",0,0,0,read_security_info,NULL);

+	

     return 0;

 }