blob: c4e843f122796f8563c31c44c4ce67d22ccf5c2c [file] [log] [blame]
/*
* drivers/usb/gadget/aml_tiny_usbtool/burn_func.c
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <common.h>
#include "usb_pcd.h"
#include <common.h>
#include <nand.h>
#include <div64.h>
#include <jffs2/jffs2.h>
//#include <asm/arch/nand.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <command.h>
#include <watchdog.h>
#include <malloc.h>
#include <linux/mtd/mtd.h>
#include <asm/byteorder.h>
//#include <amlogic/efuse.h>
#include <linux/string.h>
#include <usb.h>
//#define HDCP_PRINT
#define SECUKEY_BYTES 512
#define AML_KEY_NAMELEN 16
#define HDCP_KEY_LEN 288
#define HDCP2LC128_LEN 36
#define HDCP2KEY_LEN 862
#define HDCP2_KEY_TOTAL_LEN (HDCP2LC128_LEN+HDCP2KEY_LEN)
#define HDCP2LC128_NAME "hdcp2lc128"
#define HDCP2KEY_NAME "hdcp2key"
// pctool version >= 1.6.32,return 3 status when read
#define PCTOOL_VERSION_1632 (unsigned long)1632
static unsigned long sPctoolVersion = 0;
#ifdef WRITE_TO_EFUSE_ENABLE
#define WRITE_EFUSE 0
#define READ_EFUSE 1
#define EFUSE_VERSION_MESON3 "01:02:03"
#define EFUSE_VERSION_MESON6 "02"
#define EFUSE_READ_TEST_ENABLE 1
#ifdef CONFIG_AML_MESON3
extern int do_efuse_usb(int argc, char * const argv[], char *buf);
#elif defined(CONFIG_AML_MESON6)
extern int cmd_efuse(int argc, char * const argv[], char *buf);
#endif
#endif
extern int usb_get_update_result(void);
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE)
static int sInitedSecukey = 0;
extern int uboot_key_initial(char *device);
extern ssize_t uboot_get_keylist(char *keyname);
extern ssize_t uboot_key_read(char *keyname, char *keydata);
extern ssize_t uboot_key_write(char *keyname, char *keydata);
int ensure_secukey_init(void);
int cmd_secukey(int argc, char *argv[], char *buf);
#endif
#if defined(CONFIG_SECURE_STORAGE_BURNED)
#include <amlogic/secure_storage.h>
static int sInitedSecurestore = 0;
extern int securestore_key_init( char *seed,int len);
extern int securestore_key_query(char *keyname, unsigned int *query_return);
extern int securestore_key_read(char *keyname,char *keybuf,unsigned int keylen,unsigned int *reallen);
extern int securestore_key_write(char *keyname, char *keybuf,unsigned int keylen,int keytype);
extern int securestore_key_uninit(void);
int ensure_securestore_key_init(char *seed, int seed_len);
int cmd_securestore(int argc, char *argv[], char *buf);
#endif
void hdcpDataEncryption(const int len, const char *input, char *out);
void hdcpDataDecryption(const int len, const char *input, char *out);
extern void _mdelay(unsigned long ms);
extern void _udelay(unsigned int us);
/* hdcp key verify code */
#define DWORD unsigned int //4 bytes
#define BYTE unsigned char //1 byte
#define SHA1_MAC_LEN 20
typedef struct {
DWORD state[5];
DWORD count[2];
BYTE buffer[64];
} SHA1_CTX;
void SHA1Reset(SHA1_CTX *context);
void SHA1Input(SHA1_CTX *context, BYTE *data, DWORD len);
void SHA1Result(SHA1_CTX *context, BYTE *digest);//20
void SHA1Transform_H(DWORD *state, BYTE *buffer); //5 64
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#define blk0(i) (workspace[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
(rol(block->l[i], 8) & 0x00FF00FF))
#define blk(i) (workspace[i & 15] = rol(block->l[(i + 13) & 15] ^ \
block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) \
z += (((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5)); \
w = rol(w, 30);
#define R1(v,w,x,y,z,i) \
z += (((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5)); \
w = rol(w, 30);
#define R2(v,w,x,y,z,i) \
z += ((w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5)); w = rol(w, 30);
#define R3(v,w,x,y,z,i) \
z += ((((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5)); \
w = rol(w, 30);
#define R4(v,w,x,y,z,i) \
z += ((w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5)); \
w=rol(w, 30);
/*********************************************************************/
static int parse_line (char *line, char *argv[])
{
int nargs = 0;
#ifdef DEBUG_PARSER
printf ("parse_line: \"%s\"\n", line);
#endif
while (nargs < CONFIG_SYS_MAXARGS) {
/* skip any white space */
while ((*line == ' ') || (*line == '\t')) {
++line;
}
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
#ifdef DEBUG_PARSER
printf ("parse_line: nargs=%d\n", nargs);
#endif
return (nargs);
}
argv[nargs++] = line; /* begin of argument string */
/* find end of string */
while (*line && (*line != ' ') && (*line != '\t')) {
++line;
}
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
#ifdef DEBUG_PARSER
printf ("parse_line: nargs=%d\n", nargs);
#endif
return (nargs);
}
*line++ = '\0'; /* terminate current arg */
}
printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
#ifdef DEBUG_PARSER
printf ("parse_line: nargs=%d\n", nargs);
#endif
return (nargs);
}
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform_H(DWORD *state, BYTE *buffer)
{
DWORD a, b, c, d, e;
typedef union {
BYTE c[64];
DWORD l[16];
} CHAR64LONG16;
CHAR64LONG16 *block;
DWORD workspace[16];
block = (CHAR64LONG16 *)workspace;
memcpy(block, buffer, 64);
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);_udelay(100);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);_udelay(100);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);_udelay(100);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);_udelay(100);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);_udelay(100);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);_udelay(100);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);_udelay(100);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);_udelay(100);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);_udelay(100);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);_udelay(100);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);_udelay(100);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);_udelay(100);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);_udelay(100);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);_udelay(100);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);_udelay(100);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);_udelay(100);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);_udelay(100);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);_udelay(100);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);_udelay(100);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);_udelay(100);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
memset(block, 0, 64);
}
/* SHA1Reset - Initialize new context */
void SHA1Reset(SHA1_CTX *context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Input(SHA1_CTX* context, BYTE *_data, DWORD len)
{
DWORD i, j;
BYTE *data = _data;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3))
context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform_H(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform_H(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Result(SHA1_CTX *context, BYTE *digest)
{
DWORD i;
BYTE finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (BYTE)
((context->count[(i >= 4 ? 0 : 1)] >>
((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Input(context, (BYTE *) "\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Input(context, (BYTE *) "\0", 1);
}
SHA1Input(context, finalcount, 8); /* Should cause a SHA1Transform_H()
*/
for (i = 0; i < 20; i++) {
digest[i] = (BYTE)
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
255);
}
/* Wipe variables */
i = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(finalcount, 0, 8);
}
/**************************************************************************
* NOTES: Test Vectors (from FIPS PUB 180-1) to verify implementation
* 1- Input : "abc"
* Output : A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
* 2- Input : "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
* Output : 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
* 2- Input : A million repetitions of 'a' - not applied (memory shortage)
* Output : 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
* More test vectors can be obtained from FIPS web site
***************************************************************************/
void SHA1_Perform(BYTE *indata, DWORD inlen, BYTE *outdata) //calculate SHA-1 API
{
SHA1_CTX sha;
SHA1Reset(&sha);
SHA1Input(&sha, indata, inlen);
SHA1Result(&sha, outdata);
}
typedef struct
{
unsigned char ksv[5];
unsigned char rsv[3];
unsigned char dpk[280];
unsigned char sha[20];
}hdcp_llc_file;
#if defined(WRITE_TO_EFUSE_ENABLE)
static int _cmd_efuse(int argc, char * const argv[], char *buf)
{
int i, action = -1;
efuseinfo_item_t info;
char *title;
char *s;
char *end;
if (!strncmp(argv[1], "read", 4))
action = READ_EFUSE;
else if(!strncmp(argv[1], "write", 5))
action = WRITE_EFUSE;
else {
printf("%s arg error\n", argv[1]);
return -1;
}
//efuse read
if (action == READ_EFUSE) {
title = argv[2];
if (efuse_getinfo(title, &info) < 0)
return -1;
memset(buf, 0, EFUSE_BYTES);
efuse_read_usr(buf, info.data_len, (loff_t *)&info.offset);
printf("info.data_len=%d\n", info.data_len);
printf("%s is:\n", title);
for (i=0; i<(info.data_len); i++)
printf("%02x:", buf[i]);
printf("\n");
}
//efuse write
else if(action == WRITE_EFUSE) {
if (argc < 4) {
printf("arg count error\n");
return -1;
}
title = argv[2];
if (efuse_getinfo(title, &info) < 0)
return -1;
if (!(info.we)) {
printf("%s write unsupport now. \n", title);
return -1;
}
memset(buf, 0, info.data_len);
s = argv[3];
//for usb burn key to efuse
if (!strncmp(title, "usid", strlen("usid"))) //burn usid data(format:"xxxx...", it's string)
memcpy(buf, s, strlen(s));
else if(!strncmp(title, "hdcp", strlen("hdcp"))) //burn hdcp data(format:xx xx, it's data)
memcpy(buf, s, HDCP_KEY_LEN);
else { //burn version, mac, mac_bt, mac_wifi, customerid(format:"xx:xx:xx...", it's string)
for (i=0; i<info.data_len; i++) {
buf[i] = s ? simple_strtoul(s, &end, 16) : 0;
if (s)
s = (*end) ? end+1 : end;
}
if (*s) {
printf("error: The wriiten data length is too large.\n");
return -1;
}
}
if (efuse_write_usr(buf, info.data_len, (loff_t*)&info.offset) < 0) {
printf("error: efuse write fail.\n");
return -1;
}
else
printf("%s written done.\n", info.title);
}
else {
printf("arg error\n");
return -1;
}
return 0;
}
static int run_efuse_cmd(int argc, char *argv[], char *buff)
{
int ret = -1;
#ifdef CONFIG_AML_MESON3
ret = do_efuse_usb(argc, argv, buff);
#elif defined(CONFIG_AML_MESON6)
//ret = cmd_efuse(argc, argv, buff);
ret = _cmd_efuse(argc, argv, buff);
#endif
return ret;
}
#if defined(EFUSE_READ_TEST_ENABLE)
static int test_efuse_read(int argc, char *argv[], char *cmpBuff)
{
int i = 0, j = 0, ret = -1;
int hdcp_flag = 0, hdcp_key_len = 288;
char *hdcp = NULL;
char efuse_data[SECUKEY_BYTES], reBuff[SECUKEY_BYTES], tmpBuf[SECUKEY_BYTES];
printf("-----Test efuse read commond:\n");
for (i=0; i<argc; i++)
printf("argv[%d]=%s\n", i, argv[i]);
if (!strncmp(argv[0], "efuse", 5) && !strncmp(argv[1], "read", 4) &&
(!strncmp(argv[2], "version", 7) ||!strncmp(argv[2], "mac_wifi", 8) ||
!strncmp(argv[2], "mac_bt", 6) ||!strncmp(argv[2], "mac", 3) ||
!strncmp(argv[2], "usid", 4) ||!strncmp(argv[2], "hdcp", 4))) {
goto run;
}
else {
printf("test efuse read commond not mach\n");
return -3;
}
run:
memset(efuse_data, 0, sizeof(efuse_data));
memset(reBuff, 0, sizeof(reBuff));
memset(tmpBuf, 0, sizeof(tmpBuf));
ret = run_efuse_cmd(argc, argv, reBuff);
if (!ret) {
// test efuse read version
if (!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "version", strlen("version"))) {
#ifdef CONFIG_AML_MESON3
sprintf(efuse_data, "%02x:%02x:%02x", reBuff[0], reBuff[1], reBuff[2]);
#elif defined(CONFIG_AML_MESON6)
sprintf(efuse_data, "%02x", reBuff[0]);
#endif
if (!strncmp(efuse_data, cmpBuff, strlen(cmpBuff))) {
printf("test efuse read version success,read version=%s\n", efuse_data);
return 0;
}
else {
printf("test efuse read version success,read version=%s, but not mach %s\n", efuse_data, cmpBuff);
return -1;
}
}
// test efuse read mac/mac_bt/mac_wifi
else if(!strncmp(argv[1], "read", strlen("read")) && (!strncmp(argv[2], "mac", strlen("mac")) ||
!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")))) {
sprintf(efuse_data, "%02x:%02x:%02x:%02x:%02x:%02x", reBuff[0], reBuff[1], reBuff[2], reBuff[3], reBuff[4], reBuff[5]);
if (!strncmp(efuse_data, cmpBuff, strlen(cmpBuff))) {
printf("test efuse read %s success,read %s=%s\n", argv[2], argv[2], efuse_data);
return 0;
}
else {
printf("test efuse read %s success,read %s=%s, but not mach %s\n", argv[2], argv[2], efuse_data, cmpBuff);
return -1;
}
}
// test efuse read usid
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "usid", strlen("usid"))) {
for (i=0; i<strlen(cmpBuff); i++) {
sprintf(tmpBuf, "%c", reBuff[i]);
sprintf(&efuse_data[j], "%s", tmpBuf);
j += strlen(tmpBuf);
memset(tmpBuf, 0, sizeof(tmpBuf));
}
if (!strncmp(efuse_data, cmpBuff, strlen(cmpBuff))) {
printf("test efuse read usid success,read usid=%s\n", efuse_data);
return 0;
}
else {
printf("test efuse read usid success,read usid=%s, but not mach %s\n", efuse_data, cmpBuff);
return -1;
}
}
// test efuse read hdcp
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
hdcp = cmpBuff;
for (i=0; i<hdcp_key_len; i++) {
if (reBuff[i] != *hdcp ++) {
hdcp_flag = 1;
break;
}
}
if (!hdcp_flag) {
printf("test efuse read hdcp success\n");
printf("read hdcp is:\n");
for (i=0; i<hdcp_key_len; i++)
printf("%02x:", reBuff[i]);
printf("\n");
return 0;
}
else {
printf("test efuse read hdcp success,but not mach\n");
return -1;
}
}
}
else {
printf("test efuse read %s fail\n", argv[2]);
return -2;
}
return ret;
}
#endif /* EFUSE_READ_TEST_ENABLE */
#endif /* WRITE_TO_EFUSE_ENABLE */
int burn_board(const char *dev, void *mem_addr, u64 offset, u64 size)
{
char str[128];
printf("burn_board!!!\n");
printf("CMD: dev=%s, mem_addr=0x%llx, offset=0x%llx, size=0x%llx\n", dev, (unsigned long long)mem_addr, offset, size);
if (!strncmp("nand", (const char *)(unsigned long long)(*dev), 4))
{
sprintf(str, "nand erase 0x%llx 0x%llx}", offset, size);
printf("command: %s\n", str);
run_command(str, 0);
sprintf(str, "nand write 0x%llx 0x%llx 0x%llx}", (unsigned long long)mem_addr, offset, size);
printf("command: %s\n", str);
run_command(str, 0);
}
else if(!strncmp("spi", (const char *)(unsigned long long)(*dev), 3))
{
run_command("sf probe 2", 0);
sprintf(str, "sf erase 0x%llx 0x%llx}", offset, size);
printf("command: %s\n", str);
run_command(str, 0);
sprintf(str, "sf write 0x%llx 0x%llx 0x%llx}", (unsigned long long)mem_addr, offset, size);
printf("command: %s\n", str);
run_command(str, 0);
}
else if(!strncmp("emmc", (const char *)(unsigned long long)(*dev), 4))
{
sprintf(str, "mmc write 1 0x%llx 0x%llx 0x%llx}", (unsigned long long)mem_addr, offset, size);
printf("command: %s\n", str);
run_command(str, 0);
}
else
{
printf("Invalid Argument!\n");
return -1;
}
return 0;
}
static int usb_bootm(const void *addr)
{
char cmd[128];
memset(cmd, 0, sizeof(cmd));
sprintf(cmd, "bootm %llx", (unsigned long long)addr);
return run_command(cmd, 0);
}
u32 checkcum_32(const unsigned char *buf, u32 len)
{
u32 fake_len, chksum = 0;
u32 *ptr = (u32 *)buf;
int i;
printf("buf=0x%08llx, len=0x%x\n", (unsigned long long)buf, len);
if (len%4)
{
fake_len = len - len%4 + 4;
memset((void *)(buf+len), 0, (fake_len-len));
}
else
{
fake_len = len;
}
printf("fake_len=0x%x\n", fake_len);
for (i=0; i<fake_len; i+=4, ptr++)
{
chksum += *ptr;
}
return chksum;
}
int usb_run_command (const char *cmd, char* buff)
{
int ret = -1, flag = 0;
u64 addr = 0, length = 0;
u32 crc_value, crc_verify = 0;
int argc;
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
printf("\n\n---Tool cmd: %s\n", cmd);
memset(buff, 0, CMD_BUFF_SIZE);
if (strncmp(cmd,"get update result",(sizeof("get update result")-1)) == 0) {
ret = usb_get_update_result();
if (!ret)
{
strcpy(buff, "success");
}
else
{
strcpy(buff, "fail");
}
return ret;
}
else if(strncmp(cmd,"usb_bootm",(sizeof("usb_bootm")-1)) == 0){
addr = *((u32*)(&cmd[60]));
strcpy(buff, "okay");
usb_bootm((const void *)addr);
strcpy(buff, "fail");
return -1;
}
else if(strncmp(cmd,"crc",(sizeof("crc")-1)) == 0){
if ((argc = parse_line ((char *)cmd, argv)) == 0) {
return -1; /* no command at all */
}
addr = simple_strtoul (argv[1], NULL, 16);
length = simple_strtoul (argv[2], NULL, 10);
crc_verify = simple_strtoul (argv[3], NULL, 16);
//crc_value = crc32 (0, (const uchar *) addr, length);
crc_value = checkcum_32((const unsigned char *)addr, length);
printf("crc_value=0x%x\n", crc_value);
if (crc_verify == crc_value)
{
strcpy(buff, "success");
}
else
{
strcpy(buff, "failed");
}
}
else if(strncmp(cmd,"cmd_in_mem",(sizeof("cmd_in_mem")-1)) == 0){
char *cmd_in_mem = NULL;
/* Extract arguments */
if ((argc = parse_line ((char *)cmd, argv)) == 0) {
return -1; /* no command at all */
}
cmd_in_mem = (char *)simple_strtoul(argv[1], NULL, 0);
printf("cmd_in_mem: %s\n", cmd_in_mem);
if (run_command(cmd_in_mem, flag))
{
strcpy(buff, "fail");
return -1;
}
else
{
strcpy(buff, "okay");
}
}
/*
* pctool version >= 1.6.32,teturn 3 status in read
* "pctool version:"
*
* burn keys to efuse/nand/emmc common command:
* "efuse read version"
* "efuse write version"
* "efuse read mac"
* "efuse write mac xx:xx:xx:xx:xx:xx"
* "efuse read bt_mac"
* "efuse write bt_mac xx:xx:xx:xx:xx:xx"
* "efuse read wifi_mac"
* "efuse write wifi_mac xx:xx:xx:xx:xx:xx"
* "efuse read usid"
* "efuse write usid xxxxx..."
* "read hdcp"
* "write hdcp:" (hdcp key datas form 0x82000000 address)
* "read hdcp2"
* "write hdcp2:" (hdcp2 key datas form 0x82000000 address)
*
* or: burn keys to efuse/nand private command:
* "secukey_efuse/secukey_nand read version"
* "secukey_efuse/secukey_nand write version"
* "secukey_efuse/secukey_nand read mac"
* "secukey_efuse/secukey_nand write mac xx:xx:xx:xx:xx:xx"
* "secukey_efuse/secukey_nand read bt_mac"
* "secukey_efuse/secukey_nand write bt_mac xx:xx:xx:xx:xx:xx"
* "secukey_efuse/secukey_nand read wifi_mac"
* "secukey_efuse/secukey_nand write wifi_mac xx:xx:xx:xx:xx:xx"
* "secukey_efuse/secukey_nand read usid"
* "secukey_efuse/secukey_nand write usid xxxxx..."
* "secukey_efuse/secukey_nand read hdcp"
* "secukey_efuse/secukey_nand write hdcp:" (hdcp key datas form 0x82000000 address)
* "secukey_nand read boardid"
* "secukey_nand write boardid:" (boardid key datas form 0x82000000 address)
* "secukey_nand read serialno"
* "secukey_nand write serialno:" (serialno key datas form 0x82000000 address)
* "secukey_nand read MFG_Serialno"
* "secukey_nand write MFG_Serialno:" (MFG_Serialno key datas form 0x82000000 address)
*
* // for key to securestorage
* "efuse write random" (random datas form 0x82000000 address)
* "efuse read widevinekeybox"
* "efuse write widevinekeybox" (widevinekeybox datas form 0x82000000 address)
* "efuse read PlayReadykeybox"
* "efuse write PlayReadykeybox" (PlayReadykeybox datas form 0x82000000 address)
* "efuse read MobiDRMPrivate"
* "efuse write MobiDRMPrivate" (MobiDRMPrivate datas form 0x82000000 address)
* "efuse read MobiDRMPublic"
* "efuse write MobiDRMPublic" (MobiDRMPublic datas form 0x82000000 address)
*
**/
else if(!strncmp(cmd, "pctool version:", strlen("pctool version:")) ||!strncmp(cmd, "efuse", strlen("efuse")) ||
!strncmp(cmd, "read hdcp2", strlen("read hdcp2")) ||!strncmp(cmd, "write hdcp2:", strlen("write hdcp2:")) ||
!strncmp(cmd, "read hdcp", strlen("read hdcp")) ||!strncmp(cmd, "write hdcp:", strlen("write hdcp:")) ||
!strncmp(cmd, "secukey_efuse", strlen("secukey_efuse")) ||!strncmp(cmd, "secukey_nand", strlen("secukey_nand"))) {
int i = 0, key_device_index = -1, random_len = 0;
char widevinekeybox_verify_data_receive[20], widevinekeybox_verify_data_calculate[20];
char PlayReadykeybox_verify_data_receive[20], PlayReadykeybox_verify_data_calculate[20];
char MobiDRMPrivate_verify_data_receive[20], MobiDRMPrivate_verify_data_calculate[20];
char MobiDRMPublic_verify_data_receive[20], MobiDRMPublic_verify_data_calculate[20];
char key_data[SECUKEY_BYTES], hdcp_verify_data_receive[20], hdcp_verify_data_calculate[20];
char hdcp2lc128[HDCP2LC128_LEN], hdcp2key[HDCP2KEY_LEN], hdcp2TotalData[HDCP2_KEY_TOTAL_LEN];
char hdcp2_verify_data_receive[20], hdcp2_verify_data_calculate[20];
char *random = NULL;
enum {
RANDOM_MAX_LEN = 32,
WIDEVINEKEYBOX_MAX_LEN = 128,
PLAYREADYKEYBOX_MAX_LEN = 16*1024, // max:16k
MOBIDRMPRIVATE_MAX_LEN = 1200,
MOBIDRMPUBLIC_MAX_LEN = 300,
};
//added to remover warnning
if (!strncmp(cmd, "pctool version:", strlen("pctool version:"))) {
sPctoolVersion = simple_strtoul((char *)(cmd+strlen("pctool version:")), 0, 10);
sprintf(buff, "success:(sPctoolVersion:%d)", (int)sPctoolVersion);
printf("%s\n", buff);
return 0;
}
/* Extract arguments */
if (!strncmp(cmd, "read hdcp2", 10) || !strncmp(cmd, "write hdcp2:", 12)) {
char cmd_hdcp2[50] = {0};
strncpy(cmd_hdcp2, cmd, strlen(cmd));
sprintf((char *)cmd, "%s %s", "flash", cmd_hdcp2); // add parameter for hdcp2 command
printf("Actual cmd:%s\n", cmd);
}
else if(!strncmp(cmd, "read hdcp", 9) || !strncmp(cmd, "write hdcp:", 11)) {
char cmd_hdcp[50] = {0};
strncpy(cmd_hdcp, cmd, strlen(cmd));
sprintf((char *)cmd, "%s %s", "efuse", cmd_hdcp); // add parameter for hdcp command
printf("Actual cmd:%s\n", cmd);
}
if ((argc = parse_line ((char *)cmd, argv)) == 0) {
return -1; /* no command at all */
}
memset(key_data, 0, sizeof(key_data));
memset(hdcp_verify_data_receive, 0, sizeof(hdcp_verify_data_receive));
memset(hdcp_verify_data_calculate, 0, sizeof(hdcp_verify_data_calculate));
memset(hdcp2lc128, 0, sizeof(hdcp2lc128));
memset(hdcp2key, 0, sizeof(hdcp2key));
memset(hdcp2TotalData, 0, sizeof(hdcp2TotalData));
memset(hdcp2_verify_data_receive, 0, sizeof(hdcp2_verify_data_receive));
memset(hdcp2_verify_data_calculate, 0, sizeof(hdcp2_verify_data_calculate));
memset(widevinekeybox_verify_data_receive, 0, sizeof(widevinekeybox_verify_data_receive));
memset(widevinekeybox_verify_data_calculate, 0, sizeof(widevinekeybox_verify_data_calculate));
memset(PlayReadykeybox_verify_data_receive, 0, sizeof(PlayReadykeybox_verify_data_receive));
memset(PlayReadykeybox_verify_data_calculate, 0, sizeof(PlayReadykeybox_verify_data_calculate));
memset(MobiDRMPrivate_verify_data_receive, 0, sizeof(MobiDRMPrivate_verify_data_receive));
memset(MobiDRMPrivate_verify_data_calculate, 0, sizeof(MobiDRMPrivate_verify_data_calculate));
memset(MobiDRMPublic_verify_data_receive, 0, sizeof(MobiDRMPublic_verify_data_receive));
memset(MobiDRMPublic_verify_data_calculate, 0, sizeof(MobiDRMPublic_verify_data_calculate));
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE) || defined(WRITE_TO_EFUSE_ENABLE)
char* hdcp = NULL;
#endif
/* Burn key to efuse */
/* ---Command process */
#ifdef WRITE_TO_EFUSE_ENABLE
if (strncmp(argv[0], "efuse", strlen("efuse")) && strncmp(argv[0], "secukey_efuse", strlen("secukey_efuse"))) {
sprintf(buff, "%s", "failed:(code compiled burn to efuse,but cmd not mach with pc send)");
printf("%s\n", buff);
return -1;
}
printf("burn key to efuse. convert command...\n");
if (!strncmp(argv[0], "secukey_efuse", strlen("secukey_efuse")))
argv[0] = "efuse";
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "version", strlen("version"))) {
argc ++;
#ifdef CONFIG_AML_MESON3
argv[3] = EFUSE_VERSION_MESON3;
printf("CONFIG_AML_MESON3 VERSION(version:%s)\n",argv[3]);
#elif defined(CONFIG_AML_MESON6)
argv[3] = EFUSE_VERSION_MESON6;
printf("CONFIG_AML_MESON6 VERSION(version:%s)\n",argv[3]);
#endif
}
if (!strncmp(argv[2], "bt_mac", strlen("bt_mac")))
strncpy(argv[2], "mac_bt", strlen("mac_bt"));
if (!strncmp(argv[2], "wifi_mac", strlen("wifi_mac")))
strncpy(argv[2], "mac_wifi", strlen("mac_wifi"));
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp:", strlen("hdcp:"))) {
#define HDCP_DATA_ADDR (volatile unsigned long *)(0x82000000) //get hdcp data from address:0x82000000
hdcp = (char *)HDCP_DATA_ADDR;
printf("receive %d hdcp key datas from address:0x82000000:\n", HDCP_KEY_LEN);
for (i=0; i<HDCP_KEY_LEN; i++) { //read 288 hdcp datas
key_data[i] = *hdcp++;
printf("%.2x:", key_data[i]);
}
printf("\nreceive 20 hdcp key verify datas:\n");
for (i=0; i<20; i++) { //read 20 hdcp verify datas
hdcp_verify_data_receive[i] = *hdcp++;
printf("%.2x:", hdcp_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d hdcp key datas...\n", HDCP_KEY_LEN);
SHA1_Perform(key_data, HDCP_KEY_LEN, hdcp_verify_data_calculate);
printf("verify & get 20 hdcp verify datas:\n");
for (i=0; i<20; i++)
printf("%.2x:", hdcp_verify_data_calculate[i]);
printf("\n");
int ret = memcmp(hdcp_verify_data_receive, hdcp_verify_data_calculate, 20);
if (ret == 0) {
printf("hdcp datas verify success\n");
argv[0] = "efuse";
argv[1] = "write";
argv[2] = "hdcp";
argv[3] = key_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(hdcp datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
#endif /* WRITE_TO_EFUSE_ENABLE */
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE)
char* hdcp2 = NULL;
#endif
/* Burn key to nand/emmc */
/* ---Command process */
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE)
if (strncmp(argv[0], "efuse", strlen("efuse")) && strncmp(argv[0], "secukey_nand", strlen("secukey_nand")) &&
strncmp(argv[0], "flash", strlen("flash"))) {
sprintf(buff, "%s", "failed:(code compiled burn to flash,but cmd not mach with pc send)");
printf("%s\n", buff);
return -1;
}
printf("burn key to flash. convert command...\n");
if (!strncmp(argv[0], "efuse", strlen("efuse"))||!strncmp(argv[0], "secukey_nand", strlen("secukey_nand")))
argv[0] = "flash";
if (!strncmp(argv[2], "bt_mac", strlen("bt_mac")))
strncpy(argv[2], "mac_bt", strlen("mac_bt"));
if (!strncmp(argv[2], "wifi_mac", strlen("wifi_mac")))
strncpy(argv[2], "mac_wifi", strlen("mac_wifi"));
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp2:", strlen("hdcp2:"))) {
#define HDCP2_DATA_ADDR (volatile unsigned long *)(0x82000000)
hdcp2 = (char *)HDCP2_DATA_ADDR;
printf("receive %d %s datas from address:0x82000000:\n", HDCP2LC128_LEN, HDCP2LC128_NAME);
memcpy((char *)hdcp2lc128, (char *)hdcp2, HDCP2LC128_LEN);
#ifdef HDCP_PRINT
for (i=0; i<HDCP2LC128_LEN; i++) {
printf("%.2x:", hdcp2lc128[i]);
}
printf("\n");
#else
printf("receive %d %s datas ok !!!\n", HDCP2LC128_LEN, HDCP2LC128_NAME);
#endif
printf("receive %d %s datas from address:0x82000024:\n", HDCP2KEY_LEN, HDCP2KEY_NAME);
memcpy((char *)hdcp2key, (char *)(hdcp2+HDCP2LC128_LEN), HDCP2KEY_LEN);
#ifdef HDCP_PRINT
for (i=0; i<HDCP2KEY_LEN; i++) {
printf("%.2x:", hdcp2key[i]);
}
printf("\n");
#else
printf("receive %d %s datas ok !!!\n", HDCP2KEY_LEN, HDCP2KEY_NAME);
#endif
printf("receive 20 hdcp2(%s & %s) verify datas:\n", HDCP2LC128_NAME, HDCP2KEY_NAME);
memcpy((char *)hdcp2_verify_data_receive, (char *)(hdcp2+HDCP2_KEY_TOTAL_LEN), 20);
for (i=0; i<20; i++) {
printf("%.2x:", hdcp2_verify_data_receive[i]);
}
printf("\nstart to verify %d hdcp2(%s & %s) datas...\n", HDCP2_KEY_TOTAL_LEN, HDCP2LC128_NAME, HDCP2KEY_NAME);
memcpy((char *)hdcp2TotalData, (char *)hdcp2lc128, HDCP2LC128_LEN);
memcpy((char *)(hdcp2TotalData+HDCP2LC128_LEN), (char *)hdcp2key, HDCP2KEY_LEN);
SHA1_Perform((unsigned char *)hdcp2TotalData, HDCP2_KEY_TOTAL_LEN, (unsigned char *)hdcp2_verify_data_calculate);
printf("verify & get 20 hdcp2(%s & %s) verify datas:\n", HDCP2LC128_NAME, HDCP2KEY_NAME);
for (i=0; i<20; i++)
printf("%.2x:", hdcp2_verify_data_calculate[i]);
printf("\n");
ret = memcmp(hdcp2_verify_data_receive, hdcp2_verify_data_calculate, 20);
if (ret == 0) {
printf("hdcp2(%s & %s) datas verify success\n", HDCP2LC128_NAME, HDCP2KEY_NAME);
argv[0] = "flash";
argv[1] = "write";
argv[2] = "hdcp2";
argv[3] = hdcp2TotalData;
argc = 4;
}
else {
sprintf(buff, "failed:(hdcp2<%s & %s> datas verify failed)", HDCP2LC128_NAME, HDCP2KEY_NAME);
printf("%s\n", buff);
return -1;
}
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp:", strlen("hdcp:"))) {
#define HDCP_DATA_ADDR (volatile unsigned long *)(0x82000000)
hdcp = (char *)HDCP_DATA_ADDR;
printf("receive %d hdcp key datas from address:0x82000000:\n", HDCP_KEY_LEN);
for (i=0; i<HDCP_KEY_LEN; i++) {
key_data[i] = *hdcp++;
#ifdef HDCP_PRINT
printf("%.2x:", key_data[i]);
#endif
}
printf("\nreceive %d hdcp datas ok !!!\n", HDCP_KEY_LEN);
printf("receive 20 hdcp key verify datas:\n");
for (i=0; i<20; i++) {
hdcp_verify_data_receive[i] = *hdcp++;
printf("%.2x:", hdcp_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d hdcp key datas...\n", HDCP_KEY_LEN);
SHA1_Perform((unsigned char *)key_data, HDCP_KEY_LEN, (unsigned char *)hdcp_verify_data_calculate);
printf("verify & get 20 hdcp verify datas:\n");
for (i=0; i<20; i++)
printf("%.2x:", hdcp_verify_data_calculate[i]);
printf("\n");
ret = memcmp(hdcp_verify_data_receive, hdcp_verify_data_calculate, 20);
if (ret == 0) {
printf("hdcp datas verify success\n");
argv[0] = "flash";
argv[1] = "write";
argv[2] = "hdcp";
argv[3] = key_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(hdcp datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "boardid:", strlen("boardid:"))) {
#define BOARDID_DATA_ADDR (volatile unsigned long *)(0x82000000)//get boardid data from address:0x82000000
char length[4] = {0};
char* boardid = (char *)BOARDID_DATA_ADDR;
for (i=0; i<4; i++) {
length[i] = *boardid++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int boardid_key_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
printf("boardid_key_len=%d(maximum length limit is %d)\n", boardid_key_len, SECUKEY_BYTES);
memcpy(key_data, boardid, boardid_key_len);
printf("receive %d boardid key datas from address:0x82000000:\n%s\n", boardid_key_len, key_data);
argv[0] = "flash";
argv[1] = "write";
argv[2] = "boardid";
argv[3] = key_data;
argc = 4;
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "serialno:", strlen("serialno:"))) {
#define SERIALNO_DATA_ADDR (volatile unsigned long *)(0x82000000)//get serialno data from address:0x82000000
char length[4] = {0};
char* serialno = (char *)SERIALNO_DATA_ADDR;
for (i=0; i<4; i++) {
length[i] = *serialno++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int serialno_key_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
printf("serialno_key_len=%d(maximum length limit is %d)\n", serialno_key_len, SECUKEY_BYTES);
memcpy(key_data, serialno, serialno_key_len);
printf("receive %d serialno key datas from address:0x82000000:\n%s\n", serialno_key_len, key_data);
argv[0] = "flash";
argv[1] = "write";
argv[2] = "serialno";
argv[3] = key_data;
argc = 4;
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MFG_Serialno:", strlen("MFG_Serialno:"))) {
#define MFG_SERIALNO_DATA_ADDR (volatile unsigned long *)(0x82000000)//get MFG_Serialno data from address:0x82000000
char length[4] = {0};
char* MFG_Serialno = (char *)MFG_SERIALNO_DATA_ADDR;
for (i=0; i<4; i++) {
length[i] = *MFG_Serialno++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int MFG_Serialno_key_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
printf("MFG_Serialno_key_len=%d(maximum length limit is %d)\n", MFG_Serialno_key_len, SECUKEY_BYTES);
memcpy(key_data, MFG_Serialno, MFG_Serialno_key_len);
printf("receive %d MFG_Serialno key datas from address:0x82000000:\n%s\n", MFG_Serialno_key_len, key_data);
argv[0] = "flash";
argv[1] = "write";
argv[2] = "MFG_Serialno";
argv[3] = key_data;
argc = 4;
}
#endif /* WRITE_TO_NAND_EMMC_ENABLE || WRITE_TO_NAND_ENABLE */
#ifdef CONFIG_SECURE_STORAGE_BURNED
int widevinekeybox_len=0, PlayReadykeybox_len=0, MobiDRMPublic_len=0, MobiDRMPrivate_len=0;
#endif
/* Burn key to securestorage */
/* ---Command process */
#if defined(CONFIG_SECURE_STORAGE_BURNED)
if (!strncmp(argv[2], "random", strlen("random")) || !strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox")) ||
!strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox")) || !strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate")) ||
!strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic"))) {
argv[0] = "securestorage";
printf("burn key to %s. convert command...\n", argv[0]);
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "random", strlen("random"))) {
#define RANDOM_DATA_ADDR (volatile unsigned long *)(0x82000000)//get random data from address:0x82000000
random = (char *)RANDOM_DATA_ADDR;
char length[4] = {0}, random_data[RANDOM_MAX_LEN] = {0};
for (i=0; i<4; i++) {
length[i] = *random++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
random_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
if (random_len > RANDOM_MAX_LEN || random_len <= 0) {
sprintf(buff, "random_len=%d(maximum length limit is %d)", random_len, RANDOM_MAX_LEN);
printf("%s\n", buff);
return -1;
}
printf("receive %d random datas from address:0x82000000:\n", random_len);
memcpy((char *)random_data, (char *)random, random_len);
for (i=0; i<random_len; i++) {
printf("%02x:", random_data[i]);
}
printf("\n");
argv[3] = random_data;
argc = 4;
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox"))) {
#define WIDEVINE_KEYBOX_DATA_ADDR (volatile unsigned long *)(0x82000000)//get widevinekeybox data from address:0x82000000
char* widevinekeybox = (char *)WIDEVINE_KEYBOX_DATA_ADDR;
char length[4] = {0}, widevinekeybox_data[WIDEVINEKEYBOX_MAX_LEN] = {0};
for (i=0; i<4; i++) {
length[i] = *widevinekeybox++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int widevinekeybox_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
if (widevinekeybox_len > WIDEVINEKEYBOX_MAX_LEN || widevinekeybox_len <= 0) {
sprintf(buff, "widevinekeybox_len=%d(maximum length limit is %d)", widevinekeybox_len, WIDEVINEKEYBOX_MAX_LEN);
printf("%s\n", buff);
return -1;
}
printf("receive %d widevinekeybox datas from address:0x82000000:\n", widevinekeybox_len);
memcpy((char *)widevinekeybox_data, (char *)widevinekeybox, widevinekeybox_len);
#ifdef KEYBOX_PRINT
for (i=0; i<widevinekeybox_len; i++) {
printf("%02x:", widevinekeybox_data[i]);
}
#else
printf("receive %d widevinekeybox datas ok !!!", widevinekeybox_len);
#endif
printf("\nreceive 20 widevinekeybox verify datas:\n");
memcpy((char *)widevinekeybox_verify_data_receive, (char *)(widevinekeybox+widevinekeybox_len), 20);
for (i=0; i<20; i++) {
printf("%02x:", widevinekeybox_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d widevinekeybox datas...\n", widevinekeybox_len);
SHA1_Perform((unsigned char *)widevinekeybox_data, widevinekeybox_len, (unsigned char *)widevinekeybox_verify_data_calculate);
printf("verify & get 20 widevinekeybox verify datas:\n");
for (i=0; i<20; i++)
printf("%02x:", widevinekeybox_verify_data_calculate[i]);
printf("\n");
ret = memcmp(widevinekeybox_verify_data_receive, widevinekeybox_verify_data_calculate, 20);
if (ret == 0) {
printf("widevinekeybox datas verify success\n");
argv[3] = widevinekeybox_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(widevinekeybox datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox"))) {
#define PLAYREADY_KEYBOX_DATA_ADDR (volatile unsigned long *)(0x82000000)//get PlayReadykeybox data from address:0x82000000
char* PlayReadykeybox = (char *)PLAYREADY_KEYBOX_DATA_ADDR;
char length[4] = {0}, PlayReadykeybox_data[PLAYREADYKEYBOX_MAX_LEN] = {0};
for (i=0; i<4; i++) {
length[i] = *PlayReadykeybox++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int PlayReadykeybox_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
if (PlayReadykeybox_len > PLAYREADYKEYBOX_MAX_LEN || PlayReadykeybox_len <= 0) {
sprintf(buff, "PlayReadykeybox_len=%d(maximum length limit is %d)", PlayReadykeybox_len, PLAYREADYKEYBOX_MAX_LEN);
printf("%s\n", buff);
return -1;
}
printf("receive %d PlayReadykeybox datas from address:0x82000000:\n", PlayReadykeybox_len);
memcpy((char *)PlayReadykeybox_data, (char *)PlayReadykeybox, PlayReadykeybox_len);
#ifdef KEYBOX_PRINT
for (i=0; i<PlayReadykeybox_len; i++) {
printf("%02x:", PlayReadykeybox_data[i]);
}
#else
printf("receive %d PlayReadykeybox datas ok !!!", PlayReadykeybox_len);
#endif
printf("\nreceive 20 PlayReadykeybox verify datas:\n");
memcpy((char *)PlayReadykeybox_verify_data_receive, (char *)(PlayReadykeybox+PlayReadykeybox_len), 20);
for (i=0; i<20; i++) {
printf("%02x:", PlayReadykeybox_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d PlayReadykeybox datas...\n", PlayReadykeybox_len);
SHA1_Perform((unsigned char *)PlayReadykeybox_data, PlayReadykeybox_len, (unsigned char *)PlayReadykeybox_verify_data_calculate);
printf("verify & get 20 PlayReadykeybox verify datas:\n");
for (i=0; i<20; i++)
printf("%02x:", PlayReadykeybox_verify_data_calculate[i]);
printf("\n");
ret = memcmp(PlayReadykeybox_verify_data_receive, PlayReadykeybox_verify_data_calculate, 20);
if (ret == 0) {
printf("PlayReadykeybox datas verify success\n");
argv[3] = PlayReadykeybox_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(PlayReadykeybox datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate"))) {
#define MOBIDRMPRIVATE_DATA_ADDR (volatile unsigned long *)(0x82000000)//get MobiDRMPrivate data from address:0x82000000
char* MobiDRMPrivate = (char *)MOBIDRMPRIVATE_DATA_ADDR;
char length[4] = {0}, MobiDRMPrivate_data[MOBIDRMPRIVATE_MAX_LEN] = {0};
for (i=0; i<4; i++) {
length[i] = *MobiDRMPrivate++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
MobiDRMPrivate_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
if (MobiDRMPrivate_len > MOBIDRMPRIVATE_MAX_LEN || MobiDRMPrivate_len <= 0) {
sprintf(buff, "MobiDRMPrivate_len=%d(maximum length limit is %d)", MobiDRMPrivate_len, MOBIDRMPRIVATE_MAX_LEN);
printf("%s\n", buff);
return -1;
}
printf("receive %d MobiDRMPrivate datas from address:0x82000000:\n", MobiDRMPrivate_len);
memcpy((char *)MobiDRMPrivate_data, (char *)MobiDRMPrivate, MobiDRMPrivate_len);
#ifdef KEYBOX_PRINT
for (i=0; i<MobiDRMPrivate_len; i++) {
printf("%02x:", MobiDRMPrivate_data[i]);
}
#else
printf("receive %d MobiDRMPrivate datas ok !!!", MobiDRMPrivate_len);
#endif
printf("\nreceive 20 MobiDRMPrivate verify datas:\n");
memcpy((char *)MobiDRMPrivate_verify_data_receive, (char *)(MobiDRMPrivate+MobiDRMPrivate_len), 20);
for (i=0; i<20; i++) {
printf("%02x:", MobiDRMPrivate_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d MobiDRMPrivate datas...\n", MobiDRMPrivate_len);
SHA1_Perform((unsigned char *)MobiDRMPrivate_data, MobiDRMPrivate_len, (unsigned char *)MobiDRMPrivate_verify_data_calculate);
printf("verify & get 20 MobiDRMPrivate verify datas:\n");
for (i=0; i<20; i++)
printf("%02x:", MobiDRMPrivate_verify_data_calculate[i]);
printf("\n");
ret = memcmp(MobiDRMPrivate_verify_data_receive, MobiDRMPrivate_verify_data_calculate, 20);
if (ret == 0) {
printf("MobiDRMPrivate datas verify success\n");
argv[3] = MobiDRMPrivate_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(MobiDRMPrivate datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic"))) {
#define MOBIDRMPUBLIC_DATA_ADDR (volatile unsigned long *)(0x82000000)//get MobiDRMPublic data from address:0x82000000
char* MobiDRMPublic = (char *)MOBIDRMPUBLIC_DATA_ADDR;
char length[4] = {0}, MobiDRMPublic_data[MOBIDRMPUBLIC_MAX_LEN] = {0};
for (i=0; i<4; i++) {
length[i] = *MobiDRMPublic++;
//printf("length[%d]=0x%02x\n", i, length[i]);
}
int MobiDRMPublic_len = (int)((length[3]<<24)|(length[2]<<16)|(length[1]<<8)|(length[0]));
if (MobiDRMPublic_len > MOBIDRMPUBLIC_MAX_LEN || MobiDRMPublic_len <= 0) {
sprintf(buff, "MobiDRMPublic_len=%d(maximum length limit is %d)", MobiDRMPublic_len, MOBIDRMPUBLIC_MAX_LEN);
printf("%s\n", buff);
return -1;
}
printf("receive %d MobiDRMPublic datas from address:0x82000000:\n", MobiDRMPublic_len);
memcpy((char *)MobiDRMPublic_data, (char *)MobiDRMPublic, MobiDRMPublic_len);
#ifdef KEYBOX_PRINT
for (i=0; i<MobiDRMPublic_len; i++) {
printf("%02x:", MobiDRMPublic_data[i]);
}
#else
printf("receive %d MobiDRMPublic datas ok !!!", MobiDRMPublic_len);
#endif
printf("\nreceive 20 MobiDRMPublic verify datas:\n");
memcpy((char *)MobiDRMPublic_verify_data_receive, (char *)(MobiDRMPublic+MobiDRMPublic_len), 20);
for (i=0; i<20; i++) {
printf("%02x:", MobiDRMPublic_verify_data_receive[i]);
}
printf("\n");
printf("start to verify %d MobiDRMPublic datas...\n", MobiDRMPublic_len);
SHA1_Perform((unsigned char *)MobiDRMPublic_data, MobiDRMPublic_len, (unsigned char *)MobiDRMPublic_verify_data_calculate);
printf("verify & get 20 MobiDRMPublic verify datas:\n");
for (i=0; i<20; i++)
printf("%02x:", MobiDRMPublic_verify_data_calculate[i]);
printf("\n");
ret = memcmp(MobiDRMPublic_verify_data_receive, MobiDRMPublic_verify_data_calculate, 20);
if (ret == 0) {
printf("MobiDRMPublic datas verify success\n");
argv[3] = MobiDRMPublic_data;
argc = 4;
}
else {
sprintf(buff, "%s", "failed:(MobiDRMPublic datas verify failed)");
printf("%s\n", buff);
return -1;
}
}
}
#endif /* CONFIG_SECURE_STORAGE_BURNED */
//printf argv[0]--argv[argc-1]
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp2", strlen("hdcp2"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef HDCP_PRINT
hdcp2 = argv[3];
for (i=0; i<HDCP2_KEY_TOTAL_LEN; i++) printf("%02x:", *hdcp2 ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef HDCP_PRINT
hdcp = argv[3];
for (i=0; i<HDCP_KEY_LEN; i++) printf("%02x:", *hdcp ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "random", strlen("random"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
random = argv[3];
printf("argv[3]=");
for (i=0; i<random_len; i++) printf("%02x:", *random ++) ;
printf("\n");
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef KEYBOX_PRINT
widevinekeybox = argv[3];
for (i=0; i<widevinekeybox_len; i++) printf("%02x:", *widevinekeybox ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef KEYBOX_PRINT
PlayReadykeybox = argv[3];
for (i=0; i<PlayReadykeybox_len; i++) printf("%02x:", *PlayReadykeybox ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef KEYBOX_PRINT
MobiDRMPrivate = argv[3];
for (i=0; i<MobiDRMPrivate_len; i++) printf("%02x:", *MobiDRMPrivate ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic"))) {
for (i=0; i<argc-1; i++) printf("argv[%d]=%s\n", i, argv[i]) ;
printf("argv[3]=");
#ifdef KEYBOX_PRINT
MobiDRMPublic = argv[3];
for (i=0; i<MobiDRMPublic_len; i++) printf("%02x:", *MobiDRMPublic ++) ;
printf("\n");
#else
printf("......\n");
#endif
}
else
for (i=0; i<argc; i++) printf("argv[%d]=%s\n", i,argv[i]) ;
if (!strncmp(argv[2], "version", strlen("version")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")) ||!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||
!strncmp(argv[2], "mac", strlen("mac")) ||!strncmp(argv[2], "usid", strlen("usid")) ||!strncmp(argv[2], "hdcp2", strlen("hdcp2")) ||
!strncmp(argv[2], "hdcp", strlen("hdcp")) || !strncmp(argv[2], "boardid", strlen("boardid")) ||
!strncmp(argv[2], "serialno", strlen("serialno")) || !strncmp(argv[2], "MFG_Serialno", strlen("MFG_Serialno")))
key_device_index = 1; // flash -> efuse or nand or emmc
else if(!strncmp(argv[2], "random", strlen("random")) ||!strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox")) ||
!strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox")) ||!strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate")) ||
!strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic")))
key_device_index = 2; // securestorage
else
key_device_index = -1; // none command
/* Burn key to efuse */
/* ---The actual function to read & write operation */
#ifdef WRITE_TO_EFUSE_ENABLE
/* read/write version */
if (!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "version", strlen("version"))) {
int flag = 0;
ret = run_efuse_cmd(argc, argv, buff);
#ifdef CONFIG_AML_MESON3
if (!ret) {
for (i=0; i<3; i++) {
if (buff[i] != 0x00) {
flag = 1;
break;
}
}
if (flag) {
sprintf(key_data, "%02x:%02x:%02x", buff[0], buff[1], buff[2]);
printf("version=%s\n", key_data);
sprintf(buff, "success:(%s)", key_data);
}
else {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "%s", "okay:(version has been not writen)");
else
sprintf(buff, "%s", "failed:(version has been not writen)");
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
#elif defined(CONFIG_AML_MESON6)
if (!ret) {
if (buff[0] != 0x00) {
sprintf(key_data, "%02x", buff[0]);
printf("version=%s\n", key_data);
sprintf(buff, "success:(%s)", key_data);
}
else {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "%s", "okay:(version has been not writen)");
else
sprintf(buff, "%s", "failed:(version has been not writen)");
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
#endif
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "version", strlen("version"))) {
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
#ifndef EFUSE_READ_TEST_ENABLE
sprintf(buff, "success:(%s)", argv[3]);
#else
argv[1] = "read";
argc = 3;
ret = test_efuse_read(argc, argv, argv[3]);
if (!ret)
sprintf(buff, "success:(%s)", argv[3]);
else if(ret == -1) {
sprintf(buff, "%s", "failed:(efuse write success,but test read data not match write)");
printf("%s\n", buff);
return -1;
}
else if(ret == -2) {
sprintf(buff, "%s", "failed:(efuse write success,but test read fail)");
printf("%s\n", buff);
return -1;
}
#endif
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write mac/mac_bt/mac_wifi */
else if(!strncmp(argv[1], "read", strlen("read")) && (!strncmp(argv[2], "mac", strlen("mac")) ||
!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")))) {
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
for (i=0; i<6; i++) {
if (buff[i] != 0x00) {
flag = 1;
break;
}
}
if (flag) {
sprintf(key_data, "%02x:%02x:%02x:%02x:%02x:%02x", buff[0],buff[1],buff[2],buff[3],buff[4],buff[5]);
printf("%s_key_data=%s\n", argv[2], key_data);
sprintf(buff, "success:(%s)", key_data);
}
else {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "okay:(%s has been not writen)", argv[2]);
else
sprintf(buff, "failed:(%s has been not writen)", argv[2]);
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && (!strncmp(argv[2], "mac", strlen("mac")) ||
!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")))) {
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
#ifndef EFUSE_READ_TEST_ENABLE
sprintf(buff, "success:(%s)", argv[3]);
#else
argv[1] = "read";
argc = 3;
ret = test_efuse_read(argc, argv, argv[3]);
if (!ret)
sprintf(buff, "success:(%s)", argv[3]);
else if(ret == -1) {
sprintf(buff, "%s", "failed:(efuse write success,but test read data not match write)");
printf("%s\n", buff);
return -1;
}
else if(ret == -2) {
sprintf(buff, "%s", "failed:(efuse write success,but test read fail)");
printf("%s\n", buff);
return -1;
}
#endif
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write usid */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "usid", strlen("usid"))) {
int usid_flag = 0;
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
for (i=0; i<strlen(buff); i++) {
if (buff[i] != 0x00) {
usid_flag = 1;
break;
}
}
if (usid_flag) {
printf("usid_key_data=%s\n", buff);
memcpy(key_data, buff, strlen(buff));
sprintf(buff, "success:(%s)", key_data);
}
else {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "%s", "okay:(usid has been not writen)");
else
sprintf(buff, "%s", "failed:(usid has been not writen)");
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "usid", strlen("usid"))) {
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
#ifndef EFUSE_READ_TEST_ENABLE
sprintf(buff, "success:(%s)", argv[3]);
#else
argv[1] = "read";
argc = 3;
ret = test_efuse_read(argc, argv, argv[3]);
if (!ret)
sprintf(buff, "success:(%s)", argv[3]);
else if(ret == -1) {
sprintf(buff, "%s", "failed:(efuse write success,but test read data not match write)");
printf("%s\n", buff);
return -1;
}
else if(ret == -2) {
sprintf(buff, "%s", "failed:(efuse write success,but test read fail)");
printf("%s\n", buff);
return -1;
}
#endif
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write hdcp */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
int hdcp_flag = 0;
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
for (i=0; i<HDCP_KEY_LEN; i++) {
if (buff[i] != 0x00) {
hdcp_flag = 1;
break;
}
}
if (hdcp_flag) {
printf("hdcp_key_data is:\n");
for (i=0; i<HDCP_KEY_LEN; i++)
printf("%.2x:", buff[i]);
printf("\n");
sprintf(buff, "%s", "success:(hdcp has been writen)");
}
else {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "%s", "okay:(hdcp has been not writen)");
else
sprintf(buff, "%s", "failed:(hdcp has been not writen)");
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
ret = run_efuse_cmd(argc, argv, buff);
if (!ret) {
#ifndef EFUSE_READ_TEST_ENABLE
sprintf(buff, "%s", "success:(efuse write hdcp success)");
#else
argv[1] = "read";
argc = 3;
ret = test_efuse_read(argc, argv, argv[3]);
if (!ret)
sprintf(buff, "%s", "success:(efuse write hdcp success)");
else if(ret == -1) {
sprintf(buff, "%s", "failed:(efuse write success,but test read data not match write)");
printf("%s\n", buff);
return -1;
}
else if(ret == -2) {
sprintf(buff, "%s", "failed:(efuse write success,but test read fail)");
printf("%s\n", buff);
return -1;
}
#endif
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
#if !defined(CONFIG_SECURE_STORAGE_BURNED)
/* no command mach */
else {
sprintf(buff, "%s", "failed:(No command mached)");
printf("%s\n", buff);
return -1;
}
#endif
#endif /* WRITE_TO_EFUSE_ENABLE */
/* Burn key to nand/emmc */
/* ---The actual function to read & write operation */
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE)
/* read/write version */
if (!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "version", strlen("version"))) {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "okay:(%s has been not initialized)", argv[0]);
else
sprintf(buff, "failed:(%s has been not initialized)", argv[0]);
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "version", strlen("version"))) {
ret = ensure_secukey_init();
if (ret == 0) { //init nand/emmc success.
sprintf(buff, "success:(init %s success)", argv[0]);
}
else if(ret == 1) { //nand/emmc already inited.
sprintf(buff, "success:(%s already inited)", argv[0]);
}
else { //init nand/emmc failed!!
sprintf(buff, "failed:(init %s failed)", argv[0]);
printf("%s\n", buff);
return -1;
}
}
/* read/write mac/mac_bt/mac_wifi/usid*/
else if(!strncmp(argv[1], "read", strlen("read")) && (!strncmp(argv[2], "mac", strlen("mac")) ||
!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")) ||
!strncmp(argv[2], "usid", strlen("usid")))) {
ret = cmd_secukey(argc, argv, buff);
if (!ret) {
printf("%s_key_data=%s\n", argv[2], buff);
memcpy(key_data, buff, strlen(buff));
sprintf(buff, "success:(%s)", key_data);
}
else if(ret == 1) {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "okay:(%s has been not writen)", argv[2]);
else
sprintf(buff, "failed:(%s has been not writen)", argv[2]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && (!strncmp(argv[2], "mac", strlen("mac")) ||
!strncmp(argv[2], "mac_bt", strlen("mac_bt")) ||!strncmp(argv[2], "mac_wifi", strlen("mac_wifi")) ||
!strncmp(argv[2], "usid", strlen("usid")))) {
for (i=0; i<4; i++) buff[i] = (char)((strlen(argv[3]) >> (i*8)) & 0xff) ;
ret = cmd_secukey(argc, argv, buff);
if (!ret)
sprintf(buff, "success:(%s)", argv[3]);
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write hdcp2 */
/* two keys: hdcp2lc128, hdcp2key */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "hdcp2", strlen("hdcp2"))) {
char rKeyHdcp2Data[HDCP2_KEY_TOTAL_LEN] = {0};
argv[2] = (char *)HDCP2LC128_NAME;
printf("need to convert command again.cmd:\"%s %s %s\"\n", argv[0], argv[1], argv[2]);
ret = cmd_secukey(argc, argv, rKeyHdcp2Data);
if (!ret) {
#ifdef HDCP_PRINT
char hdcp2lc128Decryption[HDCP2LC128_LEN] = {0};
printf("start to decrypt %s...\n", HDCP2LC128_NAME);
hdcpDataDecryption(HDCP2LC128_LEN, rKeyHdcp2Data, hdcp2lc128Decryption);
printf("%s is:\n", argv[2]);
for (i=0; i<HDCP2LC128_LEN; i++)
printf("%.2x:", hdcp2lc128Decryption[i]);
printf("\n");
#endif
printf("%s has been writen,continue to read %s\n", HDCP2LC128_NAME, HDCP2KEY_NAME);
memset(rKeyHdcp2Data, 0, sizeof(rKeyHdcp2Data));
argv[2] = (char *)HDCP2KEY_NAME;
printf("need to convert command again.cmd:\"%s %s %s\"\n", argv[0], argv[1], argv[2]);
ret = cmd_secukey(argc, argv, rKeyHdcp2Data);
if (!ret) {
#ifdef HDCP_PRINT
char hdcp2keyDecryption[HDCP2KEY_LEN] = {0};
printf("start to decrypt %s...\n", HDCP2KEY_NAME);
hdcpDataDecryption(HDCP2KEY_LEN, rKeyHdcp2Data, hdcp2keyDecryption);
printf("%s is:\n", argv[2]);
for (i=0; i<HDCP2KEY_LEN; i++)
printf("%.2x:", hdcp2keyDecryption[i]);
printf("\n");
#endif
sprintf(buff, "success:(%s & %s has been writen)", HDCP2LC128_NAME, HDCP2KEY_NAME);
}
else if(ret == 1) {
sprintf(buff, "failed:(%s has been writen,but %s has been not writen)", HDCP2LC128_NAME, HDCP2KEY_NAME);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(ret == 1) {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "okay:(%s has been not writen)", argv[2]);
else
sprintf(buff, "failed:(%s has been not writen)", argv[2]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp2", strlen("hdcp2"))) {
char hdcp2lc128Encryption[HDCP2LC128_LEN] = {0};
printf("start to encrypt %s...\n", HDCP2LC128_NAME);
hdcpDataEncryption(HDCP2LC128_LEN, hdcp2lc128, hdcp2lc128Encryption);
argv[2] = (char *)HDCP2LC128_NAME;
argv[3] = (char *)hdcp2lc128Encryption;
printf("need to convert command again.cmd:\"%s %s %s ...\"\n", argv[0], argv[1], argv[2]);
for (i=0; i<4; i++) buff[i] = (char)((HDCP2LC128_LEN >> (i*8)) & 0xff) ;
ret = cmd_secukey(argc, argv, buff);
if (!ret) {
printf("success to write %s,continue to write %s\n", HDCP2LC128_NAME, HDCP2KEY_NAME);
char hdcp2keyEncryption[HDCP2KEY_LEN] = {0};
printf("start to encrypt %s...\n", HDCP2KEY_NAME);
hdcpDataEncryption(HDCP2KEY_LEN, hdcp2key, hdcp2keyEncryption);
argv[2] = (char *)HDCP2KEY_NAME;
argv[3] = (char *)hdcp2keyEncryption;
printf("need to convert command again.cmd:\"%s %s %s ...\"\n", argv[0], argv[1], argv[2]);
for (i=0; i<4; i++) buff[i] = (char)((HDCP2KEY_LEN >> (i*8)) & 0xff) ;
ret = cmd_secukey(argc, argv, buff);
if (!ret) {
sprintf(buff, "success:(%s %s %s & %s success)", argv[0], argv[1], HDCP2LC128_NAME, HDCP2KEY_NAME);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write hdcp */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
ret = cmd_secukey(argc, argv, buff);
if (!ret) {
#ifdef HDCP_PRINT
printf("hdcp_key_data is:\n");
for (i=0; i<HDCP_KEY_LEN; i++)
printf("%.2x:", buff[i]);
printf("\n");
#endif
sprintf(buff, "%s", "success:(hdcp has been writen)");
}
else if(ret == 1) {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "%s", "okay:(hdcp has been not writen)");
else
sprintf(buff, "%s", "failed:(hdcp has been not writen)");
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "hdcp", strlen("hdcp"))) {
for (i=0; i<4; i++) buff[i] = (char)((HDCP_KEY_LEN >> (i*8)) & 0xff) ;
ret = cmd_secukey(argc, argv, buff);
if (!ret)
sprintf(buff, "success:(%s %s %s success)", argv[0], argv[1], argv[2]);
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write boardid/serialno */
else if(!strncmp(argv[1], "read", strlen("read")) && (!strncmp(argv[2], "boardid", strlen("boardid")) ||
!strncmp(argv[2], "serialno", strlen("serialno")) || !strncmp(argv[2], "MFG_Serialno", strlen("MFG_Serialno")))) {
ret = cmd_secukey(argc, argv, buff);
if (!ret) {
printf("%s_key_data=%s\n", argv[2], buff);
memcpy(key_data, buff, strlen(buff));
if (!strncmp(argv[2], "MFG_Serialno", strlen("MFG_Serialno")))
sprintf(buff, "success:(%s)", key_data);
else
sprintf(buff, "success:(%s has been writen)", argv[2]);
}
else if(ret == 1) {
if (sPctoolVersion >= PCTOOL_VERSION_1632)
sprintf(buff, "okay:(%s has been not writen)", argv[2]);
else
sprintf(buff, "failed:(%s has been not writen)", argv[2]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && (!strncmp(argv[2], "boardid", strlen("boardid")) ||
!strncmp(argv[2], "serialno", strlen("serialno")) || !strncmp(argv[2], "MFG_Serialno", strlen("MFG_Serialno")))) {
for (i=0; i<4; i++) buff[i] = (char)((strlen(argv[3]) >> (i*8)) & 0xff) ;
ret = cmd_secukey(argc, argv, buff);
if (!ret)
sprintf(buff, "success:(%s %s %s success)", argv[0], argv[1], argv[2]);
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
#if !defined(CONFIG_SECURE_STORAGE_BURNED)
/* no command mach */
else {
sprintf(buff, "%s", "failed:(No command mached)");
printf("%s\n", buff);
return -1;
}
#endif
#endif /* WRITE_TO_NAND_EMMC_ENABLE || WRITE_TO_NAND_ENABLE */
if (key_device_index == 1) {
printf("%s\n",buff);
return 0;
}
/* Burn key to securestorage */
/* ---The actual function to read & write operation */
#if defined(CONFIG_SECURE_STORAGE_BURNED)
// if(key_device_index == 1) {
// printf("%s\n",buff);
// return 0;
// }
/* init securestore device and write random at same time */
if (!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "random", strlen("random"))) {
ret = ensure_securestore_key_init(key_data, random_len);
if (ret == 0) { //init securestorage and write random success
sprintf(buff, "success:(init %s and write random success)", argv[0]);
}
else if(ret == 1) {
sprintf(buff, "success:(%s already inited and writed random)", argv[0]);
}
else { //init securestorage or write random failed!!
sprintf(buff, "failed:(init %s or write random failed)", argv[0]);
printf("%s\n", buff);
return -1;
}
}
/* read/write widevinekeybox */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox"))) {
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "%s", "success:(widevinekeybox has been writen)");
}
else if(ret == 1) {
sprintf(buff, "%s", "okay:(widevinekeybox has been not writen)");
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "widevinekeybox", strlen("widevinekeybox"))) {
for (i=0; i<4; i++) buff[i] = (char)((widevinekeybox_len >> (i*8)) & 0xff) ;
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "success:(%s write widevinekeybox success)", argv[0]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write PlayReadykeybox */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox"))) {
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "%s", "success:(PlayReadykeybox has been writen)");
}
else if(ret == 1) {
sprintf(buff, "%s", "okay:(PlayReadykeybox has been not writen)");
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "PlayReadykeybox", strlen("PlayReadykeybox"))) {
for (i=0; i<4; i++) buff[i] = (char)((PlayReadykeybox_len >> (i*8)) & 0xff) ;
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "success:(%s write PlayReadykeybox success)", argv[0]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write MobiDRMPrivate */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate"))) {
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "%s", "success:(MobiDRMPrivate has been writen)");
}
else if(ret == 1) {
sprintf(buff, "%s", "okay:(MobiDRMPrivate has been not writen)");
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPrivate", strlen("MobiDRMPrivate"))) {
for (i=0; i<4; i++) buff[i] = (char)((MobiDRMPrivate_len >> (i*8)) & 0xff) ;
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "success:(%s write MobiDRMPrivate success)", argv[0]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* read/write MobiDRMPublic */
else if(!strncmp(argv[1], "read", strlen("read")) && !strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic"))) {
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "%s", "success:(MobiDRMPublic has been writen)");
}
else if(ret == 1) {
sprintf(buff, "%s", "okay:(MobiDRMPublic has been not writen)");
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
else if(!strncmp(argv[1], "write", strlen("write")) && !strncmp(argv[2], "MobiDRMPublic", strlen("MobiDRMPublic"))) {
for (i=0; i<4; i++) buff[i] = (char)((MobiDRMPublic_len >> (i*8)) & 0xff) ;
ret = cmd_securestore(argc, argv, buff);
if (!ret) {
sprintf(buff, "success:(%s write MobiDRMPublic success)", argv[0]);
}
else {
sprintf(buff, "failed:(%s %s %s failed)", argv[0], argv[1], argv[2]);
printf("%s\n", buff);
return -1;
}
}
/* no command mach */
else {
sprintf(buff, "%s", "failed:(No command mached)");
printf("%s\n", buff);
return -1;
}
// set "reboot_mode=charging",because it has been set "reboot_mode=usb_burning" when recovery shutdown
if (!strncmp(getenv("reboot_mode"), "usb_burning", strlen("usb_burning"))) {
printf("reboot_mode=usb_burning, now set reboot_mode=charging.\n");
setenv("reboot_mode", "charging");
saveenv();
if (!strncmp(getenv("reboot_mode"), "charging", strlen("charging")))
printf("set env reboot_mode=charging ok\n");
else
printf("set env reboot_mode=charging fail,now reboot_mode is:%s\n", getenv("reboot_mode"));
}
#endif /* CONFIG_SECURE_STORAGE_BURNED */
}
else {
if (run_command(cmd, flag)) {
strcpy(buff, "fail");
return -1;
}
else{
strcpy(buff, "okay");
}
}
printf("%s\n",buff);
return 0;
}
#if defined(WRITE_TO_NAND_EMMC_ENABLE) || defined(WRITE_TO_NAND_ENABLE)
int ensure_secukey_init(void)
{
int error = -1;
if (sInitedSecukey) {
printf("flash device already inited!!\n");
return 1;
}
printf("should be inited first!\n");
error = uboot_key_initial("auto");
if (error >= 0) {
printf("init key ok!!\n");
sInitedSecukey = 1;
return 0;
}
else
printf("init key fail!!\n");
return -1;
}
static char hex_to_asc(char para)
{
if (para >= 0 && para <= 9)
para = para + '0';
else if(para >= 0xa && para <= 0xf)
para = para + 'a' - 0xa;
return para;
}
static char asc_to_hex(char para)
{
if (para >= '0' && para <= '9')
para = para - '0';
else if(para >= 'a' && para <= 'f')
para = para - 'a' + 0xa;
else if(para >= 'A' && para <= 'F')
para = para - 'A' + 0xa;
return para;
}
/**
* cmd_secukey
* read: command in *argv[], and read datas saved in buf
* return: 0->success, 1->have not writen, -1->failed
*
* write: command in *argv[], and datas length in buf
* return: 0->success, -1->failed
**/
int cmd_secukey(int argc, char *argv[], char *buf)
{
int i = 0, j = 0, ret = 0, error = -1, secukey_len = 0;
char *secukey_cmd = NULL, *secukey_name = NULL, *secukey_data = NULL;
char namebuf[AML_KEY_NAMELEN], databuf[4096], listkey[1024];
/* at least two arguments please */
if (argc < 2)
goto err;
memset(namebuf, 0, sizeof(namebuf));
memset(databuf, 0, sizeof(databuf));
memset(listkey, 0, sizeof(listkey));
secukey_cmd = (char *)argv[1];
if (sInitedSecukey) {
if (argc > 2 && argc < 5) {
if (!strncmp(secukey_cmd, "read", strlen("read"))) {
if (argc > 3)
goto err;
ret = uboot_get_keylist(listkey);
printf("all key names list are(ret=%d):\n%s", ret, listkey);
secukey_name = (char *)argv[2];
strncpy(namebuf, secukey_name, strlen(secukey_name));
error = uboot_key_read(namebuf, databuf);
if (error >= 0) { //read success
if (strncmp(namebuf, HDCP2KEY_NAME, strlen(HDCP2KEY_NAME)) != 0) {
memset(buf, 0, SECUKEY_BYTES);
for (i=0,j=0; i<SECUKEY_BYTES*2; i+=2,j++) {
buf[j]= (((asc_to_hex(databuf[i]))<<4) | (asc_to_hex(databuf[i+1])));
}
}
else {
memset(buf, 0, HDCP2_KEY_TOTAL_LEN);
for (i=0,j=0; i<HDCP2_KEY_TOTAL_LEN*2; i+=2,j++) {
buf[j]= (((asc_to_hex(databuf[i]))<<4) | (asc_to_hex(databuf[i+1])));
}
}
printf("read ok!!\n");
return 0;
}
else { // read error or have not been writen
if (!strncmp(namebuf, "mac_bt", 6) || !strncmp(namebuf, "mac_wifi", 8))
;
else if(!strncmp(namebuf, "mac", 3)) {
memset(namebuf, 0, sizeof(namebuf));
sprintf(namebuf, "%s", "mac\n");
}
if (strstr(listkey, namebuf)) {
printf("find %s, but read error!!\n", namebuf);
goto err; // read error
}
else {
printf("not find %s, and it doesn't be writen before!!\n", namebuf);
return 1; // has been not writen
}
}
}
else if(!strncmp(secukey_cmd, "write", strlen("write"))) {
if (argc != 4)
goto err;
secukey_name = (char *)argv[2];
secukey_data = (char *)argv[3];
strncpy(namebuf, secukey_name, strlen(secukey_name));
secukey_len = (int)((buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]));
printf("write %s key's length is: %d bytes\n", namebuf, secukey_len);
for (i=0,j=0; i<secukey_len; i++,j++) {
databuf[j]= hex_to_asc((secukey_data[i]>>4) & 0x0f);
databuf[++j]= hex_to_asc((secukey_data[i]) & 0x0f);
//printf("%02x:%02x:", databuf[j-1], databuf[j]);
}
error = uboot_key_write(namebuf, databuf);
if (error >= 0) {
printf("write ok!!\n");
return 0;
}
else {
printf("write error!!\n");
goto err;
}
}
}
}
else {
printf("flash device uninitialized!!\n");
goto err;
}
err:
return -1;
}
#endif
#if defined(CONFIG_SECURE_STORAGE_BURNED)
int ensure_securestore_key_init(char *seed, int seed_len)
{
int ret = -1;
if (sInitedSecurestore) {
printf("securestore key already inited and seed already writed!!\n");
return 1;
}
printf("start to init securestore key and write seed!!\n");
ret = securestore_key_init(seed, seed_len);
if (ret == 0) {
printf("init securestore key and write seed ok!!\n");
sInitedSecurestore = 1;
ret = 0;
}
else {
printf("init securestore key or write seed error\n");
ret = -1;
}
return ret;
}
/**
* cmd_securestore
* read: command in *argv[], don't allow to read datas
* return: 0->success, 1->have not writen, -1->failed
*
* write: command in *argv[], and datas length in buf
* return: 0->success, -1->failed
**/
int cmd_securestore(int argc, char *argv[], char *buf)
{
int error = -1;
unsigned int key_status = 0, sstorekey_len = 0;
char *sstorekey_cmd, *sstorekey_name, *sstorekey_data;
char name_buf[20], data_buf[4096];
/* at least two arguments please */
if (argc < 2)
goto err;
memset(name_buf, 0, sizeof(name_buf));
memset(data_buf, 0, sizeof(data_buf));
sstorekey_cmd = argv[1];
if (sInitedSecurestore) {
if (argc > 2 && argc < 5) {
if (!strncmp(sstorekey_cmd, "read", strlen("read"))) {
if (argc > 3)
goto err;
sstorekey_name = argv[2];
strncpy(name_buf, sstorekey_name, strlen(sstorekey_name));
error = securestore_key_query(name_buf, &key_status);
if (!error) {
printf("key_status=%d\n", key_status);
if (key_status == 0) { //key has been not writen
printf("%s has been not writen!!\n", name_buf);
return 1;
}
else if(key_status == 1) { //key has been writen
printf("%s has been writen!!\n", name_buf);
return 0;
}
else {
printf("key_status: %d,reserved\n", key_status);
return -1;
}
}
else {
printf("err :%d,%s:%d\n", error, __func__, __LINE__);
return -1;
}
}
else if(!strncmp(sstorekey_cmd, "write", strlen("write"))) {
if (argc != 4)
goto err;
sstorekey_name = argv[2];
sstorekey_data = argv[3];
strncpy(name_buf, sstorekey_name, strlen(sstorekey_name));
sstorekey_len = (int)((buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|(buf[0]));
printf("write %s key's length is: %d\n", name_buf, sstorekey_len);
error = securestore_key_write(name_buf, sstorekey_data, sstorekey_len, 0);
if (!error) {
if (!securestore_key_query(name_buf, &key_status))
printf("after write, query key_status=%d\n", key_status);
printf("write %s ok!!\n", name_buf);
return 0;
}
else {
printf("write %s error!!\n", name_buf);
goto err;
}
}
}
}
else {
printf("securestore device or securestore key uninitialized!!\n");
goto err;
}
err:
return -1;
}
#endif
char generalDataChange(const char input)
{
int i;
char result = 0;
for (i=0; i<8; i++) {
if ((input & (1<<i)) != 0)
result |= (1<<(7-i));
else
result &= ~(1<<(7-i));
}
return result;
}
void hdcpDataEncryption(const int len, const char *input, char *out)
{
int i = 0;
for (i=0; i<len; i++)
*out++ = generalDataChange(*input++);
}
void hdcpDataDecryption(const int len, const char *input, char *out)
{
int i = 0;
for (i=0; i<len; i++)
*out++ = generalDataChange(*input++);
}