home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / utilities / cli / pgp2 / src / s / ideaARM < prev    next >
Encoding:
Text File  |  1995-06-07  |  5.1 KB  |  258 lines

  1. ; ARM code version of IDEA stuff, (1) for speed and (2) because
  2. ; Cv5 actually compiles ideaExpandKey *wrongly*.
  3. ; Unfortunately IDEA assumes MSB first, so we have to reverse everything.
  4.  
  5. ; Please see the note at the start of ideaExpandKey regarding
  6. ; alignment.
  7.  
  8. IdeaRounds EQU 8
  9.  
  10. inbuf RN 0
  11. outbuf RN 1
  12. key RN 2
  13. round RN 3
  14. x1 RN 4
  15. x2 RN 5
  16. x3 RN 6
  17. x4 RN 7
  18. t1 RN 8
  19. t2 RN 9
  20. s2 RN 10
  21. s3 RN 11
  22. sp RN 13
  23. lr RN 14
  24. pc RN 15
  25.  
  26. r0 RN 0
  27. r1 RN 1
  28. r2 RN 2
  29. r3 RN 3
  30. r4 RN 4
  31. r5 RN 5
  32. r6 RN 6
  33. r7 RN 7
  34. r8 RN 8
  35. ip RN 12
  36.  
  37.     AREA |A$$Code|, CODE, READONLY
  38.     EXPORT ideaCipher
  39.     EXPORT ideaExpandKey
  40.  
  41. ; r0 -> inbuf (8 bytes)
  42. ; r1 -> outbuf (8 bytes)
  43. ; r2 -> key
  44. ideaCipher
  45.     STMFD sp!,{x1-s3,lr}    ; change if reg nums change!!!!
  46.     MOV round,#IdeaRounds
  47.     MOV s2,#&FF
  48.     LDR t1,[inbuf],#4
  49.     AND x1,s2,t1        ; 1H
  50.     AND t2,s2,t1,LSR#8    ; 1L
  51.     ADD x1,t2,x1,LSL#8    ; x1
  52.     AND x2,s2,t1,LSR#16    ; 2H
  53.     AND t2,s2,t1,LSR#24    ; 2L
  54.     ADD x2,t2,x2,LSL#8    ; x1
  55.     LDR t1,[inbuf]
  56.     AND x3,s2,t1        ; 3H
  57.     AND t2,s2,t1,LSR#8    ; 3L
  58.     ADD x3,t2,x3,LSL#8    ; x3
  59.     AND x4,s2,t1,LSR#16    ; 4H
  60.     AND t2,s2,t1,LSR#24    ; 4L
  61.     ADD x4,t2,x4,LSL#8    ; x4
  62. ic1    ; start of DO loop
  63.     ; MUL(x1,*key++)
  64.     LDR t1,[key],#2
  65.     MOV t1,t1,LSL#16
  66.     MOVS t1,t1,LSR#16
  67.     RSBEQ x1,x1,#1
  68.     BEQ md1
  69.     MOV x1,x1,LSL#16
  70.     MOVS x1,x1,LSR#16
  71.     RSBEQ x1,t1,#1
  72.     BEQ md1
  73.     MUL x1,t1,x1
  74.     MOV t1,x1,LSR#16
  75.     BIC t2,x1,t1,LSL#16
  76.     SUBS x1,t2,t1
  77.     ADDLO x1,x1,#1
  78. md1    ; x2 += *key++; x3 += *key++
  79.     LDR t1,[key],#2
  80.     ADD x2,x2,t1
  81.     LDR t1,[key],#2
  82.     ADD x3,x3,t1
  83.     ; MUL(x4,*key++)
  84.     LDR t1,[key],#2
  85.     MOV t1,t1,LSL#16
  86.     MOVS t1,t1,LSR#16
  87.     RSBEQ x4,x4,#1
  88.     BEQ md2
  89.     MOV x4,x4,LSL#16
  90.     MOVS x4,x4,LSR#16
  91.     RSBEQ x4,t1,#1
  92.     BEQ md2
  93.     MUL x4,t1,x4
  94.     MOV t1,x4,LSR#16
  95.     BIC t2,x4,t1,LSL#16
  96.     SUBS x4,t2,t1
  97.     ADDLO x4,x4,#1
  98. md2    ; s3=x3; x3^=x1
  99.     MOV s3,x3
  100.     EOR x3,x3,x1
  101.     ; MUL(x3,*key++)
  102.     LDR t1,[key],#2
  103.     MOV t1,t1,LSL#16
  104.     MOVS t1,t1,LSR#16
  105.     RSBEQ x3,x3,#1
  106.     BEQ md3
  107.     MOV x3,x3,LSL#16
  108.     MOVS x3,x3,LSR#16
  109.     RSBEQ x3,t1,#1
  110.     BEQ md3
  111.     MUL x3,t1,x3
  112.     MOV t1,x3,LSR#16
  113.     BIC t2,x3,t1,LSL#16
  114.     SUBS x3,t2,t1
  115.     ADDLO x3,x3,#1
  116. md3    ; s2=x2; x2^=x4; x2+=x3
  117.     MOV s2,x2
  118.     EOR x2,x2,x4
  119.     ADD x2,x2,x3
  120.     ; MUL(x2,*key++)
  121.     LDR t1,[key],#2
  122.     MOV t1,t1,LSL#16
  123.     MOVS t1,t1,LSR#16
  124.     RSBEQ x2,x2,#1
  125.     BEQ md4
  126.     MOV x2,x2,LSL#16
  127.     MOVS x2,x2,LSR#16
  128.     RSBEQ x2,t1,#1
  129.     BEQ md4
  130.     MUL x2,t1,x2
  131.     MOV t1,x2,LSR#16
  132.     BIC t2,x2,t1,LSL#16
  133.     SUBS x2,t2,t1
  134.     ADDLO x2,x2,#1
  135. md4    ; x3+=x2; x1^=x2; x4^=x3; x2^=s3; x3^=s2;
  136.     ADD x3,x3,x2
  137.     EOR x1,x1,x2
  138.     EOR x4,x4,x3
  139.     EOR x2,x2,s3
  140.     EOR x3,x3,s2
  141.     ; while (--r);
  142.     SUBS round,round,#1
  143.     BNE ic1
  144.     ; MUL(x1,*key++)
  145.     LDR t1,[key],#2
  146.     MOV t1,t1,LSL#16
  147.     MOVS t1,t1,LSR#16
  148.     RSBEQ x1,x1,#1
  149.     BEQ md5
  150.     MOV x1,x1,LSL#16
  151.     MOVS x1,x1,LSR#16
  152.     RSBEQ x1,t1,#1
  153.     BEQ md5
  154.     MUL x1,t1,x1
  155.     MOV t1,x1,LSR#16
  156.     BIC t2,x1,t1,LSL#16
  157.     SUBS x1,t2,t1
  158.     ADDLO x1,x1,#1
  159. md5    ; x3 += *key++; x2+=*key++
  160.     LDR t1,[key],#2
  161.     ADD x3,x3,t1
  162.     LDR t1,[key],#2
  163.     ADD x2,x2,t1
  164.     ; MUL(x4,*key)
  165.     LDR t1,[key]
  166.     MOV t1,t1,LSL#16
  167.     MOVS t1,t1,LSR#16
  168.     RSBEQ x4,x4,#1
  169.     BEQ md6
  170.     MOV x4,x4,LSL#16
  171.     MOVS x4,x4,LSR#16
  172.     RSBEQ x4,t1,#1
  173.     BEQ md6
  174.     MUL x4,t1,x4
  175.     MOV t1,x4,LSR#16
  176.     BIC t2,x4,t1,LSL#16
  177.     SUBS x4,t2,t1
  178.     ADDLO x4,x4,#1
  179. md6    ; store x1..x4 in outbuf.
  180.     MOV s2,#&FF
  181.     ORR s2,s2,s2,LSL#16    ; s2 = 00 FF 00 FF
  182.     MOV x1,x1,LSL#16    ; x1 = 1H 1L 00 00
  183.     MOV x3,x3,LSL#16    ; x3 = 3H 3L 00 00
  184.     ORR t1,x3,x1,LSR#16    ; t1 = 3H 3L 1H 1L
  185.     AND s3,s2,t1        ; s3 = 00 3L 00 1L
  186.     AND t1,s2,t1,LSR#8    ; t1 = 00 3H 00 1H
  187.     ADD t1,t1,s3,LSL#8    ; t1 = 3L 3H 1L 1H
  188.     STR t1,[outbuf],#4
  189.     MOV x2,x2,LSL#16    ; x2 = 2H 2L 00 00
  190.     MOV x4,x4,LSL#16    ; x4 = 4H 4L 00 00
  191.     ORR t1,x4,x2,LSR#16    ; t1 = 4H 4L 2H 2L
  192.     AND s3,s2,t1        ; s3 = 00 4L 00 2L
  193.     AND t1,s2,t1,LSR#8    ; t1 = 00 4H 00 2H
  194.     ADD t1,t1,s3,LSL#8    ; t1 = 4L 4H 2L 2H
  195.     STR t1,[outbuf]
  196.     ; and we're done. I think.
  197.     LDMFD sp!,{x1-s3,pc}^    ; change if reg nums change!!!!
  198.  
  199. ; r0 -> userkey (byte const *)
  200. ; r1 -> EK (word16 *)
  201. ; NB: this *requires* that EK be 4-aligned. This is always the case
  202. ;     as ideaExpandKey is actually used. However, userkey is often
  203. ;     *not* 4-aligned; it need not even be 2-aligned.
  204. ;     I apologise for the fact that alignment is relevant at all;
  205. ;     this is entirely the result of my stupidity.
  206. ideaExpandKey
  207.     STMFD    sp!,{r4-r8,lr}
  208.     ; First loop: put user key into first 8 EK entries,
  209.     ; swapping bytes because of endianness conflict.
  210.     MOV    r4,#4
  211. l1    LDRB    r3,[r0],#1
  212.     LDRB    r2,[r0],#1
  213.     ADD    r3,r2,r3,LSL#8
  214.     LDRB    r2,[r0],#1
  215.     ADD    r3,r3,r2,LSL#24    ; sic
  216.     LDRB    r2,[r0],#1
  217.     ADD    r3,r3,r2,LSL#16    ; sic
  218.     STR    r3,[r1],#4
  219.     SUBS    r4,r4,#1
  220.     BGT    l1
  221.     ; now we've added 16 bytes to r0 (no longer needed)
  222.     ; and r1 (needs resetting).
  223.     SUB    r0,r1,#16    ; so r0 is now EK
  224.     ; Second loop: we could certainly optimise this way further,
  225.     ; but it's not done very often so we don't bother.
  226.     MOV    ip,#6
  227.     LDMIA    r0!,{r1,r2,r3,r4}
  228.     ; r1: EK[0,1]
  229.     ; r2: EK[2,3]
  230.     ; r3: EK[4,5]
  231.     ; r4: EK[6,7]
  232. l2    MOV    r1,r1,ROR#16
  233.     MOV    r2,r2,ROR#16
  234.     MOV    r3,r3,ROR#16
  235.     MOV    r4,r4,ROR#16
  236.     ; now we have, always, high 16bits first.
  237.     MOV    r5,r1,LSL#25
  238.     ADD    r5,r5,r2,LSR#7    ; r5: 1,2 2,3
  239.     MOV    r6,r2,LSL#25
  240.     ADD    r6,r6,r3,LSR#7    ; r6: 3,4 4,5
  241.     MOV    r7,r3,LSL#25
  242.     ADD    r7,r7,r4,LSR#7    ; r7: 5,6 6,7
  243.     MOV    r8,r4,LSL#25
  244.     ADD    r8,r8,r1,LSR#7    ; r8: 7,0 0,1
  245.     ; get order right again
  246.     MOV    r1,r5,ROR#16
  247.     MOV    r2,r6,ROR#16
  248.     MOV    r3,r7,ROR#16
  249.     MOV    r4,r8,ROR#16
  250.     SUBS    ip,ip,#1
  251.     STMGTIA    r0!,{r1,r2,r3,r4}
  252.     BGT    l2
  253.     STMIA    r0!,{r1,r2}    ; last time only write 4 halfwords
  254.     ; Done. (Phew!)
  255.     LDMFD    sp!,{r4-r8,pc}^
  256.  
  257.     END
  258.