📄 at88scxx.asm
字号:
SDA EQU P1.3 ;此处定义SDA
SCL EQU P1.2 ;此处定义SCL
ORG 0000H
LJMP START
ORG 0030H
START:
MOV SP,#68H
CLR P3.5 ;器件上电
;***********************AT88SC0104C加密主程序**********************************
AT88SC0104C:
MOV R5,#30H;工作单元的起始地址 本例中开机后请不要将30H-5FH单元清0,以便产生随机数
MOV R0,#31H
MOV @R0,#24H ;STU+1.此处定义执行认证时使用的密钥和密码(bit5-bit4是设置Gc,bit3-bit0设置Password);Gc_Pw_Select.
LCALL AUTHENTICATION;认证
LCALL Read_AAC ;返回值是A=AAC
MOV R0,#31H
MOV @R0,#24H;STU+1.此处定义执行认证时使用的密钥和密码(bit5-bit4是设置Gc,bit3-bit0设置Password);Gc_Pw_Select.
LCALL VERIFY_WRITE_PASSWORD ;写数据一定要校验写密码
LCALL Read_PAC
;LCALL VERIFY_READ_PASSWORD ;如仅读数据,校读密码既可
MOV R0,#30H
MOV @R0,#00H
LCALL SET_USER_ZONE;选择用户区
MOV R0,#33H
MOV @R0,#00H;0000H,STU+3.此处定义读用户区的起始地址
MOV R0,#34H
MOV @R0,#0FH;000FH,STU+4.此处定义读用户区的结束地址;(例读用户区下0000-000F单元)
MOV R0,#35H
MOV @R0,#58H;STU+5.此处定义读出的密文存放地址;Encrypted_Data_Addr(例其值不应是30H-30H+27H)
LCALL READ_USER_ZONE
MOV R0,#36H
MOV @R0,#58H;STU+6.此处定义解出的明文存放地址;Plaintext_Addr(例其值不应30H-30H+27H)
MOV R0,#37H
MOV @R0,#08H;STU+7.此处定义解密密文字节数;Decrypto_Data_Number;也可一步解完
LCALL DECRYPTO_DATA;
MOV R0,#36H
MOV @R0,#60H;STU+6.此处重新定义明文出口:注意在此例中30H-57H不能存放密文也不能存放明文)
MOV R0,#37H
MOV @R0,#04H;STU+7.此处重新定义解密密文字节数
LCALL DECRYPTO_DATA
MOV R0,#36H
MOV @R0,#64H;STU+6.此处重新定义明文出口
MOV R0,#37H
MOV @R0,#04H;STU+7.此处重新定义解密密文字节数
LCALL DECRYPTO_DATA;至此,明文全解出
MOV R0,#38H ;(注意R5=30H则30H-57H不能存放写入的明文)
MOV @R0,#00H ;0000H,STU+8.此处定义写用户区的起始地址
MOV R0,#39H
MOV @R0,#0FH ;000FH,STU+9.此处定义写用户区的结束地址
MOV R0,#3AH
MOV @R0,#58H ;STU+A.此处定义写明文的入口地址;Write_Plaintext_Addr.
LCALL WRITE_USER_ZONE;写入的数据掉电不丢失
MOV R0,#38H
MOV @R0,#00H;0000H,STU+8.此处重新定义写用户区的起始地址
MOV R0,#39H
MOV @R0,#0FH;000FH,STU+9.此处重新定义写用户区的结束地址
MOV R0,#3AH
MOV @R0,#20H;STU+A.此处重新定义写明文的入口地址(例把当前单片机RAM20H-2FH单元写到用户区的0010-001F)
LCALL WRITE_USER_ZONE
AT88SC0104C_END:SJMP $
GC_TABLE:
DB 00H,00H,00H,00H,00H,00H,00H,00H ;GC0
DB 88H,55H,96H,49H,12H,76H,16H,80H ;GC1
DB 11H,11H,11H,11H,11H,11H,11H,11H ;GC2
DB 33H,33H,33H,33H,33H,33H,33H,33H ;GC3
PASSWORD_TABLE:
DB 00H,00H,00H; ;WRITE PASSWORD 0
DB 00H,00H,00H; ;READ PASSWORD 0
DB 11H,11H,11H; ;WRITE PASSWORD 1
DB 11H,11H,11H; ;READ PASSWORD 1
DB 11H,11H,11H, ;WRITE PASSWORD 2
DB 11H,11H,11H; ;READ PASSWORD 2
DB 33H,33H,33H; ;WRITE PASSWORD 3
DB 33H,33H,33H; ;READ PASSWORD 3
DB 22H,22H,22H; ;WRITE PASSWORD 4
DB 22H,22H,22H; ;READ PASSWORD 4
DB 16H,73H,59H; ;WRITE PASSWORD 5
DB 56H,37H,61H; ;READ PASSWORD 5
DB 66H,66H,66H; ;WRITE PASSWORD 6
DB 66H,66H,66H; ;READ PASSWORD 6
DB 0DDH,42H,97H; ;WRITE PASSWORD 7
DB 0FFH,0FFH,0FFH; ;READ PASSWORD 7
;#################################
READ_USER_ZONE:
MOV A,R5
ADD A,#28H
MOV R0,A;得8命令系统地址
MOV B,A
MOV @R0,#0B2H ;B2+00+LOW_ADDR+NUMBER+密文出口地址
INC R0
MOV @R0,#00H
MOV A,R5
ADD A,#03H
MOV R1,A
MOV A,@R1
INC R0
MOV @R0,A
INC R1;得密文出口地址
MOV A,@R1
SUBB A,@R0
INC A
INC R0
MOV @R0,A
INC R0 ;读取存放地址
MOV A,R5
ADD A,#05H
MOV R1,A
MOV A,@R1
MOV @R0,A
LCALL READ
MOV A,R5
ADD A,#0BH
MOV R0,A ;DATAIN
MOV @R0,#00H
MOV R2,#05H
LCALL CRYPTO_DATA_REPEAT
MOV A,R5
ADD A,#0BH
MOV R0,A ;DATAIN
MOV A,R5
ADD A,#03H
MOV R1,A
MOV A,@R1
MOV @R0,A;LOWER ADDR BYTE
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
MOV A,R5
ADD A,#0BH
MOV R0,A ;DATAIN
MOV @R0,#00H
MOV R2,#05H
LCALL CRYPTO_DATA_REPEAT
MOV A,R5
ADD A,#0BH
MOV R0,A ;DATAIN
MOV A,R5
ADD A,#04H
MOV R1,A
MOV A,@R1 ;N
DEC R1
SUBB A,@R1
INC A
MOV @R0,A
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
RET
AUTHENTICATION: ;GC/CI/RANDOM_NUMBER_GENERATE(Q0)不可随意动;对后面有影响
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
MOV A,R5
ADD A,#02H
MOV R0,A
MOV A,R5
ADD A,#30H
MOV @R0,A;Q0 40H
LCALL CRYPTO_BLOCK_INITIAL ;初始化GPA函数
LCALL READ_CI ;38-3F ;存放在(0F)+28H的地址
LCALL GC_CI_Q0_CALCULATE ;计算存放在(r5)+28H-(r5)+2FH地址的CI 和(0F)+30H-(0F)+33H的前4字节Q0
LCALL CALCULATE_GC ;把GC读入并放在(0F)+28H-(0F)+2FH
LCALL SWAP_Q0 ;为了把计算程序压缩 Q0后4字节前移
LCALL GC_CI_Q0_CALCULATE ;计算存放在(0F)+28H-(0F)+2FH地址的GC 和(0F)+30H-(0F)+33H的后4字节Q0
LCALL SWAP_Q0_RETRUN ;Q0后8字节顺序还原;准备发送Q0
LCALL GENERATE_CH ;产生Q1存放在(0F)+28H-(0F)+2FH地址
MOV A,R5
ADD A,#01H
MOV R0,A
MOV A,@R0
ANL A,#30H
SWAP A ;AUTHENTICATION的标志
MOV B,A
LCALL SEND_Q0_Q1 ;发送Q0 Q1
LCALL CALCULATE_NEW_CI_AND_SK;计算NEW CI AND SK,存放在(0F)+28H-(0F)+37H的地址
VERIFY_CRYPTO:
LCALL CRYPTO_BLOCK_INITIAL;重新初始化GPA函数
LCALL GC_CI_Q0_CALCULATE ;NEW_SK也作Q0;计算存放在(0F)+28H-(0F)+2FH地址的CI 和(0F)+30H-(0F)+33H的前4字节Q0;把SK放到38-3F
MOV A,R5
ADD A,#02H
MOV R1,A
MOV A,@R1
MOV R1,A;ADDR
MOV A,R5
ADD A,#28H
MOV R0,A
MOV R2,#08H
MIY: MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R2,MIY
LCALL SWAP_Q0
LCALL GC_CI_Q0_CALCULATE
LCALL SWAP_Q0_RETRUN
LCALL GENERATE_CH
MOV A,R5
ADD A,#01H
MOV R0,A
MOV A,@R0
ANL A,#30H
SWAP A
ADD A,#10H ;AUTHENTICATION的标志
MOV B,A
LCALL SEND_Q0_Q1
LCALL CALCULATE_NEW_CI_AND_SK
RET
SWAP_Q0:;Q0高4字节和低4字节交换
MOV A,R5
ADD A,#02H
MOV R0,A
MOV A,@R0 ;ADDR
MOV R1,A
ADD A,#04H
MOV R0,A
MOV R2,#04H
SWAP_Q0_BYTE:
MOV B,@R1
MOV A,@R0
MOV @R1,A
MOV @R0,B
INC R0
INC R1
DJNZ R2,SWAP_Q0_BYTE
RET
SWAP_Q0_RETRUN:;Q0高4字节和低4字节交换还原
MOV A,R5
ADD A,#02H
MOV R0,A
MOV A,@R0 ;ADDR
MOV R1,A
ADD A,#04H
MOV R0,A
MOV R2,#04H
SWAP_Q0_BYTE_RETRUN:
MOV B,@R0
MOV A,@R1
MOV @R0,A
MOV @R1,B
INC R0
INC R1
DJNZ R2,SWAP_Q0_BYTE_RETRUN
RET
;///////SEND Q0/////////
SEND_Q0_Q1:
MOV A,R5
ADD A,#27H
MOV R1,A ;ADDR
DEC R1 ;24 25 26 PUSH A ;为了时序紧凑,压(0F)+24-(0F)+26单元入堆盏
MOV A,@R1
PUSH A
DEC R1
MOV A,@R1
PUSH A
DEC R1
MOV A,@R1
PUSH A
MOV @R1,#0B8H ;24
INC R1
MOV @R1,B ;25;认证关键命令 认证:0X 密文认证:1X
INC R1
MOV @R1,#00H ;26
INC R1
MOV @R1,#10H
;SEND Q0
MOV A,R5
ADD A,#02H
MOV R0,A
MOV A,@R0 ;ADDR
MOV R0,A
MOV A,R5
ADD A,#28H
MOV R1,A
MOV R2,#08H
SWAP_Q0_CH: ;按顺序发送,交换Q0 CH数据
MOV B,@R1
MOV A,@R0
MOV @R1,A
MOV @R0,B
INC R0
INC R1
DJNZ R2,SWAP_Q0_CH
MOV A,R5
ADD A,#24H
MOV R1,A ;发送所对应的ADDR
MOV R0,#14H;发送的字节数
LCALL SEND_BYTE
MOV A,R5
ADD A,#24H
MOV R1,A ;ADDR
POP A
MOV @R1,A
INC R1 ;25
POP A
MOV @R1,A
INC R1 ;26
POP A
MOV @R1,A
RET
SEND_BYTE:
MOV R2,#80H ;若出现异常,给与一定的时间重新启动命令
SEND_Q0_SMSTART:
LCALL SMSTART
WR2: MOV A,@R1
MOV B,#08H
WR1: CLR SDA
JNB ACC.7,WR0
SETB SDA
WR0: NOP
NOP
SETB SCL
NOP
NOP
CLR SCL
NOP
RL A
DJNZ B,WR1
SETB SDA
NOP
NOP
SETB SCL
NOP
NOP
WRW: JNB SDA,WRW2
WRW1: DJNZ R2,SEND_Q0_SMSTART
WRW2: CLR SCL
INC R1
NOP
DJNZ R0,WR2
JMP SMSTOP
;;---------IF Q1 VERIFY DATA SUCCESS,DEVICE WILL COMPUTE A NEW CI AND SK
;COMPUTE Q2
CALCULATE_NEW_CI_AND_SK: ;》E8-EF SK>GC
MOV A,R5
ADD A,#0BH
MOV R0,A
MOV @R0,#00H;DATAIN
MOV A,R5
ADD A,#28H
MOV R1,A
MOV @R1,#0FFH; CI(0)为FFH
MOV A,R5
ADD A,#29H
MOV R4,A ;产生存放ADDR ;(0F)+38-(0F)+3F
MOV R2,#07H
NEW_CI:
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
MOV A,R5
ADD A,#0CH
MOV R0,A
MOV A,R4
MOV R1,A
MOV A,@R0
MOV @R1,A
INC R4
DJNZ R2,NEW_CI
;%%%%%%%%%%%%%%%SK_GENERATE%%%%%%%%%%%%%% F4-FB SK INSTEND OF GC
SK_GENERATE:
MOV A,R5
ADD A,#0BH
MOV R0,A
MOV @R0,#00H;DATAIN
MOV A,R5
ADD A,#02H
MOV R0,A
MOV A,@R0
MOV R4,A ;ADDR ;SK 存放在(0F)+30-(0F)+37地址
MOV R2,#08H ;4.1
SK_LOOP:
SK0:
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
MOV A,R5
ADD A,#0CH
MOV R0,A
MOV A,R4
MOV R1,A
MOV A,@R0
MOV @R1,A
INC R4
DJNZ R2,SK_LOOP ;4.1
MOV A,R5
ADD A,#0BH
MOV R0,A
MOV @R0,#00H;DATAIN
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
RET
;%%%%%%%%%%%%%%%READ_CI%%%%%%%%%%%%%%%%%%%%%%%%%%
READ_CI:
MOV A,R5
ADD A,#28H
MOV R0,A;得8命令系统地址;存放在(0F)+28-(0F)+2F地址
MOV B,A
MOV @R0,#0B6H
INC R0
MOV @R0,#00H
MOV A,R5
ADD A,#01H
MOV R1,A;得Gc_Pw地址
MOV A,@R1
ANL A,#30H
ADD A,#50H
INC R0 ;ADDR
MOV @R0,A
INC R0
MOV @R0,#08H
INC R0 ;读取存放地址
MOV @R0,B
LCALL READ
RET
;%%%%%%%%%%%%%%%CALCULATE_GC%%%%%%%%%%%%%%%%%%%%%%%%%%
CALCULATE_GC:
MOV A,R5
INC A
MOV R1,A
MOV A,@R1
ANL A,#30H
SWAP A
MOV DPTR,#GC_TABLE
CJNE A,#00H,CHECK_GC1
MOV A,#00H
MOV R1,A
JMP CALCULATE_GC_ADDR
CHECK_GC1:
CJNE A,#01H,CHECK_GC2
MOV A,#08H
MOV R1,A
JMP CALCULATE_GC_ADDR
CHECK_GC2:
CJNE A,#02H,CHECK_GC3
MOV A,#10H
MOV R1,A
JMP CALCULATE_GC_ADDR
CHECK_GC3:
MOV A,#18H
MOV R1,A
;''''''''''''''''''''''''''''''
CALCULATE_GC_ADDR:
MOV A,R5
ADD A,#28H
MOV R0,A
DEC R1
DEC R0
MOV R2,#08H
CALCULATE_G1: ;开始存放GC (0F)+28-(0F)+2F 单元
INC R1
MOV A,R1
MOVC A,@A+DPTR
INC R0
MOV @R0,A
DJNZ R2,CALCULATE_G1
RET
SET_USER_ZONE:
MOV A,R5
ADD A,#28H
MOV R1,A
MOV @R1,#04H ;28 NUMBER
INC R1
MOV @R1,#0B4H ;29 CMD
INC R1
MOV @R1,#03H ;2A #03H
MOV A,R5
MOV R0,A
MOV A,R5
ADD A,#0BH
MOV R1,A
MOV A,@R0
MOV @R1,A
LCALL CRYPTO_DATA
LCALL OUTPUT_STAGE
MOV A,R5
ADD A,#2BH ;2B ;ZONE
MOV R0,A
MOV A,R5
MOV R1,A
MOV A,@R1
MOV @R0,A
INC R0 ;2C
MOV @R0,#00H
LCALL WRITE0104
RET
READ:
MOV R2,#80H
READ_SMSTART:
LCALL SMSTART
MOV R0,#04H ;发送4个字节的命令;必需检查ACK是否是被拉低
MOV A,R5
ADD A,#28H
MOV R1,A;得8命令系统地址
RDDD2: MOV A,@R1 ;READ-CMD
MOV B,#08H
RDDD1:
CLR SDA
JNB ACC.7,RDDD0
SETB SDA
RDDD0: NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
CLR SCL
RL A
NOP
NOP
DJNZ B,RDDD1
SETB SDA
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
RDDDA: JNB SDA,RDDDA2;READ_SMSTART
RDDDA1: DJNZ R2,READ_SMSTART
RDDDA2: INC R1
CLR SCL
NOP
NOP
NOP
DJNZ R0,RDDD2
MOV A,R5
ADD A,#2BH
MOV R0,A
MOV A,@R0
MOV R2,A ;读字节数地址
INC R0;存放数拒首地址
MOV A,@R0
MOV R1,A
RDDDB: MOV B,#08H ;此过程中必需把ACK拉低,但执行读最后一字节的ACK可不拉低
RDDDC: SETB SCL
NOP
NOP
CLR C
JNB SDA,RDDDD
SETB C
RDDDD: RLC A
NOP
NOP
CLR SCL
NOP
NOP
DJNZ B,RDDDC
DJNZ R2,READ_BYTES
JMP BYTE
READ_BYTES:
CLR SDA
NOP
NOP
SETB SCL
NOP
NOP
ACK: JB SDA,ACK
MOV @R1,A
INC R1
NOP
NOP
CLR SCL
NOP
NOP
SETB SDA ;READ_BYTES处使SDA为0,因此要拉高SDA
NOP
NOP
NOP
JMP RDDDB
BYTE:
MOV @R1,A
INC R1
SETB SCL
NOP
NOP
NOP
LCALL SMSTOP;
RET
;---------SMSTART-----------------------
SMSTART:SETB SDA ;先发5个脉冲
NOP
NOP
NOP
SETB SCL
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
SETB SCL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -