1# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 2# 3# Copyright (c) Freescale Semiconductor, Inc 2013. 4# 5# FILE NAME : mmcau_des_functions.s 6# VERSION : $Id: $ 7# TYPE : Source Cortex-M0+ assembly library code 8# DEPARTMENT : MCG R&D Cores and Platforms 9# AUTHOR : Anthony (Teejay) Ciancio 10# AUTHOR EMAIL : teejay.ciancio@freescale.com 11# 12# # # # # # # # # # # # # # # # # # # # # # # # # # # 13# 14# VERSION DATE AUTHOR DESCRIPTION 15# ******* **** ****** *********** 16# 1.0 2013-11 Ciancio initial release, using the ARMv6-M ISA 17# 18# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 19 20 21 .include "cau2_defines.hdr" 22 .syntax unified 23 24 25 .equ MMCAU_PPB_DIRECT, 0xf0005000 26 .equ MMCAU_PPB_INDIRECT, 0xf0005800 27 .equ MMCAU_1_CMD, 0x80000000 28 .equ MMCAU_2_CMDS, 0x80100000 29 .equ MMCAU_3_CMDS, 0x80100200 30 31 32# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 33# 34# MMCAU_DES_CHK_PARITY 35# Check key parity 36# 37# ARGUMENTS 38# *key pointer to 64-bit DES key with parity bits 39# return 0 no error 40# -1 parity error 41# 42# CALLING CONVENTION 43# int mmcau_des_chk_parity (const unsigned char *key) 44# 45# # # # # # # # # # # # # # # # # # # # # # # # # # # 46# 47# REGISTER | ALLOCATION (at the start of mmcau_des_chk_parity) 48# -----------+------------------------------------------------------------ 49# r0 | *key (arg0) 50# | 51# > r0 | irrelevant 52# 53# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 54 55 .global _mmcau_des_chk_parity 56 .global mmcau_des_chk_parity 57 .type mmcau_des_chk_parity, %function 58 .align 4 59 60_mmcau_des_chk_parity: 61mmcau_des_chk_parity: 62 63# load the 64-bit key into the CAU's CA0/CA1 regs 64 ldr r3, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) 65 ldmia r0!, {r1-r2} @ load key 66 str r1, [r3, #0<<2] @ store lower half in CA0 67 str r2, [r3, #1<<2] @ store upper half in CA1 68 69 ldr r1, =MMCAU_PPB_DIRECT 70 ldr r2, =MMCAU_1_CMD+((DESK+CP)<<22) 71 str r2, [r1] @ perform the key schedule 72 73# CASR[31:28] contain the version number, we left-shift that off 74# CASR[27:2] and CASR[0] are always 0 75# CASR[1] is the DPE bit, which equals 1 if parity error or 0 if no error 76 ldr r0, [r3, #(((STR+CASR)-(LDR+CA0))<<2)] @ load CASR 77 lsls r0, #4 @ shift off version number 78 beq mmcau_des_chk_parity_end @ check the DPE bit 79 80# if parity error, 81 movs r0, #1 82 negs r0, r0 @ return -1 83 84# else (no error), 85mmcau_des_chk_parity_end: 86 bx lr @ return 0 87 88 89# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 90# 91# MMCAU_DES_ENCRYPT 92# Encrypts a single 8-byte block 93# 94# ARGUMENTS 95# *in pointer to 8-byte block of input plaintext 96# *key pointer to 64-bit DES key with parity bits 97# *out pointer to 8-byte block of output ciphertext 98# 99# NOTE 100# Input and output blocks may overlap 101# 102# CALLING CONVENTION 103# void mmcau_des_encrypt (const unsigned char *in, 104# const unsigned char *key, 105# unsigned char *out) 106# 107# # # # # # # # # # # # # # # # # # # # # # # # # # # 108# 109# REGISTER | ALLOCATION (at the start of mmcau_des_encrypt) 110# -----------+------------------------------------------------------------ 111# r0 | *in (arg0) 112# r1 | *key (arg1) 113# r2 | *out (arg2) 114# | 115# > r2 | irrelevant 116# 117# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 118 119 .global _mmcau_des_encrypt 120 .global mmcau_des_encrypt 121 .type mmcau_des_encrypt, %function 122 .align 4 123 124_mmcau_des_encrypt: 125mmcau_des_encrypt: 126 127# store regs r4-r7, we need to restore them at the end of the routine 128 push {r4-r7} @ store regs 129 130# load the 64-bit key into the CAU's CA0/CA1 regs 131# load the 64-bit plaintext input block into the CAU's CA2/CA3 regs 132 ldr r7, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) 133 ldmia r1!, {r3-r4} @ load key 134 rev r3, r3 135 rev r4, r4 136 ldmia r0!, {r5-r6} @ load plaintext 137 rev r5, r5 138 rev r6, r6 139# stmia r7!, {r3-r6} @ store in CA[0-3] 140 str r3, [r7, #0<<2] @ expand stmia into str to be interruptible 141 str r4, [r7, #1<<2] 142 str r5, [r7, #2<<2] 143 str r6, [r7, #3<<2] 144 adds r7, #1<<4 145 146# send a series of 17 direct cau commands to perform the DES round operations 147# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESK,DESR+IP+KSL1,DESR+KSL2) 1- 3 148# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 4- 6 149# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL1) 7- 9 150# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 10-12 151# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSL2,DESR+KSL2,DESR+KSL2) 13-15 152# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(DESR+KSL1,DESR+FP) 16-17 153 ldr r0, =encrypt_reg_data 154# ldmia r0, {r0-r1, r3-r6} @ load commands 155 @ make ldmia interuptible in MMCAU 156 adds r0, #1<<2 @ move by 4 byte 157 ldmia r0!, {r1, r3-r6} @ load commands + move by 20 byte 158 subs r0, #3<<3 @ move back by 24byte 159 ldr r0, [r0] @ load rest/first of commands 160 str r3, [r0] @ send commands 1- 3 161 str r4, [r0] @ " " 4- 6 162 str r5, [r0] @ " " 7- 9 163 str r4, [r0] @ " " 10-12 164 str r4, [r0] @ " " 13-15 165 str r6, [r0] @ " " 16-17 166 167# store the 64-bit ciphertext output block into memory 168# ldmia r1, {r0-r1} @ load ciphertext 169 ldr r0, [r1, #0<<2] @ expand ldmia into ldr to be interruptible 170 ldr r1, [r1, #1<<2] 171 rev r0, r0 172 rev r1, r1 173# stmia r2!, {r0-r1} @ store in out[0-1] 174 str r0, [r2, #0<<2] @ expand stmia into str to be interruptible 175 str r1, [r2, #1<<2] 176 adds r2, #2<<2 177 178 pop {r4-r7} @ restore regs 179 bx lr @ exit routine 180 181 182# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 183# 184# MMCAU_DES_DECRYPT 185# Decrypts a single 8-byte block 186# 187# ARGUMENTS 188# *in pointer to 8-byte block of input ciphertext 189# *key pointer to 64-bit DES key with parity bits 190# *out pointer to 8-byte block of output plaintext 191# 192# NOTE 193# Input and output blocks may overlap 194# 195# CALLING CONVENTION 196# void mmcau_des_decrypt (const unsigned char *in, 197# const unsigned char *key, 198# unsigned char *out) 199# 200# # # # # # # # # # # # # # # # # # # # # # # # # # # 201# 202# REGISTER | ALLOCATION (at the start of mmcau_des_decrypt) 203# -----------+------------------------------------------------------------ 204# r0 | *in (arg0) 205# r1 | *key (arg1) 206# r2 | *out (arg2) 207# | 208# > r2 | irrelevant 209# 210# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 211 212 .global _mmcau_des_decrypt 213 .global mmcau_des_decrypt 214 .type mmcau_des_decrypt, %function 215 .align 4 216 217_mmcau_des_decrypt: 218mmcau_des_decrypt: 219 220# store regs r4-r7, we need to restore them at the end of the routine 221 push {r4-r7} @ store regs 222 223# load the 64-bit key into the CAU's CA0/CA1 regs 224# load the 64-bit ciphertext input block into the CAU's CA2/CA3 regs 225 ldr r7, =MMCAU_PPB_INDIRECT+((LDR+CA0)<<2) 226 ldmia r1!, {r3-r4} @ load key 227 rev r3, r3 228 rev r4, r4 229 ldmia r0!, {r5-r6} @ load ciphertext 230 rev r5, r5 231 rev r6, r6 232# stmia r7!, {r3-r6} @ store in CA[0-3] 233 str r3, [r7, #0<<2] @ expand stmia into str to be interruptible 234 str r4, [r7, #1<<2] 235 str r5, [r7, #2<<2] 236 str r6, [r7, #3<<2] 237 adds r7, #1<<4 238 239# send a series of 17 direct cau commands to perform the DES round operations 240# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESK+DC,DESR+IP+KSR1,DESR+KSR2) 1- 3 241# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 4- 6 242# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR1) 7- 9 243# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 10-12 244# *(MMCAU_PPB_DIRECT) = mmcau_3_cmds(DESR+KSR2,DESR+KSR2,DESR+KSR2) 13-15 245# *(MMCAU_PPB_DIRECT) = mmcau_2_cmds(DESR+KSR1,DESR+FP) 16-17 246 ldr r0, =decrypt_reg_data 247# ldmia r0, {r0-r1, r3-r6} @ load commands 248 @ make ldmia interuptible in MMCAU 249 adds r0, #1<<2 @ move by 4 byte 250 ldmia r0!, {r1, r3-r6} @ load commands + move by 20 byte 251 subs r0, #3<<3 @ move back by 24byte 252 ldr r0, [r0] @ load rest/first of commands 253 str r3, [r0] @ send commands 1- 3 254 str r4, [r0] @ " " 4- 6 255 str r5, [r0] @ " " 7- 9 256 str r4, [r0] @ " " 10-12 257 str r4, [r0] @ " " 13-15 258 str r6, [r0] @ " " 16-17 259 260# store the 64-bit plaintext output block into memory 261# ldmia r1, {r0-r1} @ load plaintext 262 ldr r0, [r1, #0<<2] @ expand ldmia into ldr to be interruptible 263 ldr r1, [r1, #1<<2] 264 rev r0, r0 265 rev r1, r1 266# stmia r2!, {r0-r1} @ store in out[0-1] 267 str r0, [r2, #0<<2] @ expand stmia into str to be interruptible 268 str r1, [r2, #1<<2] 269 adds r2, #2<<2 270 271 pop {r4-r7} @ restore regs 272 bx lr @ exit routine 273 274 275# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 276 277 .data 278 279 280 .type encrypt_reg_data, %object 281 .align 4 282 283encrypt_reg_data: 284 .word MMCAU_PPB_DIRECT @ r0 285 .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @ r1 286 .word MMCAU_3_CMDS+((DESK)<<22)+((DESR+IP+KSL1)<<11)+DESR+KSL2 @ r3 287 .word MMCAU_3_CMDS+((DESR+KSL2)<<22)+((DESR+KSL2)<<11)+DESR+KSL2 @ r4 288 .word MMCAU_3_CMDS+((DESR+KSL2)<<22)+((DESR+KSL2)<<11)+DESR+KSL1 @ r5 289 .word MMCAU_2_CMDS+((DESR+KSL1)<<22)+((DESR+FP)<<11) @ r6 290 291 292 .type decrypt_reg_data, %object 293 .align 4 294 295decrypt_reg_data: 296 .word MMCAU_PPB_DIRECT @ r0 297 .word MMCAU_PPB_INDIRECT+((STR+CA2)<<2) @ r1 298 .word MMCAU_3_CMDS+((DESK+DC)<<22)+((DESR+IP+KSR1)<<11)+DESR+KSR2 @ r3 299 .word MMCAU_3_CMDS+((DESR+KSR2)<<22)+((DESR+KSR2)<<11)+DESR+KSR2 @ r4 300 .word MMCAU_3_CMDS+((DESR+KSR2)<<22)+((DESR+KSR2)<<11)+DESR+KSR1 @ r5 301 .word MMCAU_2_CMDS+((DESR+KSR1)<<22)+((DESR+FP)<<11) @ r6 302