I have found a few bugs which could lead to wrong results. Updated source code of getmkey.c is here
Code: Select all
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#define CRYPTO_UNIT_BASE_PA 0x303F0000
#define CRYPTO_MAP_SIZE 0x1000
#define MEM_BASE_256MB_PA 0x6FF20000
//#define MEM_BASE_256MB_PA 0x63720000
#define MEM_BASE_SIZE 0xDFC00
#define O_SE_CPSTATUS 0x400
#define O_SE_DMACTRL_OFFSET 0x404
#define O_SE_CPCFG_OFFSET 0x430
#define O_SE_SBUFSTART_OFFSET 0x420
#define O_SE_TBUFSTART_OFFSET 0x41C
#define O_SE_XFRSIZE_OFFSET 0x414
#define O_SE_CPBLKSIZE_OFFSET 0x464
unsigned char *pCipherbase = NULL;
unsigned char *pMemBase = NULL;
unsigned long int lldSeReadReg(unsigned long int u32offset)
{
volatile unsigned long int tmp = 0;
tmp = *(volatile unsigned long int *)(pCipherbase+u32offset);
return(tmp);
}
void lldSeWriteReg(unsigned long int u32offset, unsigned long int u32Data)
{
*(volatile unsigned long int *)(pCipherbase+u32offset) = u32Data;
}
void secure_dec(unsigned char *u32SrcAddr, unsigned long int u32InDataLength, unsigned char *u32DstAddr)
{
int i = 0;
memcpy(pMemBase, u32SrcAddr, u32InDataLength);
lldSeWriteReg(O_SE_DMACTRL_OFFSET,0x2A); // 0x2A -> 0x404
lldSeWriteReg(O_SE_CPCFG_OFFSET,0); // 0 -> 0x430
lldSeWriteReg(O_SE_CPCFG_OFFSET,0x180); // 0x180 -> 0x430
//lldSeWriteReg(O_SE_SBUFSTART_OFFSET,CRYPTO_UNIT_BASE_PA); // 0x303F0000 -> 0x420 ???
//lldSeWriteReg(O_SE_TBUFSTART_OFFSET,CRYPTO_UNIT_BASE_PA); // 0x303F0000 -> 0x41C ???
lldSeWriteReg(O_SE_SBUFSTART_OFFSET,MEM_BASE_256MB_PA);
lldSeWriteReg(O_SE_TBUFSTART_OFFSET,MEM_BASE_256MB_PA);
lldSeWriteReg(O_SE_XFRSIZE_OFFSET,u32InDataLength); // Length -> 0x414
lldSeWriteReg(O_SE_CPBLKSIZE_OFFSET,u32InDataLength); // Length -> 0x464
lldSeWriteReg(O_SE_DMACTRL_OFFSET,0x2B); // 0x2B -> 0x404
while (lldSeReadReg(O_SE_CPSTATUS)!=0) i++; // 0x400
lldSeWriteReg(O_SE_DMACTRL_OFFSET,0x2A); // 0x2A -> 0x404
memcpy(u32DstAddr, pMemBase, u32InDataLength);
printf("After waiting %d loops\n", i);
}
void print_hex(unsigned char *bytes, int length)
{
int j;
do
{
for (j=0; j<((length<16)?length:16);j++)
{
printf("%02x",bytes[j]);
printf(" ");
}
printf("\n");
length-=16;
bytes += 16;
}
while (length >0);
}
int main()
{
int fd1=open("/dev/mem",O_RDWR|O_SYNC);
int fd2=open("/dev/mem",O_RDWR|O_SYNC);
if ((fd2==-1)||(fd1==-1))
{
printf("Error in opening /dev/mem! Errno=0x%X\n",errno);
if (fd1!=-1)
{
close(fd1);
}
if (fd2!=-1)
{
close(fd2);
}
}
else
{
printf("opening /dev/mem ok!\n");
pCipherbase = mmap(NULL,CRYPTO_MAP_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd1,CRYPTO_UNIT_BASE_PA);
pMemBase = mmap(NULL,MEM_BASE_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd2,MEM_BASE_256MB_PA);
if ((pCipherbase==MAP_FAILED)||(pMemBase==MAP_FAILED))
{
printf("Error in doing mmap()! pCipherbase=0x%08X pMembase=0x%08X Errno=0x%X\n", (int)pCipherbase, (int)pMemBase, errno);
close(fd1);
close(fd2);
}
else
{
int fd3=open("/dev/tfsr11",O_RDONLY);
if (fd3==-1)
{
printf("Error in opening tfsr11! Errno=0x%X\n",errno);
munmap(pCipherbase,CRYPTO_MAP_SIZE);
munmap(pMemBase,MEM_BASE_SIZE);
close(fd1);
close(fd2);
}
else
{
unsigned char keybin[20];
if (read(fd3, keybin, 20)!=20)
{
printf("could not read keybin partition!\n");
munmap(pCipherbase,CRYPTO_MAP_SIZE);
munmap(pMemBase,MEM_BASE_SIZE);
close(fd1);
close(fd2);
close(fd3);
}
else
{
unsigned char *mackey=&(keybin[4]);
unsigned char mkey[16];
close(fd3);
memset(mkey,0,16);
printf("reading keybin successful!\n");
print_hex(keybin,20);
secure_dec(mackey, 0x10, mkey);
printf("mkey=");
print_hex(mkey,0x10);
munmap(pCipherbase,CRYPTO_MAP_SIZE);
munmap(pMemBase,MEM_BASE_SIZE);
close(fd1);
close(fd2);
}
}
}
}
return 0;
}
Code: Select all
opening /dev/mem ok!
reading keybin successful!
f0 f0 fe fa 86 d4 46 c9 47 76 56 00 a4 a8 30 98
e6 ee 7a e2
After waiting 1 loops
mkey=2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c