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