Reconstruction of des.exe/undes.exe

This commit is contained in:
2026-09-09 23:28:46 +02:00
parent b90136f137
commit 5aa37bf374
64 changed files with 13344 additions and 2 deletions
+3
View File
@@ -32,3 +32,6 @@
*.out *.out
*.app *.app
build/
*.bak
.qtcreator
+102
View File
@@ -0,0 +1,102 @@
cmake_minimum_required(VERSION 3.16)
project(des_undes VERSION 1.1.0 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
set(CRYPTLIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cryptlib-0.99")
# CRYPTLIB 0.99 registers all algorithms in crypt.c at startup, so all of the
# original algorithm backends must be linked even though DES/UNDES itself uses
# only CRYPT_ALGO_3DES + CRYPT_MODE_CBC.
add_library(cryptlib099 STATIC
${CRYPTLIB_DIR}/crypt.c
${CRYPTLIB_DIR}/lib_3des.c
${CRYPTLIB_DIR}/lib_des.c
${CRYPTLIB_DIR}/lib_idea.c
${CRYPTLIB_DIR}/lib_mdc.c
${CRYPTLIB_DIR}/lib_null.c
${CRYPTLIB_DIR}/lib_rc4.c
${CRYPTLIB_DIR}/lib_safr.c
${CRYPTLIB_DIR}/idea/idea.c
${CRYPTLIB_DIR}/libdes/3ecb_enc.c
${CRYPTLIB_DIR}/libdes/ecb_enc.c
${CRYPTLIB_DIR}/libdes/pcbc_enc.c
${CRYPTLIB_DIR}/libdes/set_key.c
${CRYPTLIB_DIR}/rc4/rc4.c
${CRYPTLIB_DIR}/safer/safer.c
${CRYPTLIB_DIR}/mdc/shs.c
)
target_include_directories(cryptlib099 PUBLIC
${CRYPTLIB_DIR}
)
# The original makefile used __UNIX__ for Unix builds.
if(UNIX)
target_compile_definitions(cryptlib099 PRIVATE __UNIX__)
endif()
add_library(des_common STATIC des_common.c)
target_include_directories(des_common PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CRYPTLIB_DIR}
)
target_link_libraries(des_common PUBLIC cryptlib099)
add_executable(des des.c)
add_executable(undes undes.c)
target_link_libraries(des PRIVATE des_common)
target_link_libraries(undes PRIVATE des_common)
# des.c and undes.c deliberately retain the original DOS-style <io.h>, read()
# and fileno() calls. POSIX systems have these declarations in <unistd.h>, so
# provide a tiny generated compatibility header without changing the recovered
# source files.
if(UNIX)
set(COMPAT_DIR "${CMAKE_CURRENT_BINARY_DIR}/compat")
file(MAKE_DIRECTORY "${COMPAT_DIR}")
file(WRITE "${COMPAT_DIR}/io.h" "#ifndef DES_COMPAT_IO_H\n#define DES_COMPAT_IO_H\n#include <unistd.h>\n#endif\n")
target_include_directories(des PRIVATE "${COMPAT_DIR}")
target_include_directories(undes PRIVATE "${COMPAT_DIR}")
endif()
# Modern Microsoft C uses underscored names for these POSIX-compatible calls.
#if(MSVC)
# target_compile_definitions(des PRIVATE
# _CRT_SECURE_NO_WARNINGS
# fileno=_fileno
# read=_read
# )
# target_compile_definitions(undes PRIVATE
# _CRT_SECURE_NO_WARNINGS
# fileno=_fileno
# read=_read
# )
# target_compile_definitions(cryptlib099 PRIVATE __WINDOWS__ _CRT_SECURE_NO_WARNINGS)
#endif()
if(MSVC)
target_compile_definitions(cryptlib099 PRIVATE
_CRT_SECURE_NO_WARNINGS
)
target_compile_definitions(des PRIVATE
_CRT_SECURE_NO_WARNINGS
fileno=_fileno
read=_read
)
target_compile_definitions(undes PRIVATE
_CRT_SECURE_NO_WARNINGS
fileno=_fileno
read=_read
)
endif()
install(TARGETS des undes RUNTIME DESTINATION bin)
+815
View File
@@ -0,0 +1,815 @@
/mnt/data/des.img: file format binary
Disassembly of section .data:
000004b0 <.data+0x4b0>:
4b0: c2 33 d2 ret 0xd233
4b3: d3 e8 shr ax,cl
4b5: cb retf
4b6: 55 push bp
4b7: 8b ec mov bp,sp
4b9: 81 ec 3c 05 sub sp,0x53c
4bd: 56 push si
4be: 57 push di
4bf: 1e push ds
4c0: b8 46 0d mov ax,0xd46
4c3: 8e d8 mov ds,ax
4c5: 83 7e 06 02 cmp WORD PTR [bp+0x6],0x2
4c9: 74 03 je 0x4ce
4cb: e9 a0 00 jmp 0x56e
4ce: 1e push ds
4cf: b8 0c 00 mov ax,0xc
4d2: 50 push ax
4d3: c4 5e 08 les bx,DWORD PTR [bp+0x8]
4d6: 26 ff 77 06 push WORD PTR es:[bx+0x6]
4da: 26 ff 77 04 push WORD PTR es:[bx+0x4]
4de: 9a 0f 00 b7 0b call 0xbb7:0xf
4e3: 83 c4 08 add sp,0x8
4e6: 0b c0 or ax,ax
4e8: 75 43 jne 0x52d
4ea: b8 5f 0d mov ax,0xd5f
4ed: 8e c0 mov es,ax
4ef: 26 ff 36 04 00 push WORD PTR es:0x4
4f4: 26 ff 36 02 00 push WORD PTR es:0x2
4f9: 1e push ds
4fa: b8 18 00 mov ax,0x18
4fd: 50 push ax
4fe: 9a 06 00 d7 0b call 0xbd7:0x6
503: 83 c4 08 add sp,0x8
506: b8 5f 0d mov ax,0xd5f
509: 8e c0 mov es,ax
50b: 26 ff 36 0c 00 push WORD PTR es:0xc
510: 26 ff 36 0a 00 push WORD PTR es:0xa
515: 1e push ds
516: b8 1d 00 mov ax,0x1d
519: 50 push ax
51a: 9a 06 00 d7 0b call 0xbd7:0x6
51f: 83 c4 08 add sp,0x8
522: 6a 00 push 0x0
524: 9a 0b 00 55 0a call 0xa55:0xb
529: 44 inc sp
52a: 44 inc sp
52b: eb 41 jmp 0x56e
52d: 1e push ds
52e: b8 20 00 mov ax,0x20
531: 50 push ax
532: c4 5e 08 les bx,DWORD PTR [bp+0x8]
535: 26 ff 77 06 push WORD PTR es:[bx+0x6]
539: 26 ff 77 04 push WORD PTR es:[bx+0x4]
53d: 9a 0f 00 b7 0b call 0xbb7:0xf
542: 83 c4 08 add sp,0x8
545: 0b c0 or ax,ax
547: 75 25 jne 0x56e
549: b8 5f 0d mov ax,0xd5f
54c: 8e c0 mov es,ax
54e: 26 ff 36 04 00 push WORD PTR es:0x4
553: 26 ff 36 02 00 push WORD PTR es:0x2
558: 1e push ds
559: b8 2a 00 mov ax,0x2a
55c: 50 push ax
55d: 9a 06 00 d7 0b call 0xbd7:0x6
562: 83 c4 08 add sp,0x8
565: 6a 00 push 0x0
567: 9a 0b 00 55 0a call 0xa55:0xb
56c: 44 inc sp
56d: 44 inc sp
56e: 83 7e 06 04 cmp WORD PTR [bp+0x6],0x4
572: 74 3e je 0x5b2
574: 1e push ds
575: b8 90 00 mov ax,0x90
578: 50 push ax
579: 1e push ds
57a: b8 7b 00 mov ax,0x7b
57d: 50 push ax
57e: 1e push ds
57f: b8 64 00 mov ax,0x64
582: 50 push ax
583: 1e push ds
584: b8 3b 00 mov ax,0x3b
587: 50 push ax
588: 1e push ds
589: b8 2e 00 mov ax,0x2e
58c: 50 push ax
58d: b8 e0 11 mov ax,0x11e0
590: 50 push ax
591: b8 2a 00 mov ax,0x2a
594: 50 push ax
595: 9a 08 00 9b 0c call 0xc9b:0x8
59a: 83 c4 18 add sp,0x18
59d: 83 7e 06 01 cmp WORD PTR [bp+0x6],0x1
5a1: 75 04 jne 0x5a7
5a3: 33 c0 xor ax,ax
5a5: eb 03 jmp 0x5aa
5a7: b8 02 00 mov ax,0x2
5aa: 50 push ax
5ab: 9a 0b 00 55 0a call 0xa55:0xb
5b0: 44 inc sp
5b1: 44 inc sp
5b2: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5b5: 26 c4 5f 04 les bx,DWORD PTR es:[bx+0x4]
5b9: 8c 46 f6 mov WORD PTR [bp-0xa],es
5bc: 89 5e f4 mov WORD PTR [bp-0xc],bx
5bf: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5c2: 26 c4 5f 08 les bx,DWORD PTR es:[bx+0x8]
5c6: 8c 46 ee mov WORD PTR [bp-0x12],es
5c9: 89 5e ec mov WORD PTR [bp-0x14],bx
5cc: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5cf: 26 c4 5f 0c les bx,DWORD PTR es:[bx+0xc]
5d3: 8c 46 f2 mov WORD PTR [bp-0xe],es
5d6: 89 5e f0 mov WORD PTR [bp-0x10],bx
5d9: 1e push ds
5da: b8 b5 00 mov ax,0xb5
5dd: 50 push ax
5de: ff 76 ee push WORD PTR [bp-0x12]
5e1: ff 76 ec push WORD PTR [bp-0x14]
5e4: 9a 0f 00 b7 0b call 0xbb7:0xf
5e9: 83 c4 08 add sp,0x8
5ec: 0b c0 or ax,ax
5ee: 74 3b je 0x62b
5f0: ff 76 f2 push WORD PTR [bp-0xe]
5f3: ff 76 f0 push WORD PTR [bp-0x10]
5f6: ff 76 ee push WORD PTR [bp-0x12]
5f9: ff 76 ec push WORD PTR [bp-0x14]
5fc: 9a 0f 00 b7 0b call 0xbb7:0xf
601: 83 c4 08 add sp,0x8
604: 0b c0 or ax,ax
606: 75 23 jne 0x62b
608: 1e push ds
609: b8 bb 00 mov ax,0xbb
60c: 50 push ax
60d: 1e push ds
60e: b8 b7 00 mov ax,0xb7
611: 50 push ax
612: b8 e0 11 mov ax,0x11e0
615: 50 push ax
616: b8 2a 00 mov ax,0x2a
619: 50 push ax
61a: 9a 08 00 9b 0c call 0xc9b:0x8
61f: 83 c4 0c add sp,0xc
622: 6a 01 push 0x1
624: 9a 0b 00 55 0a call 0xa55:0xb
629: 44 inc sp
62a: 44 inc sp
62b: 1e push ds
62c: b8 e7 00 mov ax,0xe7
62f: 50 push ax
630: ff 76 ee push WORD PTR [bp-0x12]
633: ff 76 ec push WORD PTR [bp-0x14]
636: 9a 0f 00 b7 0b call 0xbb7:0xf
63b: 83 c4 08 add sp,0x8
63e: 0b c0 or ax,ax
640: 75 0c jne 0x64e
642: c7 46 fa e0 11 mov WORD PTR [bp-0x6],0x11e0
647: c7 46 f8 02 00 mov WORD PTR [bp-0x8],0x2
64c: eb 19 jmp 0x667
64e: 1e push ds
64f: b8 e9 00 mov ax,0xe9
652: 50 push ax
653: ff 76 ee push WORD PTR [bp-0x12]
656: ff 76 ec push WORD PTR [bp-0x14]
659: 9a 45 02 b0 0a call 0xab0:0x245
65e: 83 c4 08 add sp,0x8
661: 89 56 fa mov WORD PTR [bp-0x6],dx
664: 89 46 f8 mov WORD PTR [bp-0x8],ax
667: 1e push ds
668: b8 ec 00 mov ax,0xec
66b: 50 push ax
66c: ff 76 f2 push WORD PTR [bp-0xe]
66f: ff 76 f0 push WORD PTR [bp-0x10]
672: 9a 0f 00 b7 0b call 0xbb7:0xf
677: 83 c4 08 add sp,0x8
67a: 0b c0 or ax,ax
67c: 75 0c jne 0x68a
67e: c7 46 fe e0 11 mov WORD PTR [bp-0x2],0x11e0
683: c7 46 fc 16 00 mov WORD PTR [bp-0x4],0x16
688: eb 19 jmp 0x6a3
68a: 1e push ds
68b: b8 ee 00 mov ax,0xee
68e: 50 push ax
68f: ff 76 f2 push WORD PTR [bp-0xe]
692: ff 76 f0 push WORD PTR [bp-0x10]
695: 9a 45 02 b0 0a call 0xab0:0x245
69a: 83 c4 08 add sp,0x8
69d: 89 56 fe mov WORD PTR [bp-0x2],dx
6a0: 89 46 fc mov WORD PTR [bp-0x4],ax
6a3: ff 76 ee push WORD PTR [bp-0x12]
6a6: ff 76 ec push WORD PTR [bp-0x14]
6a9: ff 76 fa push WORD PTR [bp-0x6]
6ac: ff 76 f8 push WORD PTR [bp-0x8]
6af: 9a 8c 00 a0 00 call 0xa0:0x8c
6b4: 83 c4 08 add sp,0x8
6b7: ff 76 f2 push WORD PTR [bp-0xe]
6ba: ff 76 f0 push WORD PTR [bp-0x10]
6bd: ff 76 fe push WORD PTR [bp-0x2]
6c0: ff 76 fc push WORD PTR [bp-0x4]
6c3: 9a 8c 00 a0 00 call 0xa0:0x8c
6c8: 83 c4 08 add sp,0x8
6cb: ff 76 fe push WORD PTR [bp-0x2]
6ce: ff 76 fc push WORD PTR [bp-0x4]
6d1: 6a 01 push 0x1
6d3: 6a 04 push 0x4
6d5: b8 5f 0d mov ax,0xd5f
6d8: 50 push ax
6d9: b8 06 00 mov ax,0x6
6dc: 50 push ax
6dd: 9a 0a 00 60 0b call 0xb60:0xa
6e2: 83 c4 0c add sp,0xc
6e5: c7 86 ba fe 03 00 mov WORD PTR [bp-0x146],0x3
6eb: c7 86 bc fe 03 00 mov WORD PTR [bp-0x144],0x3
6f1: 68 00 40 push 0x4000
6f4: 9a 0e 00 5d 0a call 0xa5d:0xe
6f9: 44 inc sp
6fa: 44 inc sp
6fb: 89 56 e2 mov WORD PTR [bp-0x1e],dx
6fe: 89 46 e0 mov WORD PTR [bp-0x20],ax
701: 89 56 ea mov WORD PTR [bp-0x16],dx
704: 89 46 e8 mov WORD PTR [bp-0x18],ax
707: 8b 46 e0 mov ax,WORD PTR [bp-0x20]
70a: 0b 46 e2 or ax,WORD PTR [bp-0x1e]
70d: 75 1e jne 0x72d
70f: 1e push ds
710: b8 f1 00 mov ax,0xf1
713: 50 push ax
714: b8 e0 11 mov ax,0x11e0
717: 50 push ax
718: b8 2a 00 mov ax,0x2a
71b: 50 push ax
71c: 9a 08 00 9b 0c call 0xc9b:0x8
721: 83 c4 08 add sp,0x8
724: 6a 01 push 0x1
726: 9a 0b 00 55 0a call 0xa55:0xb
72b: 44 inc sp
72c: 44 inc sp
72d: c4 5e e0 les bx,DWORD PTR [bp-0x20]
730: 83 c3 08 add bx,0x8
733: 8c 46 e6 mov WORD PTR [bp-0x1a],es
736: 89 5e e4 mov WORD PTR [bp-0x1c],bx
739: 9a 38 07 b3 00 call 0xb3:0x738
73e: 16 push ss
73f: 8d 86 be fe lea ax,[bp-0x142]
743: 50 push ax
744: ff b6 bc fe push WORD PTR [bp-0x144]
748: ff b6 ba fe push WORD PTR [bp-0x146]
74c: 9a 66 05 b3 00 call 0xb3:0x566
751: 83 c4 08 add sp,0x8
754: 8b 86 ca fe mov ax,WORD PTR [bp-0x136]
758: 89 46 d6 mov WORD PTR [bp-0x2a],ax
75b: 8b 86 d0 fe mov ax,WORD PTR [bp-0x130]
75f: 89 46 d8 mov WORD PTR [bp-0x28],ax
762: 33 ff xor di,di
764: eb 0b jmp 0x771
766: c4 5e f4 les bx,DWORD PTR [bp-0xc]
769: 26 8a 01 mov al,BYTE PTR es:[bx+di]
76c: 88 83 d6 fe mov BYTE PTR [bp+di-0x12a],al
770: 47 inc di
771: 3b 7e d6 cmp di,WORD PTR [bp-0x2a]
774: 7d 09 jge 0x77f
776: c4 5e f4 les bx,DWORD PTR [bp-0xc]
779: 26 80 39 00 cmp BYTE PTR es:[bx+di],0x0
77d: 75 e7 jne 0x766
77f: eb 06 jmp 0x787
781: c6 83 d6 fe 00 mov BYTE PTR [bp+di-0x12a],0x0
786: 47 inc di
787: 3b 7e d6 cmp di,WORD PTR [bp-0x2a]
78a: 7c f5 jl 0x781
78c: ff b6 bc fe push WORD PTR [bp-0x144]
790: ff b6 ba fe push WORD PTR [bp-0x146]
794: 16 push ss
795: 8d 86 1e fc lea ax,[bp-0x3e2]
799: 50 push ax
79a: 9a 56 07 b3 00 call 0xb3:0x756
79f: 83 c4 08 add sp,0x8
7a2: ff 76 d6 push WORD PTR [bp-0x2a]
7a5: 16 push ss
7a6: 8d 86 d6 fe lea ax,[bp-0x12a]
7aa: 50 push ax
7ab: 16 push ss
7ac: 8d 86 1e fc lea ax,[bp-0x3e2]
7b0: 50 push ax
7b1: 9a c5 09 b3 00 call 0xb3:0x9c5
7b6: 83 c4 0a add sp,0xa
7b9: c7 46 dc 01 00 mov WORD PTR [bp-0x24],0x1
7be: c4 5e f8 les bx,DWORD PTR [bp-0x8]
7c1: 26 8a 47 04 mov al,BYTE PTR es:[bx+0x4]
7c5: 98 cbw
7c6: 89 46 de mov WORD PTR [bp-0x22],ax
7c9: 68 f8 3f push 0x3ff8
7cc: ff 76 e6 push WORD PTR [bp-0x1a]
7cf: ff 76 e4 push WORD PTR [bp-0x1c]
7d2: ff 76 de push WORD PTR [bp-0x22]
7d5: 9a 05 00 50 0b call 0xb50:0x5
7da: 83 c4 08 add sp,0x8
7dd: 89 46 da mov WORD PTR [bp-0x26],ax
7e0: ff 76 da push WORD PTR [bp-0x26]
7e3: 9a 0d 00 a0 00 call 0xa0:0xd
7e8: 44 inc sp
7e9: 44 inc sp
7ea: e9 93 01 jmp 0x980
7ed: 81 7e da f8 3f cmp WORD PTR [bp-0x26],0x3ff8
7f2: 75 4f jne 0x843
7f4: c4 5e e8 les bx,DWORD PTR [bp-0x18]
7f7: 26 8b 47 08 mov ax,WORD PTR es:[bx+0x8]
7fb: 99 cwd
7fc: 33 c2 xor ax,dx
7fe: 2b c2 sub ax,dx
800: f7 d8 neg ax
802: 99 cwd
803: c4 5e e8 les bx,DWORD PTR [bp-0x18]
806: 26 89 57 02 mov WORD PTR es:[bx+0x2],dx
80a: 26 89 07 mov WORD PTR es:[bx],ax
80d: c4 5e e8 les bx,DWORD PTR [bp-0x18]
810: 26 8b 07 mov ax,WORD PTR es:[bx]
813: 26 0b 47 02 or ax,WORD PTR es:[bx+0x2]
817: 75 0e jne 0x827
819: c4 5e e8 les bx,DWORD PTR [bp-0x18]
81c: 26 c7 47 02 ff ff mov WORD PTR es:[bx+0x2],0xffff
822: 26 c7 07 ff ff mov WORD PTR es:[bx],0xffff
827: c4 5e e8 les bx,DWORD PTR [bp-0x18]
82a: 26 8b 47 0c mov ax,WORD PTR es:[bx+0xc]
82e: 99 cwd
82f: 33 c2 xor ax,dx
831: 2b c2 sub ax,dx
833: f7 d8 neg ax
835: 99 cwd
836: c4 5e e8 les bx,DWORD PTR [bp-0x18]
839: 26 89 57 06 mov WORD PTR es:[bx+0x6],dx
83d: 26 89 47 04 mov WORD PTR es:[bx+0x4],ax
841: eb 28 jmp 0x86b
843: 8b 46 da mov ax,WORD PTR [bp-0x26]
846: 99 cwd
847: c4 5e e8 les bx,DWORD PTR [bp-0x18]
84a: 26 89 57 02 mov WORD PTR es:[bx+0x2],dx
84e: 26 89 07 mov WORD PTR es:[bx],ax
851: c4 5e e8 les bx,DWORD PTR [bp-0x18]
854: 26 8b 47 08 mov ax,WORD PTR es:[bx+0x8]
858: 99 cwd
859: 33 c2 xor ax,dx
85b: 2b c2 sub ax,dx
85d: f7 d8 neg ax
85f: 99 cwd
860: c4 5e e8 les bx,DWORD PTR [bp-0x18]
863: 26 89 57 06 mov WORD PTR es:[bx+0x6],dx
867: 26 89 47 04 mov WORD PTR es:[bx+0x4],ax
86b: 68 00 40 push 0x4000
86e: ff 76 e2 push WORD PTR [bp-0x1e]
871: ff 76 e0 push WORD PTR [bp-0x20]
874: 16 push ss
875: 8d 86 1e fc lea ax,[bp-0x3e2]
879: 50 push ax
87a: 9a 1e 0c b3 00 call 0xb3:0xc1e
87f: 83 c4 0a add sp,0xa
882: 83 7e dc 00 cmp WORD PTR [bp-0x24],0x0
886: 75 03 jne 0x88b
888: e9 ad 00 jmp 0x938
88b: 16 push ss
88c: 8d 86 c4 fa lea ax,[bp-0x53c]
890: 50 push ax
891: 16 push ss
892: 8d 86 1e fc lea ax,[bp-0x3e2]
896: 50 push ax
897: 9a ec 06 b3 00 call 0xb3:0x6ec
89c: 83 c4 08 add sp,0x8
89f: 8b 86 d6 fa mov ax,WORD PTR [bp-0x52a]
8a3: 89 86 1c fb mov WORD PTR [bp-0x4e4],ax
8a7: 16 push ss
8a8: 8d 86 dc fa lea ax,[bp-0x524]
8ac: 50 push ax
8ad: 16 push ss
8ae: 8d 86 1e fc lea ax,[bp-0x3e2]
8b2: 50 push ax
8b3: 9a a9 0b b3 00 call 0xb3:0xba9
8b8: 83 c4 08 add sp,0x8
8bb: ff 76 fe push WORD PTR [bp-0x2]
8be: ff 76 fc push WORD PTR [bp-0x4]
8c1: 6a 01 push 0x1
8c3: ff b6 1c fb push WORD PTR [bp-0x4e4]
8c7: 16 push ss
8c8: 8d 86 dc fa lea ax,[bp-0x524]
8cc: 50 push ax
8cd: 9a 0a 00 60 0b call 0xb60:0xa
8d2: 83 c4 0c add sp,0xc
8d5: ff 76 fe push WORD PTR [bp-0x2]
8d8: ff 76 fc push WORD PTR [bp-0x4]
8db: 9a 4a 00 a0 00 call 0xa0:0x4a
8e0: 83 c4 04 add sp,0x4
8e3: 33 f6 xor si,si
8e5: eb 09 jmp 0x8f0
8e7: 8a 82 d6 fe mov al,BYTE PTR [bp+si-0x12a]
8eb: 88 82 1e fb mov BYTE PTR [bp+si-0x4e2],al
8ef: 46 inc si
8f0: 3b 76 d6 cmp si,WORD PTR [bp-0x2a]
8f3: 7c f2 jl 0x8e7
8f5: 68 00 01 push 0x100
8f8: 16 push ss
8f9: 8d 86 1e fb lea ax,[bp-0x4e2]
8fd: 50 push ax
8fe: 16 push ss
8ff: 8d 86 1e fc lea ax,[bp-0x3e2]
903: 50 push ax
904: 9a 1e 0c b3 00 call 0xb3:0xc1e
909: 83 c4 0a add sp,0xa
90c: ff 76 fe push WORD PTR [bp-0x2]
90f: ff 76 fc push WORD PTR [bp-0x4]
912: 6a 01 push 0x1
914: 68 00 01 push 0x100
917: 16 push ss
918: 8d 86 1e fb lea ax,[bp-0x4e2]
91c: 50 push ax
91d: 9a 0a 00 60 0b call 0xb60:0xa
922: 83 c4 0c add sp,0xc
925: ff 76 fe push WORD PTR [bp-0x2]
928: ff 76 fc push WORD PTR [bp-0x4]
92b: 9a 4a 00 a0 00 call 0xa0:0x4a
930: 83 c4 04 add sp,0x4
933: c7 46 dc 00 00 mov WORD PTR [bp-0x24],0x0
938: ff 76 fe push WORD PTR [bp-0x2]
93b: ff 76 fc push WORD PTR [bp-0x4]
93e: 6a 01 push 0x1
940: 68 00 40 push 0x4000
943: ff 76 e2 push WORD PTR [bp-0x1e]
946: ff 76 e0 push WORD PTR [bp-0x20]
949: 9a 0a 00 60 0b call 0xb60:0xa
94e: 83 c4 0c add sp,0xc
951: ff 76 fe push WORD PTR [bp-0x2]
954: ff 76 fc push WORD PTR [bp-0x4]
957: 9a 4a 00 a0 00 call 0xa0:0x4a
95c: 83 c4 04 add sp,0x4
95f: 68 f8 3f push 0x3ff8
962: ff 76 e6 push WORD PTR [bp-0x1a]
965: ff 76 e4 push WORD PTR [bp-0x1c]
968: ff 76 de push WORD PTR [bp-0x22]
96b: 9a 05 00 50 0b call 0xb50:0x5
970: 83 c4 08 add sp,0x8
973: 89 46 da mov WORD PTR [bp-0x26],ax
976: ff 76 da push WORD PTR [bp-0x26]
979: 9a 0d 00 a0 00 call 0xa0:0xd
97e: 44 inc sp
97f: 44 inc sp
980: 83 7e da 00 cmp WORD PTR [bp-0x26],0x0
984: 74 03 je 0x989
986: e9 64 fe jmp 0x7ed
989: 6a 00 push 0x0
98b: ff 76 e2 push WORD PTR [bp-0x1e]
98e: ff 76 e0 push WORD PTR [bp-0x20]
991: 16 push ss
992: 8d 86 1e fc lea ax,[bp-0x3e2]
996: 50 push ax
997: 9a 1e 0c b3 00 call 0xb3:0xc1e
99c: 83 c4 0a add sp,0xa
99f: 16 push ss
9a0: 8d 86 1e fc lea ax,[bp-0x3e2]
9a4: 50 push ax
9a5: 9a 40 09 b3 00 call 0xb3:0x940
9aa: 83 c4 04 add sp,0x4
9ad: 9a 46 07 b3 00 call 0xb3:0x746
9b2: ff 76 e2 push WORD PTR [bp-0x1e]
9b5: ff 76 e0 push WORD PTR [bp-0x20]
9b8: 9a 04 00 5e 0c call 0xc5e:0x4
9bd: 83 c4 04 add sp,0x4
9c0: 8b 56 fa mov dx,WORD PTR [bp-0x6]
9c3: 8b 46 f8 mov ax,WORD PTR [bp-0x8]
9c6: bb 02 00 mov bx,0x2
9c9: b9 e0 11 mov cx,0x11e0
9cc: 3b d1 cmp dx,cx
9ce: 75 04 jne 0x9d4
9d0: 3b c3 cmp ax,bx
9d2: 74 0e je 0x9e2
9d4: ff 76 fa push WORD PTR [bp-0x6]
9d7: ff 76 f8 push WORD PTR [bp-0x8]
9da: 9a 09 00 33 0b call 0xb33:0x9
9df: 83 c4 04 add sp,0x4
9e2: 8b 56 fe mov dx,WORD PTR [bp-0x2]
9e5: 8b 46 fc mov ax,WORD PTR [bp-0x4]
9e8: bb 16 00 mov bx,0x16
9eb: b9 e0 11 mov cx,0x11e0
9ee: 3b d1 cmp dx,cx
9f0: 75 04 jne 0x9f6
9f2: 3b c3 cmp ax,bx
9f4: 74 0e je 0xa04
9f6: ff 76 fe push WORD PTR [bp-0x2]
9f9: ff 76 fc push WORD PTR [bp-0x4]
9fc: 9a 09 00 33 0b call 0xb33:0x9
a01: 83 c4 04 add sp,0x4
a04: 33 c0 xor ax,ax
a06: eb 00 jmp 0xa08
a08: 1f pop ds
a09: 5f pop di
a0a: 5e pop si
a0b: c9 leave
a0c: cb retf
a0d: 55 push bp
a0e: 8b ec mov bp,sp
a10: 1e push ds
a11: b8 56 0d mov ax,0xd56
a14: 8e d8 mov ds,ax
a16: 83 7e 06 ff cmp WORD PTR [bp+0x6],0xffff
a1a: 75 2b jne 0xa47
a1c: 1e push ds
a1d: b8 0a 00 mov ax,0xa
a20: 50 push ax
a21: b8 e0 11 mov ax,0x11e0
a24: 50 push ax
a25: b8 2a 00 mov ax,0x2a
a28: 50 push ax
a29: 9a 08 00 9b 0c call 0xc9b:0x8
a2e: 83 c4 08 add sp,0x8
a31: 1e push ds
a32: b8 31 00 mov ax,0x31
a35: 50 push ax
a36: 9a 0d 00 b6 0c call 0xcb6:0xd
a3b: 83 c4 04 add sp,0x4
a3e: 6a 03 push 0x3
a40: 9a 0b 00 55 0a call 0xa55:0xb
a45: 44 inc sp
a46: 44 inc sp
a47: 1f pop ds
a48: 5d pop bp
a49: cb retf
a4a: 55 push bp
a4b: 8b ec mov bp,sp
a4d: 1e push ds
a4e: b8 56 0d mov ax,0xd56
a51: 8e d8 mov ds,ax
a53: c4 5e 06 les bx,DWORD PTR [bp+0x6]
a56: 26 f7 47 02 10 00 test WORD PTR es:[bx+0x2],0x10
a5c: 74 2b je 0xa89
a5e: 1e push ds
a5f: b8 3a 00 mov ax,0x3a
a62: 50 push ax
a63: b8 e0 11 mov ax,0x11e0
a66: 50 push ax
a67: b8 2a 00 mov ax,0x2a
a6a: 50 push ax
a6b: 9a 08 00 9b 0c call 0xc9b:0x8
a70: 83 c4 08 add sp,0x8
a73: 1e push ds
a74: b8 62 00 mov ax,0x62
a77: 50 push ax
a78: 9a 0d 00 b6 0c call 0xcb6:0xd
a7d: 83 c4 04 add sp,0x4
a80: 6a 03 push 0x3
a82: 9a 0b 00 55 0a call 0xa55:0xb
a87: 44 inc sp
a88: 44 inc sp
a89: 1f pop ds
a8a: 5d pop bp
a8b: cb retf
a8c: 55 push bp
a8d: 8b ec mov bp,sp
a8f: 1e push ds
a90: b8 56 0d mov ax,0xd56
a93: 8e d8 mov ds,ax
a95: 8b 46 06 mov ax,WORD PTR [bp+0x6]
a98: 0b 46 08 or ax,WORD PTR [bp+0x8]
a9b: 75 31 jne 0xace
a9d: ff 76 0c push WORD PTR [bp+0xc]
aa0: ff 76 0a push WORD PTR [bp+0xa]
aa3: 1e push ds
aa4: b8 6b 00 mov ax,0x6b
aa7: 50 push ax
aa8: b8 e0 11 mov ax,0x11e0
aab: 50 push ax
aac: b8 2a 00 mov ax,0x2a
aaf: 50 push ax
ab0: 9a 08 00 9b 0c call 0xc9b:0x8
ab5: 83 c4 0c add sp,0xc
ab8: 1e push ds
ab9: b8 88 00 mov ax,0x88
abc: 50 push ax
abd: 9a 0d 00 b6 0c call 0xcb6:0xd
ac2: 83 c4 04 add sp,0x4
ac5: 6a 03 push 0x3
ac7: 9a 0b 00 55 0a call 0xa55:0xb
acc: 44 inc sp
acd: 44 inc sp
ace: 1f pop ds
acf: 5d pop bp
ad0: cb retf
ad1: 55 push bp
ad2: 8b ec mov bp,sp
ad4: 56 push si
ad5: 1e push ds
ad6: b8 5f 0d mov ax,0xd5f
ad9: 8e d8 mov ds,ax
adb: 33 f6 xor si,si
add: eb 01 jmp 0xae0
adf: 46 inc si
ae0: 8b de mov bx,si
ae2: c1 e3 02 shl bx,0x2
ae5: 8b 97 10 00 mov dx,WORD PTR [bx+0x10]
ae9: 8b 87 0e 00 mov ax,WORD PTR [bx+0xe]
aed: 3b 56 08 cmp dx,WORD PTR [bp+0x8]
af0: 75 05 jne 0xaf7
af2: 3b 46 06 cmp ax,WORD PTR [bp+0x6]
af5: 74 13 je 0xb0a
af7: 8b de mov bx,si
af9: c1 e3 02 shl bx,0x2
afc: 83 bf 10 00 ff cmp WORD PTR [bx+0x10],0xffff
b01: 75 dc jne 0xadf
b03: 83 bf 0e 00 ff cmp WORD PTR [bx+0xe],0xffff
b08: 75 d5 jne 0xadf
b0a: 8b de mov bx,si
b0c: c1 e3 02 shl bx,0x2
b0f: 83 bf 10 00 ff cmp WORD PTR [bx+0x10],0xffff
b14: 75 25 jne 0xb3b
b16: 83 bf 0e 00 ff cmp WORD PTR [bx+0xe],0xffff
b1b: 75 1e jne 0xb3b
b1d: 1e push ds
b1e: b8 5c 05 mov ax,0x55c
b21: 50 push ax
b22: b8 e0 11 mov ax,0x11e0
b25: 50 push ax
b26: b8 2a 00 mov ax,0x2a
b29: 50 push ax
b2a: 9a 08 00 9b 0c call 0xc9b:0x8
b2f: 83 c4 08 add sp,0x8
b32: 6a 01 push 0x1
b34: 9a 0b 00 55 0a call 0xa55:0xb
b39: 44 inc sp
b3a: 44 inc sp
b3b: 1f pop ds
b3c: 5e pop si
b3d: 5d pop bp
b3e: cb retf
b3f: 55 push bp
b40: 8b ec mov bp,sp
b42: 81 ec 9e 02 sub sp,0x29e
b46: 1e push ds
b47: b8 b8 0d mov ax,0xdb8
b4a: 8e d8 mov ds,ax
b4c: 83 3e 08 00 00 cmp WORD PTR ds:0x8,0x0
b51: 75 24 jne 0xb77
b53: 6a 40 push 0x40
b55: 6a 00 push 0x0
b57: 1e push ds
b58: b8 0a 00 mov ax,0xa
b5b: 50 push ax
b5c: 9a 38 00 c0 0b call 0xbc0:0x38
b61: 83 c4 08 add sp,0x8
b64: 1e push ds
b65: b8 0a 00 mov ax,0xa
b68: 50 push ax
b69: 9a 4e 00 c1 0c call 0xcc1:0x4e
b6e: 83 c4 04 add sp,0x4
b71: c7 06 08 00 01 00 mov WORD PTR ds:0x8,0x1
b77: c7 46 fe 02 00 mov WORD PTR [bp-0x2],0x2
b7c: 16 push ss
b7d: 8d 46 fe lea ax,[bp-0x2]
b80: 50 push ax
b81: 6a 04 push 0x4
b83: 6a 01 push 0x1
b85: 16 push ss
b86: 8d 86 62 fd lea ax,[bp-0x29e]
b8a: 50 push ax
b8b: 9a 41 08 b3 00 call 0xb3:0x841
b90: 83 c4 0c add sp,0xc
b93: 6a 40 push 0x40
b95: 1e push ds
b96: b8 0a 00 mov ax,0xa
b99: 50 push ax
b9a: 16 push ss
b9b: 8d 86 62 fd lea ax,[bp-0x29e]
b9f: 50 push ax
ba0: 9a c5 09 b3 00 call 0xb3:0x9c5
ba5: 83 c4 0a add sp,0xa
ba8: c7 46 ac 01 00 mov WORD PTR [bp-0x54],0x1
bad: 6a 40 push 0x40
baf: 1e push ds
bb0: b8 0a 00 mov ax,0xa
bb3: 50 push ax
bb4: 16 push ss
bb5: 8d 86 62 fd lea ax,[bp-0x29e]
bb9: 50 push ax
bba: 9a 1e 0c b3 00 call 0xb3:0xc1e
bbf: 83 c4 0a add sp,0xa
bc2: 16 push ss
bc3: 8d 86 62 fd lea ax,[bp-0x29e]
bc7: 50 push ax
bc8: 9a 40 09 b3 00 call 0xb3:0x940
bcd: 83 c4 04 add sp,0x4
bd0: ff 76 0a push WORD PTR [bp+0xa]
bd3: 1e push ds
bd4: b8 0a 00 mov ax,0xa
bd7: 50 push ax
bd8: ff 76 08 push WORD PTR [bp+0x8]
bdb: ff 76 06 push WORD PTR [bp+0x6]
bde: 9a 02 00 be 0b call 0xbbe:0x2
be3: 83 c4 0a add sp,0xa
be6: 1f pop ds
be7: c9 leave
be8: cb retf
be9: 55 push bp
bea: 8b ec mov bp,sp
bec: 83 ec 04 sub sp,0x4
bef: 56 push si
bf0: 1e push ds
bf1: b8 b8 0d mov ax,0xdb8
bf4: 8e d8 mov ds,ax
bf6: 8b 76 0a mov si,WORD PTR [bp+0xa]
bf9: 8b c6 mov ax,si
bfb: c1 e8 02 shr ax,0x2
bfe: 8b f0 mov si,ax
c00: eb 71 jmp 0xc73
c02: c4 5e 06 les bx,DWORD PTR [bp+0x6]
c05: 26 8b 57 02 mov dx,WORD PTR es:[bx+0x2]
c09: 26 8b 07 mov ax,WORD PTR es:[bx]
c0c: 89 56 fe mov WORD PTR [bp-0x2],dx
c0f: 89 46 fc mov WORD PTR [bp-0x4],ax
c12: 8b 56 fe mov dx,WORD PTR [bp-0x2]
c15: 8b 46 fc mov ax,WORD PTR [bp-0x4]
c18: 25 00 ff and ax,0xff00
c1b: 81 e2 00 ff and dx,0xff00
c1f: b1 08 mov cl,0x8
c21: 9a 97 04 00 00 call 0x0:0x497
c26: 8b 4e fe mov cx,WORD PTR [bp-0x2]
c29: 8b 5e fc mov bx,WORD PTR [bp-0x4]
c2c: 81 e3 ff 00 and bx,0xff
c30: 81 e1 ff 00 and cx,0xff
c34: 52 push dx
c35: 50 push ax
c36: 8b c3 mov ax,bx
c38: 8b d1 mov dx,cx
c3a: b1 08 mov cl,0x8
c3c: 9a 78 04 00 00 call 0x0:0x478
c41: 5b pop bx
c42: 59 pop cx
c43: 0b d8 or bx,ax
c45: 0b ca or cx,dx
c47: 89 4e fe mov WORD PTR [bp-0x2],cx
c4a: 89 5e fc mov WORD PTR [bp-0x4],bx
c4d: 8b 56 fe mov dx,WORD PTR [bp-0x2]
c50: 8b 46 fc mov ax,WORD PTR [bp-0x4]
c53: 8b d0 mov dx,ax
c55: 33 c0 xor ax,ax
c57: 8b 4e fe mov cx,WORD PTR [bp-0x2]
c5a: 8b 5e fc mov bx,WORD PTR [bp-0x4]
c5d: 8b d9 mov bx,cx
c5f: 33 c9 xor cx,cx
c61: 0b c3 or ax,bx
c63: 0b d1 or dx,cx
c65: c4 5e 06 les bx,DWORD PTR [bp+0x6]
c68: 26 89 57 02 mov WORD PTR es:[bx+0x2],dx
c6c: 26 89 07 mov WORD PTR es:[bx],ax
c6f: 83 46 06 04 add WORD PTR [bp+0x6],0x4
c73: 8b c6 mov ax,si
c75: 4e dec si
c76: 0b c0 or ax,ax
c78: 75 88 jne 0xc02
c7a: 1f pop ds
c7b: 5e pop si
c7c: c9 leave
c7d: cb retf
c7e: 55 push bp
c7f: 8b ec mov bp,sp
c81: 83 ec 02 sub sp,0x2
c84: 56 push si
c85: 1e push ds
c86: b8 b8 0d mov ax,0xdb8
c89: 8e d8 mov ds,ax
c8b: 8b 76 0a mov si,WORD PTR [bp+0xa]
c8e: 8b c6 mov ax,si
c90: d1 e8 shr ax,1
c92: 8b f0 mov si,ax
c94: eb 21 jmp 0xcb7
c96: c4 5e 06 les bx,DWORD PTR [bp+0x6]
c99: 26 8b 07 mov ax,WORD PTR es:[bx]
c9c: 89 46 fe mov WORD PTR [bp-0x2],ax
c9f: 8b 46 fe mov ax,WORD PTR [bp-0x2]
ca2: c1 e0 08 shl ax,0x8
ca5: 8b 56 fe mov dx,WORD PTR [bp-0x2]
ca8: c1 ea 08 shr dx,0x8
cab: 0b c2 or ax,dx
cad: c4 5e 06 les bx,DWORD PTR [bp+0x6]
cb0: 26 89 07 mov WORD PTR es:[bx],ax
cb3: 83 46 06 02 add WORD PTR [bp+0x6],0x2
cb7: 8b c6 mov ax,si
cb9: 4e dec si
cba: 0b c0 or ax,ax
cbc: 75 d8 jne 0xc96
cbe: 1f pop ds
cbf: 5e pop si
cc0: c9 leave
cc1: cb retf
cc2: 55 push bp
cc3: 8b ec mov bp,sp
cc5: 1e push ds
cc6: b8 b8 0d mov ax,0xdb8
cc9: 8e d8 mov ds,ax
ccb: c4 5e 06 les bx,DWORD PTR [bp+0x6]
cce: 26 8b 07 mov ax,WORD PTR es:[bx]
cd1: 26 0b 47 02 or ax,WORD PTR es:[bx+0x2]
cd5: 74 37 je 0xd0e
cd7: ff 76 0a push WORD PTR [bp+0xa]
cda: 6a 00 push 0x0
cdc: c4 5e 06 les bx,DWORD PTR [bp+0x6]
cdf: 26 ff 77 02 push WORD PTR es:[bx+0x2]
ce3: 26 ff 37 push WORD PTR es:[bx]
ce6: 9a 38 00 c0 0b call 0xbc0:0x38
ceb: 83 c4 08 add sp,0x8
cee: c4 5e 06 les bx,DWORD PTR [bp+0x6]
cf1: 26 ff 77 02 push WORD PTR es:[bx+0x2]
cf5: 26 ff 37 push WORD PTR es:[bx]
cf8: 9a 04 00 5e 0c call 0xc5e:0x4
cfd: 83 c4 04 add sp,0x4
+598
View File
@@ -0,0 +1,598 @@
/mnt/data/undes.img: file format binary
Disassembly of section .data:
000004b0 <.data+0x4b0>:
4b0: c2 33 d2 ret 0xd233
4b3: d3 e8 shr ax,cl
4b5: cb retf
4b6: 55 push bp
4b7: 8b ec mov bp,sp
4b9: 81 ec 26 05 sub sp,0x526
4bd: 56 push si
4be: 57 push di
4bf: 1e push ds
4c0: b8 49 0d mov ax,0xd49
4c3: 8e d8 mov ds,ax
4c5: 83 7e 06 02 cmp WORD PTR [bp+0x6],0x2
4c9: 74 03 je 0x4ce
4cb: e9 a0 00 jmp 0x56e
4ce: 1e push ds
4cf: b8 0c 00 mov ax,0xc
4d2: 50 push ax
4d3: c4 5e 08 les bx,DWORD PTR [bp+0x8]
4d6: 26 ff 77 06 push WORD PTR es:[bx+0x6]
4da: 26 ff 77 04 push WORD PTR es:[bx+0x4]
4de: 9a 01 00 bb 0b call 0xbbb:0x1
4e3: 83 c4 08 add sp,0x8
4e6: 0b c0 or ax,ax
4e8: 75 43 jne 0x52d
4ea: b8 65 0d mov ax,0xd65
4ed: 8e c0 mov es,ax
4ef: 26 ff 36 0a 00 push WORD PTR es:0xa
4f4: 26 ff 36 08 00 push WORD PTR es:0x8
4f9: 1e push ds
4fa: b8 18 00 mov ax,0x18
4fd: 50 push ax
4fe: 9a 08 00 da 0b call 0xbda:0x8
503: 83 c4 08 add sp,0x8
506: b8 65 0d mov ax,0xd65
509: 8e c0 mov es,ax
50b: 26 ff 36 12 00 push WORD PTR es:0x12
510: 26 ff 36 10 00 push WORD PTR es:0x10
515: 1e push ds
516: b8 1d 00 mov ax,0x1d
519: 50 push ax
51a: 9a 08 00 da 0b call 0xbda:0x8
51f: 83 c4 08 add sp,0x8
522: 6a 00 push 0x0
524: 9a 0d 00 58 0a call 0xa58:0xd
529: 44 inc sp
52a: 44 inc sp
52b: eb 41 jmp 0x56e
52d: 1e push ds
52e: b8 20 00 mov ax,0x20
531: 50 push ax
532: c4 5e 08 les bx,DWORD PTR [bp+0x8]
535: 26 ff 77 06 push WORD PTR es:[bx+0x6]
539: 26 ff 77 04 push WORD PTR es:[bx+0x4]
53d: 9a 01 00 bb 0b call 0xbbb:0x1
542: 83 c4 08 add sp,0x8
545: 0b c0 or ax,ax
547: 75 25 jne 0x56e
549: b8 65 0d mov ax,0xd65
54c: 8e c0 mov es,ax
54e: 26 ff 36 0a 00 push WORD PTR es:0xa
553: 26 ff 36 08 00 push WORD PTR es:0x8
558: 1e push ds
559: b8 2a 00 mov ax,0x2a
55c: 50 push ax
55d: 9a 08 00 da 0b call 0xbda:0x8
562: 83 c4 08 add sp,0x8
565: 6a 00 push 0x0
567: 9a 0d 00 58 0a call 0xa58:0xd
56c: 44 inc sp
56d: 44 inc sp
56e: 83 7e 06 04 cmp WORD PTR [bp+0x6],0x4
572: 74 3e je 0x5b2
574: 1e push ds
575: b8 96 00 mov ax,0x96
578: 50 push ax
579: 1e push ds
57a: b8 7f 00 mov ax,0x7f
57d: 50 push ax
57e: 1e push ds
57f: b8 66 00 mov ax,0x66
582: 50 push ax
583: 1e push ds
584: b8 3b 00 mov ax,0x3b
587: 50 push ax
588: 1e push ds
589: b8 2e 00 mov ax,0x2e
58c: 50 push ax
58d: b8 e6 11 mov ax,0x11e6
590: 50 push ax
591: b8 30 00 mov ax,0x30
594: 50 push ax
595: 9a 0a 00 9e 0c call 0xc9e:0xa
59a: 83 c4 18 add sp,0x18
59d: 83 7e 06 01 cmp WORD PTR [bp+0x6],0x1
5a1: 75 04 jne 0x5a7
5a3: 33 c0 xor ax,ax
5a5: eb 03 jmp 0x5aa
5a7: b8 02 00 mov ax,0x2
5aa: 50 push ax
5ab: 9a 0d 00 58 0a call 0xa58:0xd
5b0: 44 inc sp
5b1: 44 inc sp
5b2: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5b5: 26 c4 5f 04 les bx,DWORD PTR es:[bx+0x4]
5b9: 8c 46 f6 mov WORD PTR [bp-0xa],es
5bc: 89 5e f4 mov WORD PTR [bp-0xc],bx
5bf: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5c2: 26 c4 5f 08 les bx,DWORD PTR es:[bx+0x8]
5c6: 8c 46 ee mov WORD PTR [bp-0x12],es
5c9: 89 5e ec mov WORD PTR [bp-0x14],bx
5cc: c4 5e 08 les bx,DWORD PTR [bp+0x8]
5cf: 26 c4 5f 0c les bx,DWORD PTR es:[bx+0xc]
5d3: 8c 46 f2 mov WORD PTR [bp-0xe],es
5d6: 89 5e f0 mov WORD PTR [bp-0x10],bx
5d9: 1e push ds
5da: b8 bb 00 mov ax,0xbb
5dd: 50 push ax
5de: ff 76 ee push WORD PTR [bp-0x12]
5e1: ff 76 ec push WORD PTR [bp-0x14]
5e4: 9a 01 00 bb 0b call 0xbbb:0x1
5e9: 83 c4 08 add sp,0x8
5ec: 0b c0 or ax,ax
5ee: 74 3b je 0x62b
5f0: ff 76 f2 push WORD PTR [bp-0xe]
5f3: ff 76 f0 push WORD PTR [bp-0x10]
5f6: ff 76 ee push WORD PTR [bp-0x12]
5f9: ff 76 ec push WORD PTR [bp-0x14]
5fc: 9a 01 00 bb 0b call 0xbbb:0x1
601: 83 c4 08 add sp,0x8
604: 0b c0 or ax,ax
606: 75 23 jne 0x62b
608: 1e push ds
609: b8 c1 00 mov ax,0xc1
60c: 50 push ax
60d: 1e push ds
60e: b8 bd 00 mov ax,0xbd
611: 50 push ax
612: b8 e6 11 mov ax,0x11e6
615: 50 push ax
616: b8 30 00 mov ax,0x30
619: 50 push ax
61a: 9a 0a 00 9e 0c call 0xc9e:0xa
61f: 83 c4 0c add sp,0xc
622: 6a 01 push 0x1
624: 9a 0d 00 58 0a call 0xa58:0xd
629: 44 inc sp
62a: 44 inc sp
62b: 1e push ds
62c: b8 ed 00 mov ax,0xed
62f: 50 push ax
630: ff 76 ee push WORD PTR [bp-0x12]
633: ff 76 ec push WORD PTR [bp-0x14]
636: 9a 01 00 bb 0b call 0xbbb:0x1
63b: 83 c4 08 add sp,0x8
63e: 0b c0 or ax,ax
640: 75 0c jne 0x64e
642: c7 46 fa e6 11 mov WORD PTR [bp-0x6],0x11e6
647: c7 46 f8 08 00 mov WORD PTR [bp-0x8],0x8
64c: eb 19 jmp 0x667
64e: 1e push ds
64f: b8 ef 00 mov ax,0xef
652: 50 push ax
653: ff 76 ee push WORD PTR [bp-0x12]
656: ff 76 ec push WORD PTR [bp-0x14]
659: 9a 47 02 b3 0a call 0xab3:0x247
65e: 83 c4 08 add sp,0x8
661: 89 56 fa mov WORD PTR [bp-0x6],dx
664: 89 46 f8 mov WORD PTR [bp-0x8],ax
667: 1e push ds
668: b8 f2 00 mov ax,0xf2
66b: 50 push ax
66c: ff 76 f2 push WORD PTR [bp-0xe]
66f: ff 76 f0 push WORD PTR [bp-0x10]
672: 9a 01 00 bb 0b call 0xbbb:0x1
677: 83 c4 08 add sp,0x8
67a: 0b c0 or ax,ax
67c: 75 0c jne 0x68a
67e: c7 46 fe e6 11 mov WORD PTR [bp-0x2],0x11e6
683: c7 46 fc 1c 00 mov WORD PTR [bp-0x4],0x1c
688: eb 19 jmp 0x6a3
68a: 1e push ds
68b: b8 f4 00 mov ax,0xf4
68e: 50 push ax
68f: ff 76 f2 push WORD PTR [bp-0xe]
692: ff 76 f0 push WORD PTR [bp-0x10]
695: 9a 47 02 b3 0a call 0xab3:0x247
69a: 83 c4 08 add sp,0x8
69d: 89 56 fe mov WORD PTR [bp-0x2],dx
6a0: 89 46 fc mov WORD PTR [bp-0x4],ax
6a3: ff 76 ee push WORD PTR [bp-0x12]
6a6: ff 76 ec push WORD PTR [bp-0x14]
6a9: ff 76 fa push WORD PTR [bp-0x6]
6ac: ff 76 f8 push WORD PTR [bp-0x8]
6af: 9a 8e 00 a3 00 call 0xa3:0x8e
6b4: 83 c4 08 add sp,0x8
6b7: ff 76 f2 push WORD PTR [bp-0xe]
6ba: ff 76 f0 push WORD PTR [bp-0x10]
6bd: ff 76 fe push WORD PTR [bp-0x2]
6c0: ff 76 fc push WORD PTR [bp-0x4]
6c3: 9a 8e 00 a3 00 call 0xa3:0x8e
6c8: 83 c4 08 add sp,0x8
6cb: c7 86 7a fd 03 00 mov WORD PTR [bp-0x286],0x3
6d1: c7 86 7c fd 03 00 mov WORD PTR [bp-0x284],0x3
6d7: c7 86 ea fe 01 00 mov WORD PTR [bp-0x116],0x1
6dd: 68 00 40 push 0x4000
6e0: 9a 00 00 61 0a call 0xa61:0x0
6e5: 44 inc sp
6e6: 44 inc sp
6e7: 89 96 e0 fe mov WORD PTR [bp-0x120],dx
6eb: 89 86 de fe mov WORD PTR [bp-0x122],ax
6ef: c4 9e de fe les bx,DWORD PTR [bp-0x122]
6f3: 83 c3 08 add bx,0x8
6f6: 8c 86 e4 fe mov WORD PTR [bp-0x11c],es
6fa: 89 9e e2 fe mov WORD PTR [bp-0x11e],bx
6fe: 8b 86 de fe mov ax,WORD PTR [bp-0x122]
702: 0b 86 e0 fe or ax,WORD PTR [bp-0x120]
706: 75 1e jne 0x726
708: 1e push ds
709: b8 f7 00 mov ax,0xf7
70c: 50 push ax
70d: b8 e6 11 mov ax,0x11e6
710: 50 push ax
711: b8 30 00 mov ax,0x30
714: 50 push ax
715: 9a 0a 00 9e 0c call 0xc9e:0xa
71a: 83 c4 08 add sp,0x8
71d: 6a 01 push 0x1
71f: 9a 0d 00 58 0a call 0xa58:0xd
724: 44 inc sp
725: 44 inc sp
726: c4 9e de fe les bx,DWORD PTR [bp-0x122]
72a: 8c 86 e8 fe mov WORD PTR [bp-0x118],es
72e: 89 9e e6 fe mov WORD PTR [bp-0x11a],bx
732: 9a 2a 07 b7 00 call 0xb7:0x72a
737: 16 push ss
738: 8d 86 7e fd lea ax,[bp-0x282]
73c: 50 push ax
73d: ff b6 7c fd push WORD PTR [bp-0x284]
741: ff b6 7a fd push WORD PTR [bp-0x286]
745: 9a 58 05 b7 00 call 0xb7:0x558
74a: 83 c4 08 add sp,0x8
74d: 8b 86 8a fd mov ax,WORD PTR [bp-0x276]
751: 89 86 d6 fe mov WORD PTR [bp-0x12a],ax
755: 8b 86 90 fd mov ax,WORD PTR [bp-0x270]
759: 89 86 d8 fe mov WORD PTR [bp-0x128],ax
75d: 33 ff xor di,di
75f: eb 0b jmp 0x76c
761: c4 5e f4 les bx,DWORD PTR [bp-0xc]
764: 26 8a 01 mov al,BYTE PTR es:[bx+di]
767: 88 83 96 fd mov BYTE PTR [bp+di-0x26a],al
76b: 47 inc di
76c: 3b be d6 fe cmp di,WORD PTR [bp-0x12a]
770: 7d 09 jge 0x77b
772: c4 5e f4 les bx,DWORD PTR [bp-0xc]
775: 26 80 39 00 cmp BYTE PTR es:[bx+di],0x0
779: 75 e6 jne 0x761
77b: eb 06 jmp 0x783
77d: c6 83 96 fd 00 mov BYTE PTR [bp+di-0x26a],0x0
782: 47 inc di
783: 3b be d6 fe cmp di,WORD PTR [bp-0x12a]
787: 7c f4 jl 0x77d
789: b8 65 0d mov ax,0xd65
78c: 8e c0 mov es,ax
78e: 26 c7 06 0e 00 ff ff mov WORD PTR es:0xe,0xffff
795: 26 c7 06 0c 00 ff ff mov WORD PTR es:0xc,0xffff
79c: c4 5e f8 les bx,DWORD PTR [bp-0x8]
79f: 26 8a 47 04 mov al,BYTE PTR es:[bx+0x4]
7a3: 98 cbw
7a4: 89 86 dc fe mov WORD PTR [bp-0x124],ax
7a8: 6a 04 push 0x4
7aa: b8 65 0d mov ax,0xd65
7ad: 50 push ax
7ae: b8 0c 00 mov ax,0xc
7b1: 50 push ax
7b2: ff b6 dc fe push WORD PTR [bp-0x124]
7b6: 9a 07 00 53 0b call 0xb53:0x7
7bb: 83 c4 08 add sp,0x8
7be: 89 86 da fe mov WORD PTR [bp-0x126],ax
7c2: ff b6 da fe push WORD PTR [bp-0x126]
7c6: 9a 0f 00 a3 00 call 0xa3:0xf
7cb: 44 inc sp
7cc: 44 inc sp
7cd: b8 65 0d mov ax,0xd65
7d0: 8e c0 mov es,ax
7d2: 26 ff 36 0e 00 push WORD PTR es:0xe
7d7: 26 ff 36 0c 00 push WORD PTR es:0xc
7dc: 9a 03 00 b0 00 call 0xb0:0x3
7e1: 83 c4 04 add sp,0x4
7e4: ff b6 7c fd push WORD PTR [bp-0x284]
7e8: ff b6 7a fd push WORD PTR [bp-0x286]
7ec: 16 push ss
7ed: 8d 86 de fa lea ax,[bp-0x522]
7f1: 50 push ax
7f2: 9a 48 07 b7 00 call 0xb7:0x748
7f7: 83 c4 08 add sp,0x8
7fa: ff b6 d6 fe push WORD PTR [bp-0x12a]
7fe: 16 push ss
7ff: 8d 86 96 fd lea ax,[bp-0x26a]
803: 50 push ax
804: 16 push ss
805: 8d 86 de fa lea ax,[bp-0x522]
809: 50 push ax
80a: 9a b7 09 b7 00 call 0xb7:0x9b7
80f: 83 c4 0a add sp,0xa
812: 16 push ss
813: 8d 86 7e fd lea ax,[bp-0x282]
817: 50 push ax
818: 16 push ss
819: 8d 86 de fa lea ax,[bp-0x522]
81d: 50 push ax
81e: 9a de 06 b7 00 call 0xb7:0x6de
823: 83 c4 08 add sp,0x8
826: 8b 86 90 fd mov ax,WORD PTR [bp-0x270]
82a: 89 86 d8 fe mov WORD PTR [bp-0x128],ax
82e: ff b6 d8 fe push WORD PTR [bp-0x128]
832: 16 push ss
833: 8d 86 96 fe lea ax,[bp-0x16a]
837: 50 push ax
838: ff b6 dc fe push WORD PTR [bp-0x124]
83c: 9a 07 00 53 0b call 0xb53:0x7
841: 83 c4 08 add sp,0x8
844: 89 86 da fe mov WORD PTR [bp-0x126],ax
848: ff b6 da fe push WORD PTR [bp-0x126]
84c: 9a 0f 00 a3 00 call 0xa3:0xf
851: 44 inc sp
852: 44 inc sp
853: ff b6 d8 fe push WORD PTR [bp-0x128]
857: 16 push ss
858: 8d 86 96 fe lea ax,[bp-0x16a]
85c: 50 push ax
85d: 16 push ss
85e: 8d 86 de fa lea ax,[bp-0x522]
862: 50 push ax
863: 9a 90 0a b7 00 call 0xb7:0xa90
868: 83 c4 0a add sp,0xa
86b: 68 00 01 push 0x100
86e: 16 push ss
86f: 8d 86 ec fe lea ax,[bp-0x114]
873: 50 push ax
874: ff b6 dc fe push WORD PTR [bp-0x124]
878: 9a 07 00 53 0b call 0xb53:0x7
87d: 83 c4 08 add sp,0x8
880: 89 86 da fe mov WORD PTR [bp-0x126],ax
884: ff b6 da fe push WORD PTR [bp-0x126]
888: 9a 0f 00 a3 00 call 0xa3:0xf
88d: 44 inc sp
88e: 44 inc sp
88f: 68 00 40 push 0x4000
892: ff b6 e0 fe push WORD PTR [bp-0x120]
896: ff b6 de fe push WORD PTR [bp-0x122]
89a: ff b6 dc fe push WORD PTR [bp-0x124]
89e: 9a 07 00 53 0b call 0xb53:0x7
8a3: 83 c4 08 add sp,0x8
8a6: 89 86 da fe mov WORD PTR [bp-0x126],ax
8aa: ff b6 da fe push WORD PTR [bp-0x126]
8ae: 9a 0f 00 a3 00 call 0xa3:0xf
8b3: 44 inc sp
8b4: 44 inc sp
8b5: e9 f5 00 jmp 0x9ad
8b8: 68 00 40 push 0x4000
8bb: ff b6 e0 fe push WORD PTR [bp-0x120]
8bf: ff b6 de fe push WORD PTR [bp-0x122]
8c3: 16 push ss
8c4: 8d 86 de fa lea ax,[bp-0x522]
8c8: 50 push ax
8c9: 9a ec 0c b7 00 call 0xb7:0xcec
8ce: 83 c4 0a add sp,0xa
8d1: c4 9e e6 fe les bx,DWORD PTR [bp-0x11a]
8d5: 26 8b 57 02 mov dx,WORD PTR es:[bx+0x2]
8d9: 26 8b 07 mov ax,WORD PTR es:[bx]
8dc: 89 96 dc fa mov WORD PTR [bp-0x524],dx
8e0: 89 86 da fa mov WORD PTR [bp-0x526],ax
8e4: 83 be dc fa 00 cmp WORD PTR [bp-0x524],0x0
8e9: 7f 15 jg 0x900
8eb: 7c 07 jl 0x8f4
8ed: 83 be da fa 00 cmp WORD PTR [bp-0x526],0x0
8f2: 73 0c jae 0x900
8f4: c7 86 dc fa 00 00 mov WORD PTR [bp-0x524],0x0
8fa: c7 86 da fa f8 3f mov WORD PTR [bp-0x526],0x3ff8
900: 83 be ea fe 00 cmp WORD PTR [bp-0x116],0x0
905: 74 56 je 0x95d
907: 68 00 01 push 0x100
90a: 16 push ss
90b: 8d 86 ec fe lea ax,[bp-0x114]
90f: 50 push ax
910: 16 push ss
911: 8d 86 de fa lea ax,[bp-0x522]
915: 50 push ax
916: 9a ec 0c b7 00 call 0xb7:0xcec
91b: 83 c4 0a add sp,0xa
91e: 33 f6 xor si,si
920: eb 01 jmp 0x923
922: 46 inc si
923: 3b b6 d6 fe cmp si,WORD PTR [bp-0x12a]
927: 7d 0a jge 0x933
929: 8a 82 ec fe mov al,BYTE PTR [bp+si-0x114]
92d: 3a 82 96 fd cmp al,BYTE PTR [bp+si-0x26a]
931: 74 ef je 0x922
933: 3b b6 d6 fe cmp si,WORD PTR [bp-0x12a]
937: 74 1e je 0x957
939: 1e push ds
93a: b8 0e 01 mov ax,0x10e
93d: 50 push ax
93e: b8 e6 11 mov ax,0x11e6
941: 50 push ax
942: b8 30 00 mov ax,0x30
945: 50 push ax
946: 9a 0a 00 9e 0c call 0xc9e:0xa
94b: 83 c4 08 add sp,0x8
94e: 6a 01 push 0x1
950: 9a 0d 00 58 0a call 0xa58:0xd
955: 44 inc sp
956: 44 inc sp
957: c7 86 ea fe 00 00 mov WORD PTR [bp-0x116],0x0
95d: ff 76 fe push WORD PTR [bp-0x2]
960: ff 76 fc push WORD PTR [bp-0x4]
963: 6a 01 push 0x1
965: ff b6 da fa push WORD PTR [bp-0x526]
969: ff b6 e4 fe push WORD PTR [bp-0x11c]
96d: ff b6 e2 fe push WORD PTR [bp-0x11e]
971: 9a 0c 00 63 0b call 0xb63:0xc
976: 83 c4 0c add sp,0xc
979: ff 76 fe push WORD PTR [bp-0x2]
97c: ff 76 fc push WORD PTR [bp-0x4]
97f: 9a 4c 00 a3 00 call 0xa3:0x4c
984: 83 c4 04 add sp,0x4
987: 68 00 40 push 0x4000
98a: ff b6 e0 fe push WORD PTR [bp-0x120]
98e: ff b6 de fe push WORD PTR [bp-0x122]
992: ff b6 dc fe push WORD PTR [bp-0x124]
996: 9a 07 00 53 0b call 0xb53:0x7
99b: 83 c4 08 add sp,0x8
99e: 89 86 da fe mov WORD PTR [bp-0x126],ax
9a2: ff b6 da fe push WORD PTR [bp-0x126]
9a6: 9a 0f 00 a3 00 call 0xa3:0xf
9ab: 44 inc sp
9ac: 44 inc sp
9ad: 83 be da fe 00 cmp WORD PTR [bp-0x126],0x0
9b2: 74 03 je 0x9b7
9b4: e9 01 ff jmp 0x8b8
9b7: 6a 00 push 0x0
9b9: ff b6 e0 fe push WORD PTR [bp-0x120]
9bd: ff b6 de fe push WORD PTR [bp-0x122]
9c1: 16 push ss
9c2: 8d 86 de fa lea ax,[bp-0x522]
9c6: 50 push ax
9c7: 9a ec 0c b7 00 call 0xb7:0xcec
9cc: 83 c4 0a add sp,0xa
9cf: 16 push ss
9d0: 8d 86 de fa lea ax,[bp-0x522]
9d4: 50 push ax
9d5: 9a 32 09 b7 00 call 0xb7:0x932
9da: 83 c4 04 add sp,0x4
9dd: 9a 38 07 b7 00 call 0xb7:0x738
9e2: ff b6 e0 fe push WORD PTR [bp-0x120]
9e6: ff b6 de fe push WORD PTR [bp-0x122]
9ea: 9a 06 00 61 0c call 0xc61:0x6
9ef: 83 c4 04 add sp,0x4
9f2: 8b 56 fa mov dx,WORD PTR [bp-0x6]
9f5: 8b 46 f8 mov ax,WORD PTR [bp-0x8]
9f8: bb 08 00 mov bx,0x8
9fb: b9 e6 11 mov cx,0x11e6
9fe: 3b d1 cmp dx,cx
a00: 75 04 jne 0xa06
a02: 3b c3 cmp ax,bx
a04: 74 0e je 0xa14
a06: ff 76 fa push WORD PTR [bp-0x6]
a09: ff 76 f8 push WORD PTR [bp-0x8]
a0c: 9a 0b 00 36 0b call 0xb36:0xb
a11: 83 c4 04 add sp,0x4
a14: 8b 56 fe mov dx,WORD PTR [bp-0x2]
a17: 8b 46 fc mov ax,WORD PTR [bp-0x4]
a1a: bb 1c 00 mov bx,0x1c
a1d: b9 e6 11 mov cx,0x11e6
a20: 3b d1 cmp dx,cx
a22: 75 04 jne 0xa28
a24: 3b c3 cmp ax,bx
a26: 74 0e je 0xa36
a28: ff 76 fe push WORD PTR [bp-0x2]
a2b: ff 76 fc push WORD PTR [bp-0x4]
a2e: 9a 0b 00 36 0b call 0xb36:0xb
a33: 83 c4 04 add sp,0x4
a36: 33 c0 xor ax,ax
a38: eb 00 jmp 0xa3a
a3a: 1f pop ds
a3b: 5f pop di
a3c: 5e pop si
a3d: c9 leave
a3e: cb retf
a3f: 55 push bp
a40: 8b ec mov bp,sp
a42: 1e push ds
a43: b8 5d 0d mov ax,0xd5d
a46: 8e d8 mov ds,ax
a48: 83 7e 06 ff cmp WORD PTR [bp+0x6],0xffff
a4c: 75 2b jne 0xa79
a4e: 1e push ds
a4f: b8 00 00 mov ax,0x0
a52: 50 push ax
a53: b8 e6 11 mov ax,0x11e6
a56: 50 push ax
a57: b8 30 00 mov ax,0x30
a5a: 50 push ax
a5b: 9a 0a 00 9e 0c call 0xc9e:0xa
a60: 83 c4 08 add sp,0x8
a63: 1e push ds
a64: b8 27 00 mov ax,0x27
a67: 50 push ax
a68: 9a 0f 00 b9 0c call 0xcb9:0xf
a6d: 83 c4 04 add sp,0x4
a70: 6a 03 push 0x3
a72: 9a 0d 00 58 0a call 0xa58:0xd
a77: 44 inc sp
a78: 44 inc sp
a79: 1f pop ds
a7a: 5d pop bp
a7b: cb retf
a7c: 55 push bp
a7d: 8b ec mov bp,sp
a7f: 1e push ds
a80: b8 5d 0d mov ax,0xd5d
a83: 8e d8 mov ds,ax
a85: c4 5e 06 les bx,DWORD PTR [bp+0x6]
a88: 26 f7 47 02 10 00 test WORD PTR es:[bx+0x2],0x10
a8e: 74 2b je 0xabb
a90: 1e push ds
a91: b8 30 00 mov ax,0x30
a94: 50 push ax
a95: b8 e6 11 mov ax,0x11e6
a98: 50 push ax
a99: b8 30 00 mov ax,0x30
a9c: 50 push ax
a9d: 9a 0a 00 9e 0c call 0xc9e:0xa
aa2: 83 c4 08 add sp,0x8
aa5: 1e push ds
aa6: b8 58 00 mov ax,0x58
aa9: 50 push ax
aaa: 9a 0f 00 b9 0c call 0xcb9:0xf
aaf: 83 c4 04 add sp,0x4
ab2: 6a 03 push 0x3
ab4: 9a 0d 00 58 0a call 0xa58:0xd
ab9: 44 inc sp
aba: 44 inc sp
abb: 1f pop ds
abc: 5d pop bp
abd: cb retf
abe: 55 push bp
abf: 8b ec mov bp,sp
ac1: 1e push ds
ac2: b8 5d 0d mov ax,0xd5d
ac5: 8e d8 mov ds,ax
ac7: 8b 46 06 mov ax,WORD PTR [bp+0x6]
aca: 0b 46 08 or ax,WORD PTR [bp+0x8]
acd: 75 31 jne 0xb00
acf: ff 76 0c push WORD PTR [bp+0xc]
ad2: ff 76 0a push WORD PTR [bp+0xa]
ad5: 1e push ds
ad6: b8 61 00 mov ax,0x61
ad9: 50 push ax
ada: b8 e6 11 mov ax,0x11e6
add: 50 push ax
ade: b8 30 00 mov ax,0x30
ae1: 50 push ax
ae2: 9a 0a 00 9e 0c call 0xc9e:0xa
ae7: 83 c4 0c add sp,0xc
aea: 1e push ds
aeb: b8 7e 00 mov ax,0x7e
aee: 50 push ax
aef: 9a 0f 00 b9 0c call 0xcb9:0xf
af4: 83 c4 04 add sp,0x4
af7: 6a 03 push 0x3
af9: 9a 0d 00 58 0a call 0xa58:0xd
afe: 44 inc sp
aff: 44 inc sp
b00: 1f pop ds
b01: 5d pop bp
b02: cb retf
b03: 55 push bp
b04: 8b ec mov bp,sp
b06: 56 push si
b07: 1e push ds
b08: b8 65 0d mov ax,0xd65
b0b: 8e d8 mov ds,ax
b0d: 33 f6 xor si,si
b0f: eb 01 jmp 0xb12
b11: 46 inc si
b12: 8b de mov bx,si
b14: c1 e3 02 shl bx,0x2
b17: 8b 97 16 00 mov dx,WORD PTR [bx+0x16]
b1b: 8b 87 14 00 mov ax,WORD PTR [bx+0x14]
b1f: 3b cmp dx,WORD PTR [bp+0x8]
+37 -2
View File
@@ -1,3 +1,38 @@
# des_undes # DES/UNDES V1.1.0 source reconstruction — v2
Old des/undes code based on libdes-3.14. This directory contains a revised C reconstruction of `des.exe` and
`undes.exe` after comparison with the original `cryptl99.zip` dependency.
## Main files
- `des.c` — reconstructed encryption program
- `undes.c` — reconstructed decryption program
- `des_common.c`, `des_common.h` — reconstructed common support
- `reconstruction-notes.md` — evidence, file format and remaining uncertainty
- `cryptlib-api-map.md` — exact CRYPTLIB 0.99 function mapping
- `validation.md` — build/round-trip sanity check
- `asm/` — disassembly used for the reconstruction
- `third_party/cryptl99.zip` — user-supplied original archive
- `third_party/cryptlib-0.99/` — extracted dependency source
## What changed from the first reconstruction
The supplied CRYPTLIB source resolves several earlier uncertainties and one
important mistake:
1. The real API names are lower-case (`initLibrary`,
`queryAlgoModeInformation`, `retrieveIV`, etc.).
2. The executable uses `CRYPT_ALGO_3DES`, not `CRYPT_ALGO_DES`.
3. The mode is `CRYPT_MODE_CBC`.
4. The effective queried key size is 14 bytes.
5. The queried/stored IV is 4 bytes, not 8 bytes.
6. The archive contains exactly libdes 3.14, matching the embedded executable
version string.
## Status
The control flow and file-format reconstruction is high confidence. The code
is intended primarily as a faithful readable reconstruction. It has not been
claimed to be byte-for-byte recompilable to the original executables because
that would require the exact original compiler flags, source layout, linker
configuration and original identifiers.
+3
View File
@@ -0,0 +1,3 @@
d118d9b9a618d7e758229642c0585e005b0ab4d458ef369f44d1f4de7012c034 /mnt/data/des.exe
2e54e8820857a1391ac6ce12444f11f75a8a65bfcc58226edd51d6f495c4aa84 /mnt/data/undes.exe
3cd4d36c75916a2c6050b75bd3ad2706e284d3993fbaa68fbde4343a7056f629 /mnt/data/cryptl99.zip
+40
View File
@@ -0,0 +1,40 @@
# CRYPTLIB 0.99 API mapping
The supplied `cryptl99.zip` removes the remaining uncertainty about the
CRYPTLIB calls. The executable's call shapes, local structure offsets and the
source in `crypt.h`/`crypt.c` all agree.
| Operation | CRYPTLIB 0.99 function | des.exe target | undes.exe target |
|---|---|---:|---:|
| Initialise library | `initLibrary()` | `00B3:0738` | `00B7:072A` |
| End library | `endLibrary()` | `00B3:0746` | `00B7:0738` |
| Query algorithm/mode | `queryAlgoModeInformation()` | `00B3:0566` | `00B7:0558` |
| Query context | `queryContextInformation()` | `00B3:06EC` | `00B7:06DE` |
| Initialise context | `initCryptContext()` | `00B3:0756` | `00B7:0748` |
| Destroy context | `destroyCryptContext()` | `00B3:0940` | `00B7:0932` |
| Load key | `loadCryptContext()` | `00B3:09C5` | `00B7:09B7` |
| Retrieve IV | `retrieveIV()` | `00B3:0BA9` | — |
| Load IV | `loadIV()` | — | `00B7:0A90` |
| Encrypt | `encryptBuffer()` | `00B3:0C1E` | — |
| Decrypt | `decryptBuffer()` | — | `00B7:0CEC` |
## Algorithm values
Both mains store the integer value `3` for the algorithm and `3` for the mode.
In the supplied `crypt.h` these are:
```c
CRYPT_ALGO_3DES == 3
CRYPT_MODE_CBC == 3
```
So DES/UNDES V1.1.0 uses **two-key triple DES in CBC mode**.
The `CRYPT_QUERY_INFO` offsets used by the machine code also match the supplied
header in the 16-bit large memory model. The program reads:
- `keySize` = 14 bytes (112 bits)
- `ivSize` = 4 bytes (32 bits)
Those are exactly the recommended values in the CRYPTLIB 0.99 `3DES-CBC`
capability entry.
+205
View File
@@ -0,0 +1,205 @@
/*
* DES V1.1.0 - reconstructed from des.exe
* Original executable: (C) 1998 H.N.M. Dijkema, GPL
*
* IMPORTANT: despite the program name, the executable selects
* CRYPT_ALGO_3DES + CRYPT_MODE_CBC, i.e. two-key triple DES in CBC mode.
*
* This is reconstructed source, not the original source text. Control flow,
* constants, CRYPTLIB calls and file-format behaviour are derived from the
* 16-bit Turbo C executable and verified against CRYPTLIB 0.99 source.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include "crypt.h"
#include "des_common.h"
int main( int argc, char **argv )
{
char *password;
char *inputName;
char *outputName;
FILE *input;
FILE *output;
unsigned char *buffer;
unsigned char *payload;
BYTE key[ CRYPT_MAX_KEYSIZE ];
BYTE iv[ CRYPT_MAX_IVSIZE ];
BYTE passwordBlock[ CRYPT_MAX_KEYSIZE ];
CRYPT_INFO cryptInfo;
CRYPT_QUERY_INFO queryInfo;
CRYPT_ALGO algorithm = CRYPT_ALGO_3DES;
CRYPT_MODE mode = CRYPT_MODE_CBC;
DES_INT32 fileVersion = DES_FILE_VERSION;
int keySize;
int ivSize;
int bytesRead;
int firstTime;
int inputFd;
int i;
if( argc == 2 )
{
if( strcmp( argv[ 1 ], "--copyright" ) == 0 )
{
printf( "%s\n\n", desProgramVersion );
printf( "%s", desCopyrightText );
exit( 0 );
}
if( strcmp( argv[ 1 ], "--version" ) == 0 )
{
printf( "%s\n", desProgramVersion );
exit( 0 );
}
}
if( argc != 4 )
{
fprintf( stderr,
"usage: des <passwd> <file in> <file out>\n"
" des --copyright\n"
" des --version\n"
" '-' for file --> stdin/stdout\n" );
exit( argc == 1 ? 0 : 2 );
}
password = argv[ 1 ];
inputName = argv[ 2 ];
outputName = argv[ 3 ];
if( strcmp( inputName, "-" ) != 0 &&
strcmp( inputName, outputName ) == 0 )
{
fprintf( stderr, "<file in> and <file out> cannot be the same\n" );
exit( 1 );
}
input = ( strcmp( inputName, "-" ) == 0 ) ?
stdin : fopen( inputName, "rb" );
output = ( strcmp( outputName, "-" ) == 0 ) ?
stdout : fopen( outputName, "wb" );
checkOpen( input, inputName );
checkOpen( output, outputName );
/* The executable writes exactly four bytes here. */
fwrite( &fileVersion, 4, 1, output );
algorithm = CRYPT_ALGO_3DES;
mode = CRYPT_MODE_CBC;
buffer = (unsigned char *) malloc( DES_BUFFER_SIZE );
if( buffer == NULL )
{
fprintf( stderr, "Cannot allocate buffer\n" );
exit( 1 );
}
payload = buffer + DES_PREFIX_SIZE;
initLibrary();
queryAlgoModeInformation( algorithm, mode, &queryInfo );
keySize = queryInfo.keySize; /* 14 bytes for 3DES-CBC in 0.99 */
ivSize = queryInfo.ivSize; /* 4 bytes for 3DES-CBC in 0.99 */
i = 0;
while( i < keySize && password[ i ] != '\0' )
{
key[ i ] = (BYTE) password[ i ];
i++;
}
while( i < keySize )
key[ i++ ] = 0;
initCryptContext( &cryptInfo, algorithm, mode );
loadCryptContext( &cryptInfo, key, keySize );
firstTime = TRUE;
inputFd = fileno( input );
bytesRead = read( inputFd, payload, DES_PAYLOAD_SIZE );
checkRead( bytesRead );
while( bytesRead != 0 )
{
DES_INT32 marker;
if( bytesRead == DES_PAYLOAD_SIZE )
{
marker = negativeMarker( payload );
if( marker == 0 )
marker = (DES_INT32) -1;
memcpy( buffer, &marker, 4 );
marker = negativeMarker( payload + 4 );
memcpy( buffer + 4, &marker, 4 );
}
else
{
marker = (DES_INT32) bytesRead;
memcpy( buffer, &marker, 4 );
marker = negativeMarker( payload );
memcpy( buffer + 4, &marker, 4 );
}
/* The executable always encrypts the complete 16 KiB buffer. */
encryptBuffer( &cryptInfo, buffer, DES_BUFFER_SIZE );
if( firstTime )
{
/*
* CRYPTLIB generates the IV on the first encryptBuffer() call.
* Therefore it can only be retrieved after that call.
*/
queryContextInformation( &cryptInfo, &queryInfo );
ivSize = queryInfo.ivSize;
retrieveIV( &cryptInfo, iv );
fwrite( iv, ivSize, 1, output );
checkWrite( output );
fflush( output );
/*
* Only keySize bytes are assigned. The remaining bytes of this
* 256-byte stack buffer are intentionally left as they were in the
* original executable; UNDES compares only the first keySize bytes.
*/
for( i = 0; i < keySize; i++ )
passwordBlock[ i ] = key[ i ];
encryptBuffer( &cryptInfo, passwordBlock, CRYPT_MAX_KEYSIZE );
fwrite( passwordBlock, CRYPT_MAX_KEYSIZE, 1, output );
checkWrite( output );
fflush( output );
firstTime = FALSE;
}
fwrite( buffer, DES_BUFFER_SIZE, 1, output );
checkWrite( output );
fflush( output );
bytesRead = read( inputFd, payload, DES_PAYLOAD_SIZE );
checkRead( bytesRead );
}
/* Courtesy close call used by CRYPTLIB block-cipher examples. */
encryptBuffer( &cryptInfo, buffer, 0 );
destroyCryptContext( &cryptInfo );
endLibrary();
free( buffer );
if( input != stdin )
fclose( input );
if( output != stdout )
fclose( output );
return( 0 );
}
+122
View File
@@ -0,0 +1,122 @@
/*
* Common support reconstructed from DES/UNDES V1.1.0 executables.
* Original program copyright: (C) 1998 H.N.M. Dijkema, GPL.
*
* This is reconstructed source, not the original source text. The helper
* behaviour and strings below are derived directly from des.exe/undes.exe.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "des_common.h"
DES_INT32 desKnownVersions[] = {
DES_FILE_VERSION,
(DES_INT32) -1
};
const char *desProgramVersion =
"DES/UNDES V1.1.0, (C) 1998 H.N.M. Dijkema (GPL)";
const char *desCopyrightText =
" Copyright (C) 1998 H.N.M. Dijkema\n"
"\n"
" This product includes software developed by Eric Young (eay@mincom.oz.au)\n"
"\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
" (at your option) any later version.\n"
"\n"
" This program is distributed in the hope that it will be useful,\n"
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
"\n"
" You can contact the author by electronic mail, hnmdijkema@freemail.nl\n"
"\n"
"\n"
"Acknowledgements\n"
"----------------\n"
"The author of CRYPTLIB, Peter Putmann of University of Auckland\n"
"cryptl99.zip Free encryption library for DOS/UNIX/Windows\n"
"\n"
"The DES and 3DES encryption code was contributed by Eric Young\n"
"<eay@psych.psy.uq.oz.au> and is part of his libdes package.\n"
"The primary ftp site for the full libdes is\n"
" ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz.\n"
"\n";
void checkRead( int result )
{
if( result == -1 )
{
fprintf( stderr, "\nFATAL : error reading input stream\n" );
perror( "MESSAGE " );
exit( 3 );
}
}
void checkWrite( FILE *stream )
{
if( ferror( stream ) )
{
fprintf( stderr, "\nFATAL : error writing output stream\n" );
perror( "MESSAGE " );
exit( 3 );
}
}
void checkOpen( FILE *stream, const char *name )
{
if( stream == NULL )
{
fprintf( stderr, "\nFATAL : Cannot open '%s'\n", name );
perror( "MESSAGE " );
exit( 3 );
}
}
void checkVersion( DES_INT32 version )
{
int i = 0;
while( desKnownVersions[ i ] != version &&
desKnownVersions[ i ] != (DES_INT32) -1 )
i++;
if( desKnownVersions[ i ] == (DES_INT32) -1 )
{
fprintf( stderr,
"I don't know the version of this file, can't decrypt this\n" );
exit( 1 );
}
}
/*
* The compiler output proves that the marker is formed from a signed 16-bit
* word: abs(word), followed by negation and sign-extension to 32 bits.
*/
DES_INT32 negativeMarker( const unsigned char *p )
{
DES_INT16 value;
DES_UINT16 magnitude;
DES_UINT16 negated;
memcpy( &value, p, sizeof( value ) );
/* Emulate 16-bit Turbo C arithmetic exactly, including -32768. */
if( value < 0 )
magnitude = (DES_UINT16) ( -(DES_INT32) value );
else
magnitude = (DES_UINT16) value;
negated = (DES_UINT16) ( 0U - magnitude );
memcpy( &value, &negated, sizeof( value ) );
return( (DES_INT32) value );
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef DES_COMMON_H
#define DES_COMMON_H
#include <stdio.h>
#include "crypt.h"
/*
* Types which have the same width as Turbo C 2.x int/long when this source
* is inspected or built on a modern compiler.
*/
#ifdef __TURBOC__
typedef int DES_INT16;
typedef unsigned int DES_UINT16;
typedef long DES_INT32;
#else
#include <stdint.h>
typedef int16_t DES_INT16;
typedef uint16_t DES_UINT16;
typedef int32_t DES_INT32;
#endif
#define DES_BUFFER_SIZE 0x4000
#define DES_PREFIX_SIZE 8
#define DES_PAYLOAD_SIZE ( DES_BUFFER_SIZE - DES_PREFIX_SIZE )
#define DES_FILE_VERSION ((DES_INT32) 0x2775L)
extern DES_INT32 desKnownVersions[];
extern const char *desProgramVersion;
extern const char *desCopyrightText;
void checkRead( int result );
void checkWrite( FILE *stream );
void checkOpen( FILE *stream, const char *name );
void checkVersion( DES_INT32 version );
DES_INT32 negativeMarker( const unsigned char *p );
#endif
View File
+162
View File
@@ -0,0 +1,162 @@
# Reconstruction notes — DES/UNDES V1.1.0
## Confidence
The main program logic is now reconstructed with high confidence. The supplied
`cryptl99.zip` is especially useful because it contains the exact CRYPTLIB 0.99
API and libdes 3.14 source that was linked into the executables.
This is **not** the original source text. Original variable names, comments,
whitespace and file decomposition were not retained in the executable. Names
such as `firstTime`, `passwordBlock`, `negativeMarker`, and the split into
`des_common.c`/`.h` are descriptive reconstruction choices.
## Compiler and memory model
Both programs are 16-bit MS-DOS MZ executables and contain the runtime string:
`Turbo-C - Copyright (c) 1988 Borland Intl.`
The generated code uses far data pointers extensively, and `malloc()` returns a
segment:offset pointer. That is consistent with a Turbo C large-memory-model
build.
## Exact crypto dependency
The executables contain:
`libdes v 3.14 - eay`
The supplied CRYPTLIB archive contains the same `libdes/version.h` string, plus
`crypt.h`, `crypt.c`, `lib_3des.c` and the relevant libdes sources. This is the
actual dependency family used by the executables rather than merely a later
compatible library.
## Important correction: it is 3DES
The machine code assigns value 3 to both the algorithm and mode variables.
According to the supplied `crypt.h`:
- `CRYPT_ALGO_3DES` = 3
- `CRYPT_MODE_CBC` = 3
Therefore the encryption is **two-key 3DES-CBC**, despite the executable being
called `des.exe`.
`crypt.c` defines the recommended 3DES-CBC parameters as:
- key size: 112 bits = 14 bytes
- IV size: 32 bits = 4 bytes
- DES block size: 64 bits = 8 bytes
The main routine obtains both sizes through `queryAlgoModeInformation()`.
## Password handling
The command-line password is copied directly into a 14-byte key buffer and is
zero-padded if shorter. Characters after byte 14 do not influence encryption.
There is no password hash or KDF in the DES/UNDES layer.
CRYPTLIB's `des3InitKey()` then constructs the two DES key schedules from that
user-key buffer. `des_check_key` in the bundled libdes defaults to zero, so
parity/weak-key checking is not enabled by default.
## File layout
For a non-empty encrypted input the file is:
```text
Offset Size Meaning
0 4 file version: 0x00002775
4 4 CRYPTLIB-recommended CBC IV
8 256 encrypted password-check block
264 16384 encrypted data block 1
16648 16384 encrypted data block 2
... ...
```
For an empty input, `des.exe` writes only the four-byte version. Because no
`encryptBuffer()` call with data occurs, no IV or password-check block is
written.
## Data-block layout before encryption
Each 16384-byte encrypted data block consists of:
```text
0..3 signed 32-bit length marker
4..7 signed 32-bit secondary marker
8..16383 at most 16376 bytes input data
```
For a partial final block, the first field is the positive plaintext byte count.
For a full block it is a negative value; `undes.exe` interprets any negative
value as exactly 16376 plaintext bytes.
The full-block negative value is formed from the absolute value of the first
signed 16-bit word of the plaintext and then negated. If that produces zero,
`-1` is stored instead. The second field is also a negative marker derived from
a signed 16-bit plaintext word. `undes.exe` does not use this second field.
The exact purpose of the secondary marker cannot be established from the
executables alone; its computation is established, its design intent is not.
## CBC ordering on the first block
An unusual but confirmed detail is the first-block ordering.
`des.exe` performs the cryptographic operations in this order:
1. encrypt first 16 KiB data block
2. retrieve the now-generated IV
3. encrypt the 256-byte password-check block
but writes:
1. IV
2. encrypted password-check block
3. encrypted first data block
`undes.exe` reads the stored password block and first data block, then decrypts
in cryptographic order:
1. decrypt first data block
2. decrypt password-check block
This preserves the CBC state exactly. The apparent storage/processing order
mismatch is therefore intentional in the program logic, not a decompiler error.
## Password-check block
Before encryption, the first 14 bytes of the 256-byte password-check block are
the derived 14-byte key. The executable does not initialise the remaining 242
bytes before encrypting the block. During decryption only the first 14 bytes
are compared.
## Uninitialised bytes in the final data block
`des.exe` always encrypts the complete 16384-byte buffer. If the final input
chunk is shorter than 16376 bytes, the unused tail is not explicitly cleared
first. This is also visible in the machine code. UNDES writes only the number
of plaintext bytes stored in the first 32-bit field.
## Error handling and robustness
Read errors are detected only when `read()` returns `-1`; short reads are not
rejected. `undes.exe` does not authenticate ciphertext and does not validate a
positive decrypted length against 16376 before passing it to `fwrite()`. These
are normal limitations for small DOS-era utility code, but they matter if old
encrypted files are corrupted or attacker-controlled.
## Remaining uncertainty
The following cannot be recovered exactly without original source/debug
symbols:
- original variable/function names for the DES/UNDES-specific code;
- original comments and formatting;
- exact source-file decomposition;
- the design rationale for the secondary 32-bit marker;
- the symbolic name/formula originally used for file version `0x2775`.
The actual program behaviour no longer depends on guessed CRYPTLIB API names.
BIN
View File
Binary file not shown.
+120
View File
@@ -0,0 +1,120 @@
#****************************************************************************
#* *
#* Makefile for the encryption library *
#* *
#****************************************************************************
CC = dcc -v -c
PROJ = crypt
LIBNAME = $(PROJ).lib
# Where object files go (/tmp is a good place)
OUTPATH = DObjs/
# Extension for object files
OBJ = .o
# Linker (just use the C compiler)
LD = dcc -v
# Echo to screen command
ECHO = echo
# The make command
MAKE = dmake
# The object files which make up the library
OBJS = $(OUTPATH)crypt$(OBJ) $(OUTPATH)lib_3des$(OBJ) $(OUTPATH)lib_des$(OBJ) $(OUTPATH)lib_idea$(OBJ) $(OUTPATH)lib_mdc$(OBJ) $(OUTPATH)lib_null$(OBJ) $(OUTPATH)lib_rc4$(OBJ) $(OUTPATH)idea$(OBJ) $(OUTPATH)3ecb_enc$(OBJ) $(OUTPATH)ecb_enc$(OBJ) $(OUTPATH)pcbc_enc$(OBJ) $(OUTPATH)set_key$(OBJ) $(OUTPATH)rc4$(OBJ) $(OUTPATH)shs$(OBJ)
#****************************************************************************
#* *
#* If no args are given, print a usage message and exit *
#* *
#****************************************************************************
default: $(LIBNAME)
love:
@$(ECHO) "Nicht wahr?"
@$(ECHO)
#****************************************************************************
#* *
#* Rules to build the encryption library *
#* *
#****************************************************************************
# Main directory
$(OUTPATH)crypt$(OBJ): crypt.h crypt.c
$(CC) -o %(left) crypt.c
$(OUTPATH)lib_3des$(OBJ): crypt.h libdes/des.h lib_3des.c
$(CC) -o %(left) lib_3des.c
$(OUTPATH)lib_des$(OBJ): crypt.h testdes.h libdes/des.h lib_des.c
$(CC) -o %(left) lib_des.c
$(OUTPATH)lib_idea$(OBJ): crypt.h idea/idea.h testidea.h lib_idea.c
$(CC) -o %(left) lib_idea.c
$(OUTPATH)lib_mdc$(OBJ): crypt.h mdc/shs.h lib_mdc.c
$(CC) -o %(left) lib_mdc.c
$(OUTPATH)lib_null$(OBJ): crypt.h lib_null.c
$(CC) -o %(left) lib_null.c
$(OUTPATH)lib_rc4$(OBJ): crypt.h testrc4.h rc4/rc4.h lib_rc4.c
$(CC) -o %(left) lib_rc4.c
$(OUTPATH)test$(OBJ): crypt.h test.c
$(CC) -o %(left) test.c
# idea subdirectory
$(OUTPATH)idea$(OBJ): idea/idea.h idea/idea.c
$(CC) -o %(left) idea/idea.c
# libdes subdirectory
$(OUTPATH)3ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/3ecb_enc.c
$(CC) -o %(left) libdes/3ecb_enc.c
$(OUTPATH)ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/spr.h libdes/version.h libdes/ecb_enc.c
$(CC) -o %(left) libdes/ecb_enc.c
$(OUTPATH)pcbc_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/pcbc_enc.c
$(CC) -o %(left) libdes/pcbc_enc.c
$(OUTPATH)set_key$(OBJ): libdes/des.h libdes/des_locl.h libdes/podd.h libdes/sk.h libdes/set_key.c
$(CC) -o %(left) libdes/set_key.c
# rc4 subdirectory
$(OUTPATH)rc4$(OBJ): rc4/rc4.h rc4/rc4.c
$(CC) -o %(left) rc4/rc4.c
# mdc subdirectory
$(OUTPATH)shs$(OBJ): mdc/shs.h mdc/shs.c
$(CC) -o %(left) mdc/shs.c
# Create the library. The test program is also listed as a dependancy
# since we need to use OS-specific compiler options for it which a
# simple 'make test' won't give us (yuck).
$(LIBNAME): $(OBJS) $(OUTPATH)test$(OBJ)
join as $(LIBNAME) $(OBJS)
# Link everything into a test program
test: $(LIBNAME) $(OUTPATH)test$(OBJ)
$(LD) -o testcrypt $(OUTPATH)test$(OBJ) -l$(PROJ)
#****************************************************************************
#* *
#* Cleanup after make has finished *
#* *
#****************************************************************************
clean:
delete force #?.o testcrypt $(LIBNAME)
+35
View File
@@ -0,0 +1,35 @@
Ansi
Batch
Debug=Line
Error=All
ErrorRexx
Ignore=178
Ignore=306
IncludeDir=A31:
LinkOpts=NoAlvs
MemSize=Huge
MultiCharacterConstants
NoIcons
NoMultipleIncludes
NoStackCheck
OnError=Continue
NoOptimize
OptimizerComplexity=10
OptimizerDepth=10
OptimizerInlineLocal
OptimizerRecurDepth=10
NoOptimizerScheduler
OptimizerTime
Parameters=Registers
SmallCode
SmallData
Startup=cres
Strict
StringMerge
Verbose
Define=_STRICT_ANSI
Define=__ANSI__
Define=USE_BUILTIN_MATH
Define=AMIGA
Define=STDC_HEADERS
Define=KULTUR
+115
View File
@@ -0,0 +1,115 @@
#****************************************************************************
#* *
#* Makefile for the encryption library *
#* *
#****************************************************************************
CC = sc
PROJ = crypt
LIBNAME = $(PROJ).lib
OUTPATH = SObjs/ # Where object files go (/tmp is a good place)
OBJ = .o # Extension for object files
LD = $(CC) link # Linker (just use the C compiler)
ECHO = echo # Echo to screen command
MAKE = smake # The make command
# The object files which make up the library
OBJS = $(OUTPATH)crypt$(OBJ) $(OUTPATH)lib_3des$(OBJ) $(OUTPATH)lib_des$(OBJ) $(OUTPATH)lib_idea$(OBJ) $(OUTPATH)lib_mdc$(OBJ) $(OUTPATH)lib_null$(OBJ) $(OUTPATH)lib_rc4$(OBJ) $(OUTPATH)idea$(OBJ) $(OUTPATH)3ecb_enc$(OBJ) $(OUTPATH)ecb_enc$(OBJ) $(OUTPATH)pcbc_enc$(OBJ) $(OUTPATH)set_key$(OBJ) $(OUTPATH)rc4$(OBJ) $(OUTPATH)shs$(OBJ)
#****************************************************************************
#* *
#* If no args are given, print a usage message and exit *
#* *
#****************************************************************************
default: $(LIBNAME)
love:
@$(ECHO) "Nicht wahr?"
@$(ECHO)
#****************************************************************************
#* *
#* Rules to build the encryption library *
#* *
#****************************************************************************
# Main directory
$(OUTPATH)crypt$(OBJ): crypt.h crypt.c
$(CC) objname $@ crypt.c
$(OUTPATH)lib_3des$(OBJ): crypt.h libdes/des.h lib_3des.c
$(CC) objname $@ lib_3des.c
$(OUTPATH)lib_des$(OBJ): crypt.h testdes.h libdes/des.h lib_des.c
$(CC) objname $@ lib_des.c
$(OUTPATH)lib_idea$(OBJ): crypt.h idea/idea.h testidea.h lib_idea.c
$(CC) objname $@ lib_idea.c
$(OUTPATH)lib_mdc$(OBJ): crypt.h mdc/shs.h lib_mdc.c
$(CC) objname $@ lib_mdc.c
$(OUTPATH)lib_null$(OBJ): crypt.h lib_null.c
$(CC) objname $@ lib_null.c
$(OUTPATH)lib_rc4$(OBJ): crypt.h testrc4.h rc4/rc4.h lib_rc4.c
$(CC) objname $@ lib_rc4.c
$(OUTPATH)test$(OBJ): crypt.h test.c
$(CC) objname $@ test.c
# idea subdirectory
$(OUTPATH)idea$(OBJ): idea/idea.h idea/idea.c
$(CC) objname $@ idea/idea.c
# libdes subdirectory
$(OUTPATH)3ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/3ecb_enc.c
$(CC) objname $@ libdes/3ecb_enc.c
$(OUTPATH)ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/spr.h libdes/version.h libdes/ecb_enc.c
$(CC) objname $@ libdes/ecb_enc.c
$(OUTPATH)pcbc_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/pcbc_enc.c
$(CC) objname $@ libdes/pcbc_enc.c
$(OUTPATH)set_key$(OBJ): libdes/des.h libdes/des_locl.h libdes/podd.h libdes/sk.h libdes/set_key.c
$(CC) objname $@ libdes/set_key.c
# rc4 subdirectory
$(OUTPATH)rc4$(OBJ): rc4/rc4.h rc4/rc4.c
$(CC) objname $@ rc4/rc4.c
# mdc subdirectory
$(OUTPATH)shs$(OBJ): mdc/shs.h mdc/shs.c
$(CC) objname $@ mdc/shs.c
# Create the library. The test program is also listed as a dependancy
# since we need to use OS-specific compiler options for it which a
# simple 'make test' won't give us (yuck).
$(LIBNAME): $(OBJS) $(OUTPATH)test$(OBJ)
oml -n -b $(LIBNAME) r $(OBJS)
# Link everything into a test program
test: $(LIBNAME) $(OUTPATH)test$(OBJ)
@$(LD) pname testcrypt $(OUTPATH)test$(OBJ) lib $(LIBNAME)
#****************************************************************************
#* *
#* Cleanup after make has finished *
#* *
#****************************************************************************
clean:
delete force \#?.o testcrypt $(LIBNAME)
+215
View File
@@ -0,0 +1,215 @@
' A warning to parents that this programming language is unsuited for small
' children
Option Explicit
'****************************************************************************
'* *
'* Encryption Algorithm Types/Modes *
'* *
'****************************************************************************
' The encryption algorithms we can use
Global Const CRYPT_ALGO_NONE = 0 ' No encryption
Global Const CRYPT_ALGO_MDCSHS = 1 ' MDC/SHS
Global Const CRYPT_ALGO_DES = 2 ' DES
Global Const CRYPT_ALGO_3DES = 3 ' Two-key triple DES
Global Const CRYPT_ALGO_IDEA = 4 ' IDEA
Global Const CRYPT_ALGO_RC4 = 5 ' RC4
Global Const CRYPT_ALGO_SAFER = 6 ' SAFER and SAFER-SK
Global Const CRYPT_ALGO_LAST = 7 ' Last possible crypt algo value
' The encryption modes we can use
Global Const CRYPT_MODE_NONE = 0 ' No encryption
Global Const CRYPT_MODE_STREAM = 1 ' Stream cipher
Global Const CRYPT_MODE_ECB = 2 ' ECB
Global Const CRYPT_MODE_CBC = 3 ' CBC
Global Const CRYPT_MODE_CFB = 4 ' CFB
Global Const CRYPT_MODE_OFB = 5 ' OFB
Global Const CRYPT_MODE_PCBC = 6 ' PCBC
Global Const CRYPT_MODE_LAST = 6 ' Last possible crypt algo value
'****************************************************************************
'* *
'* Library-Wide Constants and Definitions *
'* *
'****************************************************************************
' The maximum user key size - 2048 bits
Global Const CRYPT_MAX_KEYSIZE = 256
' The maximum IV size - 256 bits
Global Const CRYPT_MAX_IVSIZE = 64
' The maximum speed ratio for an encryption algorithm
Global Const CRYPT_MAX_SPEED = 1000
'****************************************************************************
'* *
'* Data Structures *
'* *
'****************************************************************************
' An encryption context. Note the order of the BYTE[] fields in this
' structure, which ensures they're aligned to the machine word size
Type CRYPT_INFO
' Basic information on the encryption we're using (a pointer to an
' internal data structure)
capabilityInfo As Long ' The encryption capability data
' User keying information. The user key is the key as entered by the
' user, the transformed user key is (for those algoriths which do this)
' the user key transformed by whatever key preprocessing method is used,
' stored in canonical form. The IV is the initial IV stored in canonical
' form
userKey As String * MAX_KEYSIZE ' User encryption key
transUserKey As String * MAX_KEYSIZE ' Transformed user key
iv As String * MAX_IVSIZE ' Initial IV
userKeyLength As Integer ' User encryption key length in bytes
ivLength As Integer ' IV length in bytes
keySet As Integer ' Whether the key is set up
ivSet As Integer ' Whether the IV is set up
' Keying information. The key is the raw encryption key stored in
' whatever form is required by the algorithm. This may be simply an
' endianness-adjusted form of the transformed key (in the case of
' algorithms like MDC/SHS) or a processed form of the user key (in the
' case of algorithms like DES or IDEA). The IV is the current working
' IV stored in an endianness-adjusted form. The ivCount is the number
' of bytes of IV in use, and may be used for various chaining modes.
' These fields may be unused if the algorithm is implemented in hardware
key As Long ' Pointer to internal working key
currentIV As String * MAX_IVSIZE ' Internal working IV
keyLength As Integer ' Internal key length in bytes
ivCount As Integer ' Internal IV count for chaining modes
' Private data needed by the algorithm
privateData As Long ' For private use
End Type
' Extra algorithm-specific information stored within a crypt context
Type CRYPT_INFO_MDCSHS
keySetupIterations As Integer ' No.iterations for user key setup
End Type
Type CRYPT_INFO_SAFER
rounds As Integer ' Number of encryption rounds
currentRounds As Integer ' Internal number of rounds for this key
useSaferSK As Integer ' Whether to use strengthened-key version
End Type
' Results returned from the encryption capability query
Type CRYPT_QUERY_INFO
' The algorithm, encryption mode, and algorithm name. Note that the
' algorithm name is a pointer to a C string, which current versions of
' Visual Basic can't handle when they're inside a structure. To use it,
' you need to extract it into a String in the VB program
cryptAlgo As Integer ' The encryption algorithm
cryptMode As Integer ' The encryption mode
algoName As Long ' The algorithm name
' The algorithm parameters
blockSize As Integer ' The basic block size of the algorithm
minKeySize As Integer ' Minimum key size in bytes
keySize As Integer ' Recommended key size in bytes
maxKeySize As Integer ' Maximum key size in bytes
minIVsize As Integer ' Minimum IV size in bytes
ivSize As Integer ' Recommended IV size in bytes
maxIVsize As Integer ' Maximum IV size in bytes
' Various algorithm characteristics
speed As Integer ' Speed relative to block copy
End Type
'****************************************************************************
'* *
'* Status Codes *
'* *
'****************************************************************************
' No error in function call
Global Const CRYPT_OK = 0 ' No error
' Generic internal error
Global Const CRYPT_ERROR = -1 ' Nonspecific error
' Failed self-test in encryption code
Global Const CRYPT_SELFTEST = -2 ' Failed self-test
' Error in parameters passed to function
Global Const CRYPT_BADPARM = -3 ' Generic bad argument to function
Global Const CRYPT_BADPARM1 = -4 ' Bad argument, parameter 1
Global Const CRYPT_BADPARM2 = -5 ' Bad argument, parameter 2
Global Const CRYPT_BADPARM3 = -6 ' Bad argument, parameter 3
Global Const CRYPT_BADPARM4 = -7 ' Bad argument, parameter 4
Global Const CRYPT_BADPARM5 = -8 ' Bad argument, parameter 5
Global Const CRYPT_BADPARM6 = -9 ' Bad argument, parameter 6
Global Const CRYPT_BADPARM7 = -10 ' Bad argument, parameter 7
Global Const CRYPT_BADPARM8 = -11 ' Bad argument, parameter 8
Global Const CRYPT_BADPARM9 = -12 ' Bad argument, parameter 9
Global Const CRYPT_BADPARM10 = -13 ' Bad argument, parameter 10
Global Const CRYPT_BADPARM11 = -14 ' Bad argument, parameter 11
Global Const CRYPT_BADPARM12 = -15 ' Bad argument, parameter 12
Global Const CRYPT_BADPARM13 = -16 ' Bad argument, parameter 13
Global Const CRYPT_BADPARM14 = -17 ' Bad argument, parameter 14
Global Const CRYPT_BADPARM15 = -18 ' Bad argument, parameter 15
' Errors due to insufficient resources
Global Const CRYPT_NOMEM = -19 ' Out of memory
Global Const CRYPT_NOTINITED = -20 ' Data has not been initialised
Global Const CRYPT_INITED = -21 ' Data has already been initialised
Global Const CRYPT_NOALGO = -22 ' Algorithm unavailable
Global Const CRYPT_NOMODE = -23 ' Encryption mode unavailable
Global Const CRYPT_NOKEY = -24 ' Key not initialised
Global Const CRYPT_NOIV = -25 ' IV not initialised
'****************************************************************************
'* *
'* Public Functions *
'* *
'****************************************************************************
' Initialise and shut down the encryption library
Declare Function initLibrary Lib "Crypt.Dll" () As Integer
Declare Function endLibrary Lib "Crypt.Dll" () As Integer
' Query the capabilities of the encryption library
Declare Function queryModeAvailability Lib "Crypt.Dll" (ByVal cryptAlgo As Integer, ByVal cryptMode As Integer) As Integer
Declare Function queryAlgoAvailability Lib "Crypt.Dll" (ByVal cryptAlgo As Integer) As Integer
Declare Function queryAlgoModeInformation Lib "Crypt.Dll" (ByVal cryptAlgo As Integer, ByVal cryptMode As Integer, cryptQueryInfo As CRYPT_QUERY_INFO) As Integer
Declare Function queryContextInformation Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, cryptQueryInfo As CRYPT_QUERY_INFO) As Integer
' Initialise and destroy an encryption context
Declare Function initCryptContext Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal cryptAlgo As Integer, ByVal cryptMode As Integer) As Integer
Declare Function initCryptContextEx Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal cryptAlgo As Integer, ByVal cryptMode As Integer, cryptInfoEx As Any) As Integer
Declare Function destroyCryptContext Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO) As Integer
' Load a user key into a crypt context
Declare Function loadCryptContext Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal key As String, ByVal keyLength As Integer) As Integer
' Load/retreive an IV into/from a crypt context
Declare Function loadIV Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal iv As String, ByVal length As Integer) As Integer
Declare Function retrieveIV Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal iv As String) As Integer
' Encrypt/decrypt a block of memory
Declare Function encryptBuffer Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal buffer As String, ByVal length As Integer) As Integer
Declare Function decryptBuffer Lib "Crypt.Dll" (cryptInfo As CRYPT_INFO, ByVal buffer As String, ByVal length As Integer) As Integer
+1049
View File
File diff suppressed because it is too large Load Diff
+421
View File
@@ -0,0 +1,421 @@
#ifndef _CRYPT_DEFINED
#define _CRYPT_DEFINED
/* Fixup for Windoze support. We need to include windows.h for various types
and prototypes needed for DLL's, and then fix up a type clash with a
Windows predefined type - for some bizarre reason BYTE and WORD are
unsigned, but LONG is signed */
#if defined( __WINDOWS__ )
#include <windows.h>
#undef LONG
#endif /* __WINDOWS__ */
/* Some encryption algorithms which rely on longints having 32 bits won't
work on 64- or 128-bit machines due to problems with sign extension and
whatnot. The following define can be used to enable special handling for
processors with a > 32 bit word size */
#include <limits.h>
#if LONG_MAX > 0xFFFFFFFFUL
#define _BIG_WORDS
#endif /* LONG > 32 bits */
/* Some useful types. We have to jump through all sorts of hoops for Windoze,
not helped by the fact that the method of detecting Windoze at compile
time changes with different versions of Visual C */
#if defined(_MSC_VER)
typedef int BOOLEAN;
#elif !( defined( WIN32 ) || defined( _WIN32 ) )
typedef int BOOLEAN;
#endif /* !( WIN32 || _WIN32 ) */
typedef unsigned char BYTE;
#ifndef __WINDOWS__
typedef unsigned short WORD;
#endif /* __WINDOWS__ */
#if defined( __WINDOWS__ ) && ( defined( WIN32 ) || defined( _WIN32 ) )
#pragma warning( disable : 4142 )
typedef unsigned long LONG;
#pragma warning( default : 4142 )
#ifdef _WIN32
/* Visual C 2.1 doesn't seem to like LONG being typedef'd to unsigned
no matter what you do, so we rely on the preprocessor to get rid of
the problem. Visual C 2.1 defined _WIN32 whereas 2.0 defined WIN32,
so we can use this to tell the two apart */
#define LONG unsigned long
#endif /* _WIN32 */
#else
typedef unsigned long LONG;
#endif /* __WINDOWS__ && ( WIN32 || _WIN32 ) */
/* Boolean consants */
#ifndef TRUE
#define FALSE 0
#define TRUE !FALSE
#endif /* TRUE */
/* Machine-dependant types to allow use in special library types such as
DLL's */
#if defined( __WINDOWS__ ) && !( defined( WIN32 ) || defined( _WIN32 ) )
#define CPTR FAR * /* DLL pointer */
#define CRET int FAR PASCAL _export /* DLL return value */
#else
#define CPTR * /* General pointer */
#define CRET int /* General return value */
#endif /* __WINDOWS__ && !( WIN32 || _WIN32 ) */
/* Determine the processor endianness. Thanks to Shawn Clifford
<sysop@robot.nuceng.ufl.edu> for this trick.
NB: A number of compilers aren't tough enough for this test */
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#if defined(_MSC_VER)
/*
* All architectures currently supported by MSVC/Windows
* use little-endian byte ordering.
*/
#if defined(_M_IX86) || \
defined(_M_X64) || \
defined(_M_AMD64) || \
defined(_M_ARM) || \
defined(_M_ARM64) || \
defined(_M_ARM64EC)
#define LITTLE_ENDIAN
#else
#error Cannot determine processor endianness for MSVC
#endif
#elif defined(AMIGA)
#define BIG_ENDIAN
#elif defined(__GNUC__)
#ifdef BYTES_BIG_ENDIAN
#define BIG_ENDIAN
#else
#define LITTLE_ENDIAN
#endif
#else
#error Cannot determine processor endianness - edit crypt.h and recompile
#endif
#endif
/****************************************************************************
* *
* Encryption Algorithm Types/Modes *
* *
****************************************************************************/
/* The encryption algorithms we can use */
typedef enum {
CRYPT_ALGO_NONE, /* No encryption */
CRYPT_ALGO_MDCSHS, /* MDC/SHS */
CRYPT_ALGO_DES, /* DES */
CRYPT_ALGO_3DES, /* Two-key triple DES */
CRYPT_ALGO_IDEA, /* IDEA */
CRYPT_ALGO_RC4, /* RC4 */
CRYPT_ALGO_SAFER, /* SAFER */
CRYPT_ALGO_LAST /* Last possible crypt algo value */
} CRYPT_ALGO;
/* The encryption modes we can use */
typedef enum {
/* No encryption */
CRYPT_MODE_NONE, /* No encryption */
/* Stream cipher modes */
CRYPT_MODE_STREAM, /* Stream cipher */
/* Block cipher modes */
CRYPT_MODE_ECB, /* ECB */
CRYPT_MODE_CBC, /* CBC */
CRYPT_MODE_CFB, /* CFB */
CRYPT_MODE_OFB, /* OFB */
CRYPT_MODE_PCBC, /* PCBC */
CRYPT_MODE_LAST /* Last possible crypt algo value */
} CRYPT_MODE;
/****************************************************************************
* *
* Library-Wide Constants and Definitions *
* *
****************************************************************************/
/* The maximum user key size - 2048 bits */
#define CRYPT_MAX_KEYSIZE 256
/* The maximum IV size - 256 bits */
#define CRYPT_MAX_IVSIZE 64
/* The maximum speed ratio for an encryption algorithm */
#define CRYPT_MAX_SPEED 1000
/* A magic value indicating that the default setting for this parameter
should be used */
#define CRYPT_USE_DEFAULT -1
/* Macros to convert to and from the bit counts used for some encryption
parameters */
#define bitsToBytes(bits) ( ( bits ) >> 3 )
#define bytesToBits(bytes) ( ( bytes ) << 3 )
/****************************************************************************
* *
* Data Structures *
* *
****************************************************************************/
/* The structure used to store internal information about the crypto library
capabilities. This information is used internally by the library and is
not available to users */
struct CI; /* Forward declaration for nested struct */
typedef struct CA {
/* Basic identification information for the algorithm */
CRYPT_ALGO cryptAlgo; /* The encryption algorithm */
CRYPT_MODE cryptMode; /* The encryption mode */
int blockSize; /* The basic block size of the algorithm */
char *name; /* Algorithm name */
int speed; /* Speed relative to block copy */
/* Keying information */
int minKeySize; /* Minimum key size in bytes */
int keySize; /* Recommended key size in bytes */
int maxKeySize; /* Maximum key size in bytes */
/* IV information */
int minIVsize; /* Minimum IV size in bytes */
int ivSize; /* Recommended IV size in bytes */
int maxIVsize; /* Maximum IV size in bytes */
/* The functions for implementing the algorithm */
int ( *selfTestFunction )( void );
int ( *initFunction )( struct CI CPTR cryptInfo );
int ( *initExFunction )( struct CI CPTR cryptInfo, void CPTR cryptInfoEx );
int ( *endFunction )( struct CI CPTR cryptInfo );
int ( *initKeyFunction )( struct CI CPTR cryptInfo );
int ( *initIVFunction )( struct CI CPTR cryptInfo );
int ( *encryptFunction )( struct CI CPTR cryptInfo, void CPTR buffer, int length );
int ( *decryptFunction )( struct CI CPTR cryptInfo, void CPTR buffer, int length );
/* The results of the self-test for this algorithm */
int selfTestStatus;
/* The next record in the list */
struct CA *next; /* Pointer to the next record */
} CAPABILITY_INFO;
/* An encryption context. Note the order of the BYTE[] fields in this
structure, which ensures they're aligned to the machine word size */
typedef struct CI {
/* Basic information on the encryption we're using */
CAPABILITY_INFO *capabilityInfo;/* The encryption capability data */
/* User keying information. The user key is the key as entered by the
user, the transformed user key is (for those algoriths which do
this) the user key transformed by whatever key preprocessing method
is used, stored in canonical form. The IV is the initial IV stored
in canonical form */
BYTE userKey[ CRYPT_MAX_KEYSIZE ]; /* User encryption key */
BYTE transUserKey[ CRYPT_MAX_KEYSIZE ]; /* Transformed user key */
BYTE iv[ CRYPT_MAX_IVSIZE ]; /* Initial IV */
int userKeyLength; /* User encryption key length in bytes */
int ivLength; /* IV length in bytes */
BOOLEAN keySet; /* Whether the key is set up */
BOOLEAN ivSet; /* Whether the IV is set up */
/* Keying information. The key is the raw encryption key stored in
whatever form is required by the algorithm. This may be simply an
endianness-adjusted form of the transformed key (in the case of
algorithms like MDC/SHS) or a processed form of the user key (in the
case of algorithms like DES or IDEA). The IV is the current working
IV stored in an endianness-adjusted form. The ivCount is the number
of bytes of IV in use, and may be used for various chaining modes.
These fields may be unused if the algorithm is implemented in hardware */
void *key; /* Internal working key */
BYTE currentIV[ CRYPT_MAX_IVSIZE ]; /* Internal working IV */
int keyLength; /* Internal key length in bytes */
int ivCount; /* Internal IV count for chaining modes */
/* Private data needed by the algorithm */
void *privateData; /* For private use */
/* A check value so we can determine whether the crypt context has been
initialised or not. This is needed because passing in an
uninitialised block of memory as a crypt context can lead to problems
when we try to dereference wild pointers */
LONG checkValue;
} CRYPT_INFO;
/* Extra algorithm-specific information stored within a crypt context. Set
the parameter values to CRYPT_USE_DEFAULT to use the default values for
this algorithm */
typedef struct {
int keySetupIterations; /* No.iterations for user key setup */
} CRYPT_INFO_MDCSHS;
typedef struct {
int rounds; /* Number of encryption rounds */
int currentRounds; /* Internal number of rounds for this key */
BOOLEAN useSaferSK; /* Whether to use strengthened-key version */
} CRYPT_INFO_SAFER;
/* Results returned from the encryption capability query */
typedef struct {
/* The algorithm, encryption mode, and algorithm name */
CRYPT_ALGO cryptAlgo; /* The encryption algorithm */
CRYPT_MODE cryptMode; /* The encryption mode */
char *algoName; /* The algorithm name */
/* The algorithm parameters */
int blockSize; /* The basic block size of the algorithm */
int minKeySize; /* Minimum key size in bytes */
int keySize; /* Recommended key size in bytes */
int maxKeySize; /* Maximum key size in bytes */
int minIVsize; /* Minimum IV size in bytes */
int ivSize; /* Recommended IV size in bytes */
int maxIVsize; /* Maximum IV size in bytes */
/* Various algorithm characteristics */
int speed; /* Speed relative to block copy */
} CRYPT_QUERY_INFO;
/****************************************************************************
* *
* Status Codes *
* *
****************************************************************************/
/* No error in function call */
#define CRYPT_OK 0 /* No error */
/* Generic internal error */
#define CRYPT_ERROR -1 /* Nonspecific error */
/* Failed self-test in encryption code */
#define CRYPT_SELFTEST -2 /* Failed self-test */
/* Error in parameters passed to function */
#define CRYPT_BADPARM -3 /* Generic bad argument to function */
#define CRYPT_BADPARM1 -4 /* Bad argument, parameter 1 */
#define CRYPT_BADPARM2 -5 /* Bad argument, parameter 2 */
#define CRYPT_BADPARM3 -6 /* Bad argument, parameter 3 */
#define CRYPT_BADPARM4 -7 /* Bad argument, parameter 4 */
#define CRYPT_BADPARM5 -8 /* Bad argument, parameter 5 */
#define CRYPT_BADPARM6 -9 /* Bad argument, parameter 6 */
#define CRYPT_BADPARM7 -10 /* Bad argument, parameter 7 */
#define CRYPT_BADPARM8 -11 /* Bad argument, parameter 8 */
#define CRYPT_BADPARM9 -12 /* Bad argument, parameter 9 */
#define CRYPT_BADPARM10 -13 /* Bad argument, parameter 10 */
#define CRYPT_BADPARM11 -14 /* Bad argument, parameter 11 */
#define CRYPT_BADPARM12 -15 /* Bad argument, parameter 12 */
#define CRYPT_BADPARM13 -16 /* Bad argument, parameter 13 */
#define CRYPT_BADPARM14 -17 /* Bad argument, parameter 14 */
#define CRYPT_BADPARM15 -18 /* Bad argument, parameter 15 */
/* Errors due to insufficient resources */
#define CRYPT_NOMEM -19 /* Out of memory */
#define CRYPT_NOTINITED -20 /* Data has not been initialised */
#define CRYPT_INITED -21 /* Data has already been initialised */
#define CRYPT_NOALGO -22 /* Algorithm unavailable */
#define CRYPT_NOMODE -23 /* Encryption mode unavailable */
#define CRYPT_NOKEY -24 /* Key not initialised */
#define CRYPT_NOIV -25 /* IV not initialised */
/* A macro to detect an error return value */
#define isStatusError(status) ( ( status ) < CRYPT_OK )
#define isStatusOK(status) ( ( status ) == CRYPT_OK )
/****************************************************************************
* *
* Private Functions *
* *
****************************************************************************/
/* Functions to convert the endianness from the canonical form to the
internal form. These are only needed on little-endian machines */
#ifdef LITTLE_ENDIAN
void longReverse( LONG *buffer, int count );
void wordReverse( WORD *buffer, int count );
#else
#define longReverse(x,y)
#define wordReverse(x,y)
#endif /* LITTLE_ENDIAN */
/* A free() which sanitises the memory before it frees it */
void secureFree( void **pointer, int count );
/****************************************************************************
* *
* Public Functions *
* *
****************************************************************************/
/* Initialise and shut down the encryption library */
CRET initLibrary( void );
CRET endLibrary( void );
/* Query the capabilities of the encryption library */
CRET queryModeAvailability( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode );
CRET queryAlgoAvailability( CRYPT_ALGO cryptAlgo );
CRET queryAlgoModeInformation( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, CRYPT_QUERY_INFO CPTR cryptQueryInfo );
CRET queryContextInformation( CRYPT_INFO CPTR cryptInfo, CRYPT_QUERY_INFO CPTR cryptQueryInfo );
/* Initialise and destroy an encryption context */
CRET initCryptContext( CRYPT_INFO CPTR cryptInfo, CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode );
CRET initCryptContextEx( CRYPT_INFO CPTR cryptInfo, CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, void *cryptInfoEx );
CRET destroyCryptContext( CRYPT_INFO CPTR cryptInfo );
/* Load a user key into a crypt context */
CRET loadCryptContext( CRYPT_INFO CPTR cryptInfo, void CPTR key, int keyLength );
/* Load/retreive an IV into/from a crypt context */
CRET loadIV( CRYPT_INFO CPTR cryptInfo, void CPTR iv, int length );
CRET retrieveIV( CRYPT_INFO CPTR cryptInfo, void CPTR iv );
/* Encrypt/decrypt a block of memory */
CRET encryptBuffer( CRYPT_INFO CPTR cryptInfo, void CPTR buffer, int length );
CRET decryptBuffer( CRYPT_INFO CPTR cryptInfo, void CPTR buffer, int length );
#endif /* _CRYPT_DEFINED */
+23
View File
@@ -0,0 +1,23 @@
; Definition file for Crypt DLL
LIBRARY CRYPTNT
DESCRIPTION 'Encryption DLL'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 8192
EXPORTS initLibrary
endLibrary
queryModeAvailability
queryAlgoAvailability
queryAlgoModeInformation
queryContextInformation
initCryptContext
initCryptContextEx
destroyCryptContext
loadCryptContext
loadIV
retrieveIV
encryptBuffer
decryptBuffer
IMPORTS
+391
View File
@@ -0,0 +1,391 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "CRYPTNT.MAK" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
MTL=MkTypLib.exe
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : .\cryptnt.dll $(OUTDIR)/CRYPTNT.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE CPP /nologo /MT /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /c
# SUBTRACT CPP /YX /Fr
CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
"__WINDOWS__" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
RSC_PROJ=/l 0x409 /fo$(INTDIR)/"CRYPTNT.res" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_SBRS= \
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"CRYPTNT.bsc"
$(OUTDIR)/CRYPTNT.bsc : $(OUTDIR) $(BSC32_SBRS)
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DLL /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /NOLOGO /VERSION:0,99 /SUBSYSTEM:windows /DLL /PDB:none /MACHINE:I386 /OUT:"cryptnt.dll"
LINK32_FLAGS=kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib\
shell32.lib /NOLOGO /VERSION:0,99 /SUBSYSTEM:windows /DLL /PDB:none\
/MACHINE:I386 /DEF:".\CRYPTNT.DEF" /OUT:"cryptnt.dll"\
/IMPLIB:$(OUTDIR)/"CRYPTNT.lib"
DEF_FILE=.\CRYPTNT.DEF
LINK32_OBJS= \
$(INTDIR)/SHS.OBJ \
$(INTDIR)/LIB_IDEA.OBJ \
$(INTDIR)/SET_KEY.OBJ \
$(INTDIR)/CRYPTNT.res \
$(INTDIR)/3ECB_ENC.OBJ \
$(INTDIR)/IDEA.OBJ \
$(INTDIR)/CRYPT.OBJ \
$(INTDIR)/LIB_MDC.OBJ \
$(INTDIR)/LIB_RC4.OBJ \
$(INTDIR)/LIB_3DES.OBJ \
$(INTDIR)/LIB_NULL.OBJ \
$(INTDIR)/LIB_DES.OBJ \
$(INTDIR)/RC4.OBJ \
$(INTDIR)/ECB_ENC.OBJ \
$(INTDIR)/PCBC_ENC.OBJ \
$(INTDIR)/SAFER.OBJ \
$(INTDIR)/LIB_SAFR.OBJ
.\cryptnt.dll : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : .\cryptnt.dll $(OUTDIR)/CRYPTNT.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE CPP /nologo /MT /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /c
# ADD CPP /nologo /MT /W3 /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /c
# SUBTRACT CPP /YX /Fr
CPP_PROJ=/nologo /MT /W3 /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D\
"__WINDOWS__" /Fo$(INTDIR)/ /Fd$(OUTDIR)/"CRYPTNT.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
RSC_PROJ=/l 0x409 /fo$(INTDIR)/"CRYPTNT.res" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_SBRS= \
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"CRYPTNT.bsc"
$(OUTDIR)/CRYPTNT.bsc : $(OUTDIR) $(BSC32_SBRS)
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /NOLOGO /SUBSYSTEM:windows /DLL /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib /NOLOGO /VERSION:0,99 /SUBSYSTEM:windows /DLL /PDB:none /DEBUG /MACHINE:I386 /OUT:"cryptnt.dll"
LINK32_FLAGS=kernel32.lib user32.lib winspool.lib comdlg32.lib advapi32.lib\
shell32.lib /NOLOGO /VERSION:0,99 /SUBSYSTEM:windows /DLL /PDB:none /DEBUG\
/MACHINE:I386 /DEF:".\CRYPTNT.DEF" /OUT:"cryptnt.dll"\
/IMPLIB:$(OUTDIR)/"CRYPTNT.lib"
DEF_FILE=.\CRYPTNT.DEF
LINK32_OBJS= \
$(INTDIR)/SHS.OBJ \
$(INTDIR)/LIB_IDEA.OBJ \
$(INTDIR)/SET_KEY.OBJ \
$(INTDIR)/CRYPTNT.res \
$(INTDIR)/3ECB_ENC.OBJ \
$(INTDIR)/IDEA.OBJ \
$(INTDIR)/CRYPT.OBJ \
$(INTDIR)/LIB_MDC.OBJ \
$(INTDIR)/LIB_RC4.OBJ \
$(INTDIR)/LIB_3DES.OBJ \
$(INTDIR)/LIB_NULL.OBJ \
$(INTDIR)/LIB_DES.OBJ \
$(INTDIR)/RC4.OBJ \
$(INTDIR)/ECB_ENC.OBJ \
$(INTDIR)/PCBC_ENC.OBJ \
$(INTDIR)/SAFER.OBJ \
$(INTDIR)/LIB_SAFR.OBJ
.\cryptnt.dll : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\MDC\SHS.C
DEP_SHS_C=\
.\CRYPT.H\
.\MDC\SHS.H
$(INTDIR)/SHS.OBJ : $(SOURCE) $(DEP_SHS_C) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_IDEA.C
DEP_LIB_I=\
.\CRYPT.H\
.\IDEA\IDEA.H\
.\TESTIDEA.H
$(INTDIR)/LIB_IDEA.OBJ : $(SOURCE) $(DEP_LIB_I) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIBDES\SET_KEY.C
DEP_SET_K=\
.\LIBDES\DES_LOCL.H\
.\LIBDES\PODD.H\
.\LIBDES\SK.H\
.\LIBDES\DES.H
$(INTDIR)/SET_KEY.OBJ : $(SOURCE) $(DEP_SET_K) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\CRYPTNT.RC
$(INTDIR)/CRYPTNT.res : $(SOURCE) $(INTDIR)
$(RSC) $(RSC_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\CRYPTNT.DEF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIBDES\3ECB_ENC.C
DEP_3ECB_=\
.\LIBDES\DES_LOCL.H\
.\LIBDES\DES.H
$(INTDIR)/3ECB_ENC.OBJ : $(SOURCE) $(DEP_3ECB_) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\IDEA\IDEA.C
DEP_IDEA_=\
.\CRYPT.H\
.\IDEA\IDEA.H
$(INTDIR)/IDEA.OBJ : $(SOURCE) $(DEP_IDEA_) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\CRYPT.C
DEP_CRYPT=\
.\CRYPT.H
$(INTDIR)/CRYPT.OBJ : $(SOURCE) $(DEP_CRYPT) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_MDC.C
DEP_LIB_M=\
.\CRYPT.H\
.\MDC\SHS.H
$(INTDIR)/LIB_MDC.OBJ : $(SOURCE) $(DEP_LIB_M) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_RC4.C
DEP_LIB_R=\
.\CRYPT.H\
.\RC4\RC4.H\
.\TESTRC4.H
$(INTDIR)/LIB_RC4.OBJ : $(SOURCE) $(DEP_LIB_R) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_3DES.C
DEP_LIB_3=\
.\CRYPT.H\
.\LIBDES\DES.H
$(INTDIR)/LIB_3DES.OBJ : $(SOURCE) $(DEP_LIB_3) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_NULL.C
DEP_LIB_N=\
.\CRYPT.H
$(INTDIR)/LIB_NULL.OBJ : $(SOURCE) $(DEP_LIB_N) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_DES.C
DEP_LIB_D=\
.\CRYPT.H\
.\LIBDES\DES.H\
.\TESTDES.H
$(INTDIR)/LIB_DES.OBJ : $(SOURCE) $(DEP_LIB_D) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\RC4\RC4.C
DEP_RC4_C=\
.\RC4\RC4.H
$(INTDIR)/RC4.OBJ : $(SOURCE) $(DEP_RC4_C) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIBDES\ECB_ENC.C
DEP_ECB_E=\
.\LIBDES\DES_LOCL.H\
.\LIBDES\SPR.H\
.\LIBDES\VERSION.H\
.\LIBDES\DES.H
$(INTDIR)/ECB_ENC.OBJ : $(SOURCE) $(DEP_ECB_E) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIBDES\PCBC_ENC.C
DEP_PCBC_=\
.\LIBDES\DES_LOCL.H\
.\LIBDES\DES.H
$(INTDIR)/PCBC_ENC.OBJ : $(SOURCE) $(DEP_PCBC_) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\SAFER\SAFER.C
DEP_SAFER=\
.\SAFER\SAFER.H
$(INTDIR)/SAFER.OBJ : $(SOURCE) $(DEP_SAFER) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\LIB_SAFR.C
DEP_LIB_S=\
.\CRYPT.H\
.\SAFER\SAFER.H\
.\TESTSAFR.H
$(INTDIR)/LIB_SAFR.OBJ : $(SOURCE) $(DEP_LIB_S) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################
+33
View File
@@ -0,0 +1,33 @@
; Resource file for the Windows 32-bit encryption library
#include <ver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,99
PRODUCTVERSION 0,0,0,99
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252 ; US English, Windoze charset
END
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" ; US English, Windoze charset data
BEGIN
VALUE "CompanyName", "Peter Gutmann et al.\0"
VALUE "FileDescription", "Encryption library.\0"
VALUE "FileVersion", "0.99\0"
VALUE "InternalName", "CRYPT.DLL\0"
VALUE "LegalCopyright", "Copyright \251 Peter Gutmann, Eric Young, Colin Plumb 1994, 1995.\0"
VALUE "OriginalFilename", "CRYPT.DLL\0"
VALUE "ProductName", "Encryption library.\0"
VALUE "ProductVersion", "0.99\0"
END
END
END
+24
View File
@@ -0,0 +1,24 @@
; Definition file for Crypt DLL
LIBRARY CRYPT
DESCRIPTION 'Encryption DLL'
EXETYPE WINDOWS 3
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 8192
EXPORTS initLibrary
endLibrary
queryModeAvailability
queryAlgoAvailability
queryAlgoModeInformation
queryContextInformation
initCryptContext
initCryptContextEx
destroyCryptContext
loadCryptContext
loadIV
retrieveIV
encryptBuffer
decryptBuffer
IMPORTS
+24
View File
@@ -0,0 +1,24 @@
; Definition file for Crypt DLL
LIBRARY CRYPT
DESCRIPTION 'Encryption DLL'
EXETYPE WINDOWS 3
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 8192
EXPORTS initLibrary
endLibrary
queryModeAvailability
queryAlgoAvailability
queryAlgoModeInformation
queryContextInformation
initCryptContext
initCryptContextEx
destroyCryptContext
loadCryptContext
loadIV
retrieveIV
encryptBuffer
decryptBuffer
IMPORTS
+255
View File
@@ -0,0 +1,255 @@
# Microsoft Visual C++ generated build script - Do not modify
PROJ = CRYPTWIN
DEBUG = 0
PROGTYPE = 1
CALLER =
ARGS =
DLLS =
D_RCDEFINES = -d_DEBUG
R_RCDEFINES = -dNDEBUG
ORIGIN = MSVC
ORIGIN_VER = 1.00
PROJPATH = C:\WORK\CRYPT\
USEMFC = 0
CC = cl
CPP = cl
CXX = cl
CCREATEPCHFLAG =
CPPCREATEPCHFLAG =
CUSEPCHFLAG =
CPPUSEPCHFLAG =
FIRSTC = CRYPT.C
FIRSTCPP =
RC = rc
CFLAGS_D_WDLL = /nologo /G2 /W3 /Zi /ALw /Od /D "_DEBUG" /D "__WINDOWS__" /GD /Fd"CRYPT.PDB"
CFLAGS_R_WDLL = /nologo /G2 /W3 /ALw /O1 /D "NDEBUG" /D "__WINDOWS__" /GD
LFLAGS_D_WDLL = /NOLOGO /NOD /NOE /PACKC:61440 /ALIGN:16 /ONERROR:NOEXE /CO
LFLAGS_R_WDLL = /NOLOGO /NOD /NOE /PACKC:61440 /ALIGN:16 /ONERROR:NOEXE
LIBS_D_WDLL = oldnames libw ldllcew
LIBS_R_WDLL = oldnames libw ldllcew
RCFLAGS = /nologo
RESFLAGS = /nologo
RUNFLAGS =
DEFFILE = CRYPTWIN.DEF
OBJS_EXT =
LIBS_EXT =
!if "$(DEBUG)" == "1"
CFLAGS = $(CFLAGS_D_WDLL)
LFLAGS = $(LFLAGS_D_WDLL)
LIBS = $(LIBS_D_WDLL)
MAPFILE = nul
RCDEFINES = $(D_RCDEFINES)
!else
CFLAGS = $(CFLAGS_R_WDLL)
LFLAGS = $(LFLAGS_R_WDLL)
LIBS = $(LIBS_R_WDLL)
MAPFILE = nul
RCDEFINES = $(R_RCDEFINES)
!endif
!if [if exist MSVC.BND del MSVC.BND]
!endif
SBRS = CRYPT.SBR \
LIB_3DES.SBR \
LIB_IDEA.SBR \
LIB_DES.SBR \
LIB_MDC.SBR \
LIB_NULL.SBR \
LIB_RC4.SBR \
IDEA.SBR \
3ECB_ENC.SBR \
ECB_ENC.SBR \
PCBC_ENC.SBR \
SET_KEY.SBR \
RC4.SBR \
SHS.SBR \
SAFER.SBR \
LIB_SAFR.SBR
CRYPT_DEP = c:\work\crypt\crypt.h
LIB_3DES_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\libdes/des.h
LIB_IDEA_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\idea/idea.h \
c:\work\crypt\testidea.h
LIB_DES_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\libdes/des.h \
c:\work\crypt\testdes.h
LIB_MDC_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\mdc/shs.h
LIB_NULL_DEP = c:\work\crypt\crypt.h
LIB_RC4_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\rc4/rc4.h \
c:\work\crypt\testrc4.h
CRYPTWIN_RCDEP =
IDEA_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\idea\idea.h \
idea/idea.h
3ECB_ENC_DEP = c:\work\crypt\libdes\des_locl.h \
c:\work\crypt\libdes\des.h \
libdes/des.h \
libdes/des_locl.h
ECB_ENC_DEP = c:\work\crypt\libdes\des_locl.h \
c:\work\crypt\libdes\des.h \
libdes/des.h \
c:\work\crypt\libdes\spr.h \
c:\work\crypt\libdes\version.h \
libdes/des_locl.h \
libdes/spr.h \
libdes/version.h
PCBC_ENC_DEP = c:\work\crypt\libdes\des_locl.h \
c:\work\crypt\libdes\des.h \
libdes/des.h \
libdes/des_locl.h
SET_KEY_DEP = c:\work\crypt\libdes\des_locl.h \
c:\work\crypt\libdes\des.h \
libdes/des.h \
c:\work\crypt\libdes\podd.h \
c:\work\crypt\libdes\sk.h \
libdes/des_locl.h \
libdes/podd.h \
libdes/sk.h
RC4_DEP = c:\work\crypt\rc4\rc4.h \
rc4/rc4.h
SHS_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\mdc\shs.h \
mdc/shs.h
SAFER_DEP = c:\work\crypt\safer\safer.h \
safer/safer.h
LIB_SAFR_DEP = c:\work\crypt\crypt.h \
c:\work\crypt\safer/safer.h \
c:\work\crypt\testsafr.h
all: $(PROJ).DLL
CRYPT.OBJ: CRYPT.C $(CRYPT_DEP)
$(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c CRYPT.C
LIB_3DES.OBJ: LIB_3DES.C $(LIB_3DES_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_3DES.C
LIB_IDEA.OBJ: LIB_IDEA.C $(LIB_IDEA_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_IDEA.C
LIB_DES.OBJ: LIB_DES.C $(LIB_DES_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_DES.C
LIB_MDC.OBJ: LIB_MDC.C $(LIB_MDC_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_MDC.C
LIB_NULL.OBJ: LIB_NULL.C $(LIB_NULL_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_NULL.C
LIB_RC4.OBJ: LIB_RC4.C $(LIB_RC4_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_RC4.C
CRYPTWIN.RES: CRYPTWIN.RC $(CRYPTWIN_RCDEP)
$(RC) $(RCFLAGS) $(RCDEFINES) -r CRYPTWIN.RC
IDEA.OBJ: IDEA\IDEA.C $(IDEA_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c IDEA\IDEA.C
3ECB_ENC.OBJ: LIBDES\3ECB_ENC.C $(3ECB_ENC_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIBDES\3ECB_ENC.C
ECB_ENC.OBJ: LIBDES\ECB_ENC.C $(ECB_ENC_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIBDES\ECB_ENC.C
PCBC_ENC.OBJ: LIBDES\PCBC_ENC.C $(PCBC_ENC_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIBDES\PCBC_ENC.C
SET_KEY.OBJ: LIBDES\SET_KEY.C $(SET_KEY_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIBDES\SET_KEY.C
RC4.OBJ: RC4\RC4.C $(RC4_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c RC4\RC4.C
SHS.OBJ: MDC\SHS.C $(SHS_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c MDC\SHS.C
SAFER.OBJ: SAFER\SAFER.C $(SAFER_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c SAFER\SAFER.C
LIB_SAFR.OBJ: LIB_SAFR.C $(LIB_SAFR_DEP)
$(CC) $(CFLAGS) $(CUSEPCHFLAG) /c LIB_SAFR.C
$(PROJ).DLL:: CRYPTWIN.RES
$(PROJ).DLL:: CRYPT.OBJ LIB_3DES.OBJ LIB_IDEA.OBJ LIB_DES.OBJ LIB_MDC.OBJ LIB_NULL.OBJ \
LIB_RC4.OBJ IDEA.OBJ 3ECB_ENC.OBJ ECB_ENC.OBJ PCBC_ENC.OBJ SET_KEY.OBJ RC4.OBJ SHS.OBJ \
SAFER.OBJ LIB_SAFR.OBJ $(OBJS_EXT) $(DEFFILE)
echo >NUL @<<$(PROJ).CRF
CRYPT.OBJ +
LIB_3DES.OBJ +
LIB_IDEA.OBJ +
LIB_DES.OBJ +
LIB_MDC.OBJ +
LIB_NULL.OBJ +
LIB_RC4.OBJ +
IDEA.OBJ +
3ECB_ENC.OBJ +
ECB_ENC.OBJ +
PCBC_ENC.OBJ +
SET_KEY.OBJ +
RC4.OBJ +
SHS.OBJ +
SAFER.OBJ +
LIB_SAFR.OBJ +
$(OBJS_EXT)
$(PROJ).DLL
$(MAPFILE)
G:\MSVC15\LIB\+
G:\MSVC15\MFC\LIB\+
$(LIBS)
$(DEFFILE);
<<
link $(LFLAGS) @$(PROJ).CRF
$(RC) $(RESFLAGS) CRYPTWIN.RES $@
@copy $(PROJ).CRF MSVC.BND
implib /nowep $(PROJ).LIB $(PROJ).DLL
$(PROJ).DLL:: CRYPTWIN.RES
if not exist MSVC.BND $(RC) $(RESFLAGS) CRYPTWIN.RES $@
run: $(PROJ).DLL
$(PROJ) $(RUNFLAGS)
$(PROJ).BSC: $(SBRS)
bscmake @<<
/o$@ $(SBRS)
<<
+33
View File
@@ -0,0 +1,33 @@
; Resource file for the encryption library
#include <ver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,99
PRODUCTVERSION 0,0,0,99
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS16
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252 ; US English, Windoze charset
END
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" ; US English, Windoze charset data
BEGIN
VALUE "CompanyName", "Peter Gutmann et al.\0"
VALUE "FileDescription", "Encryption library.\0"
VALUE "FileVersion", "0.99\0"
VALUE "InternalName", "CRYPT.DLL\0"
VALUE "LegalCopyright", "Copyright \251 Peter Gutmann, Eric Young, Colin Plumb 1994, 1995.\0"
VALUE "OriginalFilename", "CRYPT.DLL\0"
VALUE "ProductName", "Encryption library.\0"
VALUE "ProductVersion", "0.99\0"
END
END
END
+613
View File
@@ -0,0 +1,613 @@
After much procrastinating I'm finally ready to release the initial version of
my encryption library. I wrote this in response to random requests I keep
seeing in various newsgroups for encryption libraries, usually with no
responses. This library provides a (hopefully) universal interface to all
kinds of conventional-key encryption algorithms in an easy-to-use manner. The
library is divided into two parts:
1. Routines to query the library capabilities.
2. Routines to perform the en/decryption.
The library currently provides the following encryption algorithms and modes:
MDC/SHS CFB
DES ECB, CBC, CFB, OFB, PCBC
3DES ECB, CBC, CFB, OFB
IDEA ECB, CBC, CFB, OFB
RC4
SAFER ECB, CBC, CFB, OFB
SAFER-SK ECB, CBC, CFB, OFB
Notes:
1. The Visual Basic interface hasn't been tested much. If someone could do
a Delphi interface and a VBX or OCX version that'd be nice.
2. A proper configure script with everything would be nice for Unix users.
Anyone want to create one of these?
3. Optimised asm implementations of some of the routines would be useful.
There are 80x86 and 68K asm routines included for IDEA and RC4, but I
haven't had time to tie them into the code yet. I have 386+ asm code for
SHA, but need to tie that in as well. Volunteers?
Requirements for a Standard Encryption Library
----------------------------------------------
- It should be idiot-proof.
It's quite difficult to implement insecure encryption using this code without
actually trying.
- It should provide extensive error checking.
Each parameter and function call is checked for errors before any actions are
performed, with error reporting down to the level of individual parameters.
- It should be portable.
The library is written entirely in ANSI C, with hooks for certain OS-specific
oddities such as Windows/OS/2 dynamic link libraries. The only external
routines used are ones from <string.h> and one call from <time.h>.
- It should be extendable.
The library provides the capability to add encryption capabilities at runtime
(currently only partially implemented, since the interface is somewhat messy
- you need to pass in about 15 parameters to do it).
- It should be free of silly restrictions.
This software is distributed as copyrighted freeware, with copyrights on
individual encryption modules being held by the contributing authors. You
are free to use the code in any way you want, with the following
restrictions:
If you make any changes to the code, you should send a copy of the changes
to the author or authors to allow them to integrate the changes into the
code. This is to allow a central consistent version to be maintained.
If you use the library as part of a product, you should offer a copy to the
author or authors of the library routines you are using. This is to let
the authors know that their work is being usefully applied.
Any commercial software you create with this code may not be merely a set
or subset of the encryption libraries, with or without minor added
functionality. This is to stop people adding their own wrappers and
selling it as "their" encryption product.
These terms are pretty much identical the the library GPL, which seem to be
about the least restrictive usage terms around apart from outright public
domain software.
- It should be buzzword-complete.
The library is written in C, but is basically laid out as a C++ class
library. It can work as a static library, a shared library, or a dynamic
link library. It'll even work with things like Visual Basic.
Library Basics
--------------
Like the standard C file I/O libraries which work with FILE objects, this
library works with an "encryption context" of type CRYPT_INFO. To encrypt
data, you create an encryption context, load a user key into it, en/decrypt
data, and destroy it when you've finished. This concept lends itself to
implementation either as a C++ class or as C routines. Throughout this
document all examples are given in C, translation to C++ is a simple step.
The overall library structure is as follows:
Library core Plug-in
modules
+---------------+------------+
| | MDC/SHS |
| +------------+
| | DES |
| +------------+
/ \ | Crypt | Triple DES |
User / ---- \ | +------------+
Programs \ ---- / | Library | IDEA |
\ / | +------------+
| API | RC4 |
| +------------+
| | Safer |
| +------------+
| | others |
+---------------+------------+
The library API serves as an interface to a range of plug-in encryption modules
which allow encryption algorithms to be added in a fairly transparent manner.
The standardised API allows any of the algorithms and modes supported by the
library to be used with a minimum of coding effort. As such the main function
of the library is to provide a standard, portable, easy-to-use interface
between the underlying encryption routines and the user software.
Portability
-----------
All data made accessible through the library API is in big-endian format. The
library automatically takes care of endianness conversion to the form used by
the local system in a manner invisible to the end user.
All code is plain ANSI C, with no machine or OS-specific functions or calls
being used.
Creating/Destroying Encryption Contexts
---------------------------------------
When you create an encryption context, you must specify the encryption
algorithm and mode you want to use for that context. The encryption algorithms
and modes are given in the crypt.h file, and are updated along with the library
itself. For example, to create and destroy an encryption context for DES in
CBC mode, you would use the following code:
CRYPT_INFO cryptInfo;
initCryptContext( &cryptInfo, CRYPT_ALGO_DES, CRYPT_MODE_CBC );
/* Perform en/decryption */
endCryptContext( &cryptInfo );
The initCryptContext() and endCryptContext() functions take care of issues like
initialization, memory management, and erasure of data after use.
Loading Keys into Encryption Contexts
-------------------------------------
Once an encryption context has been created, you need to load a key into it.
This is done with the loadCryptContext() function. For example to load the key
"Secret key" into the previously-created encryption context you would use:
loadCryptContext( &cryptInfo, "Secret key", 10 );
Some hardware modules which enforce red/black seperation will not allow
plaintext keys to pass across the library interface. In this case the key
parameter passed to loadCryptContext() will be a key selector or key encryption
key to be passed to the underlying hardware. For example to pass a key
selector to a key stored inside a DES hardware module you would use:
loadCryptContext( &cryptInfo, &keySelector, sizeof( keySelector ) );
You can also load an IV into the context, although for encryption you would
usually leave this to the library to perform automatically. To load an IV you
would use:
loadIV( &cryptInfo, iv, ivSize );
To retrieve an IV which has been generated by the library you would use:
retrieveIV( &cryptInfo, iv );
The loadCryptContext(), loadIV(), and retrieveIV() functions take care of
issues like initialization, memory management, endianness conversion, and key
setup.
If you need to reserver space for keys and IV's, you can use the
CRYPT_MAX_KEYSIZE and CRYPT_MAX_IVSIZE defines from crypt.h to determine the
mount of memory you need. No key or IV used by the library will ever need more
storage than the settings given in these defines.
Encrypting/Decrypting Data
--------------------------
Now that the encryption context and (if necessary) IV are set up, you're ready
to encrypt or decrypt data. To encrypt or decrypt a block of data you use:
encryptBuffer( &cryptInfo, buffer, length );
and:
decryptBuffer( &cryptInfo, buffer, length );
If a block encryption mode is being used, these functions will recognise a call
with length == 0 as a courtesy call to indicate that this is the last data
block and will take whatever special action is necessary for this case.
Extended Initialization
-----------------------
The initCryptContext() has a companion function initCryptContextEx() which may
be used to perform an extended, algorithm-specific initialisation. The second
parameter passed to the function is an algorithm-dependant structure used to
specify extra information to be used in the initalisation. Not all algorithms
will support extended initialisation parameters. If they are supported, the
structures have the name CRYPT_INFO_<algorithm_name>, and are laid out as
follows:
Structure CRYPT_INFO_MDCSHS:
/* The number of iterations used during the key setup process triggered
by a loadCryptContext() call. Using a high value (500 or more) will
greatly slow down password-guessing attacks by making the key setup
process painfully slow. Values in the range of 50-100 are recommended for
most systems */
int keySetupIterations;
Structure CRYPT_INFO_SAFER:
/* The number of rounds of encryption. The default settings are 6 rounds for
SAFER-K64, 8 rounds for SAFER-SK64, and 10 rounds for SAFER-K128 and
SAFER-SK128 */
int rounds;
/* Whether to use SAFER or SAFER-SK. The default is to use the original
algorithm SAFER. SAFER-SK is a version which improves the key schedule to
eliminate some possible weaknesses when SAFER is used as a keyed hash
function */
BOOLEAN useSaferSK;
Error Checking
--------------
When the library is initialised, each of the built-in encryption algorithms
goes through a self-test procedure which checks the implementation using
standard test vectors and methods given with the algorithm specification
(typically FIPS publications, ANSI standards, or standard reference
implementations). This self-test is used to verify that each encryption
algorithm is performing as required.
Each function in the library performs extensive error checking (although
monitoring of error codes has been left out in the following code samples for
readability). The file TEST.C, included with the crypt library, includes
better error handling than the short examples below.
For functions which complete with no error, the library will return CRYPT_OK.
For functions which complete with some form of error internal to the library
itself, the library will return CRYPT_ERROR (this situation should never occur
and should be reported to the library authors).
If the encryption code or hardware fails an internal self-test, the library
will return CRYPT_SELFTEST if an attempt is made to use the encryption module
which failed the self-test.
If there is a problem with a parameter passed to a library function, the
library will return one of CRYPT_BADPARM1 ... CRYPT_BADPARM15 depending on the
parameter in error, or simply CRYPT_BADPARM if it cannot resolve the exact
parameter error type.
General resource and programming errors are flagged by the return values
CRYPT_NOMEM for a lack of memory, CRYPT_NOTINITED if you try to use an
encryption context hasn't been initialised yet or which has been destroyed,
CRYPT_INITED when you try to re-initialise an encryption context or re-load an
encryption key, CRYPT_NOALGO or CRYPT_NOMODE if the requested encryption
algorithm or mode is unavailable, CRYPT_NOKEY if the encryption key hasn't been
loaded into an encryption context, and CRYPT_NOIV if the IV hasn't been loaded
into an encryption context.
The macros isStatusError() and isStatusOK() can be used to determine whether a
return value denotes an error condition, for example:
int status;
status = initCryptContext( &cryptInfo, CRYPT_ALGO_IDEA, CRYPT_MODE_CFB );
if( isStatusError( status ) )
/* Perform error processing */
Examples
--------
The following examples have had error checking removed for readability. See
the test code in TEST.C for an example with full error checking.
To encrypt a buffer using DES in CFB mode with the password 0x12345678ABCDEF:
CRYPT_INFO cryptInfo;
BYTE key[] = { 0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD, 0xEF };
/* Load the key, encrypt the buffer (the IV is automatically generated
if we don't specify one, it can be obtained with retrieveIV()), and
destroy the encryption context */
initCryptContext( &cryptInfo, CRYPT_ALGO_DES, CRYPT_MODE_CFB );
loadCryptContext( &cryptInfo, key, sizeof( key ) );
encryptBuffer( &cryptInfo, buffer, length );
destroyCryptContext( &cryptInfo );
To hash an arbitrary-size passphrase down to the one used by a particular
cryptosystem (in this case triple DES) using MDC/SHS:
CRYPT_QUERY_INFO cryptQueryInfo;
CRYPT_INFO cryptInfo;
BYTE key[ 100 ];
int keySize, ivSize;
/* Find out how long we can make the key */
queryAlgoModeInformation( CRYPT_ALGO_3DES, CRYPT_MODE_CBC,
&cryptQueryInfo );
keySize = cryptQueryInfo->maxKeySize; /* Use all we can */
ivSize = cryptQueryInfo->ivSize;
/* Encrypt a null data block using a null IV with the passphrase as the
key. This works vaguely like the Unix password encryption except
that we don't have a salt (which would be the IV) */
memset( key, 0, keySize );
initCryptContext( &cryptInfo, CRYPT_ALGO_MDCSHS, CRYPT_MODE_CFB );
loadCryptContext( &cryptInfo, passphrase, strlen( passphrase ) );
loadIV( &cryptInfo, key, ivSize );
encryptBuffer( &cryptInfo, key, keySize );
destroyCryptContext( &cryptInfo );
To encrypt a file using triple DES in CBC mode with the key generated in the
previous example:
BOOLEAN firstTime = TRUE;
/* Load the previously-generated key */
initCryptContext( &cryptInfo, CRYPT_ALGO_3DES, CRYPT_MODE_CBC );
loadCryptContext( &cryptInfo, key, keySize );
/* Copy the data across, encrypting as we go */
while( ( length = fread( buffer, 1, BUFSIZE, inFile ) ) != 0 )
{
/* Encrypt the data in the buffer */
encryptBuffer( &cryptInfo, buffer, length );
/* If it's the first block, retrieve the IV and prepend it to the
output data. Note the since we've let the library generate the
IV for us automatically, we can't retrieve it until after the first
encryptBuffer() call */
if( firstTime )
{
CRYPT_QUERY_INFO cryptQueryInfo;
BYTE iv[ CRYPT_MAX_IVSIZE ];
int ivSize;
/* Find out how long the IV we're using is */
queryContextInformation( &cryptInfo, &cryptQueryInfo );
ivSize = cryptQueryInfo->ivSize;
/* Retrieve the IV and write it to the output file */
retrieveIV( &cryptInfo, iv );
fwrite( iv, 1, ivSize, outFile );
firstTime = FALSE;
}
/* Write the encrypted data to the output file */
fwrite( buffer, 1, length, outFile );
}
/* Since CBC is a block cipher, we perform a courtesy close call to let
the encryption routines handle the last block */
encryptBuffer( &cryptInfo, buffer, 0 );
destroyCryptContext( &cryptInfo );
To decrypt the previously encrypted file with the key generated in the previous
example:
CRYPT_QUERY_INFO cryptQueryInfo;
BYTE iv[ CRYPT_MAX_IVSIZE ];
int ivSize;
/* Load the previously-generated key */
initCryptContext( &cryptInfo, CRYPT_ALGO_3DES, CRYPT_MODE_CBC );
loadCryptContext( &cryptInfo, key, keySize );
/* Find out how long the IV we're using is */
queryContextInformation( &cryptInfo, &cryptQueryInfo );
ivSize = cryptQueryInfo->ivSize;
/* Read the IV from the input file and load it into the encryption
context */
fread( iv, 1, ivSize, inFile );
loadIV( &cryptInfo, iv, ivSize );
/* Copy the data across, decrypting as we go */
while( ( length = fread( buffer, 1, BUFSIZE, inFile ) ) != 0 )
{
/* Encrypt the data in the buffer */
decryptBuffer( &cryptInfo, buffer, length );
/* Write the decrypted data to the output file */
fwrite( buffer, 1, length, outFile );
}
/* Since CBC is a block cipher, we perform a courtesy close call to let
the encryption routines handle the last block */
decryptBuffer( &cryptInfo, buffer, 0 );
destroyCryptContext( &cryptInfo );
A longer usage example including proper error checking and with various other
test routines can be found in the file test.c included with the code.
Querying the Encryption Library Capabilities
--------------------------------------------
The previous examples showed the use of the queryAlgoModeInformation() and
queryContextInformation() calls to retrieve information about the
characteristics of a particular algorithm as implemented by the encryption
library. There are four such calls in total, of which two query the existence
of an implementation of an algorithm or algorithm/mode combination, and two
return information about the implementation.
The library can be interrogated about the existence of a particular encryption
algorithm or algorithm and encryption mode combination with:
status = queryAlgoAvailability( algorithm );
or:
status = queryModeAvailability( algorithm, mode );
In addition to requesting information on the availability of an encryption
algorithm and mode, you can request extra information to be returned in a
CRYPT_QUERY_INFO structure with:
status = queryAlgoModeInformation( algorithm, mode, &cryptQueryInfo );
or
status = queryContextInformation( &cryptInfo, &cryptQueryInfo );
with the former being used to request information on a given algorithm/mode
combination and the latter being used to request information about the
encryption context being used.
The CRYPT_QUERY_INFO structure contains the following fields:
/* The encryption algorithm, encryption mode, and general algorithm name
as an ASCII string */
CRYPT_ALGO cryptAlgo;
CRYPT_MODE cryptMode;
char *algoName;
/* The algorithm block size in bytes, the minimum, recommended, and
maximum key size in bytes, and the minimum, recommended, and maximum
IV size in bytes */
int blockSize;
int minKeySize;
int keySize;
int maxKeySize;
int minIVsize;
int ivSize;
int maxIVsize;
/* The algorithm speed relative to a block copy operation. This value
ranges from 1 ... CRYPT_MAX_SPEED, or CRYPT_ERROR if no speed rating is
available */
int speed;
Algorithm-Specific Notes
------------------------
MDCSHS:
None
DES:
loadCryptContext() will return a bad parameter code if the DES key parity is
wrong or if the key is a weak key (CRYPT_BADPARM2 in this case).
encryptBuffer() and decryptBuffer() will return a bad parameter code if the
encryption mode is ECB, CBC, or PCBC and the encrypted data length is not a
multiple of the block size (CRYPT_BADPARM3 in this case).
Triple DES:
loadCryptContext() will return a bad parameter code if the DES key parity is
wrong or if the key is a weak key (CRYPT_BADPARM2 in this case).
encryptBuffer() and decryptBuffer() will return a bad parameter code if the
encryption mode is ECB or CBC and the encrypted data length is not a multiple
of the block size (CRYPT_BADPARM3 in this case).
IDEA:
encryptBuffer() and decryptBuffer() will return a bad parameter code if the
encryption mode is ECB or CBC and the encrypted data length is not a multiple
of the block size (CRYPT_BADPARM3 in this case).
The IDEA algorithm is patented by Ascom Systec AG, CH-5506 Maegenwil,
Switzerland, ph. +41 64 56 59 45, email idea@ascom.ch, and cannot be used
commercially without a license. As of June 1995, the licensing terms were
120 SFr (about US$90) per user for 1-10 users, 80 Sfr (about US$60) per user
for 11-20 users, and 60 Sfr (about US$46) per user for 21-100 users.
RC4:
None
SAFER:
SAFER-SK:
encryptBuffer() and decryptBuffer() will return a bad parameter code if the
encryption mode is ECB or CBC and the encrypted data length is not a multiple
of the block size (CRYPT_BADPARM3 in this case).
Plug-In Module Implementation
-----------------------------
These notes are rather brief since there is a lot of ground to cover, and the
easiest way to see what is required is to look at the crypt.c code and the way
it interfaces to the lib_XXX.c code, which may be regarded as standard
implementations of a plug-in module (the triple DES and IDEA modules are
probably the best examples). Basically, implementors must provide the
following services in their plug-in modules:
int selfTestFunction( void );
Perform a self-test on the encryption hardware/software module. This
function is called once before any other function is called.
int initFunction( CRYPT_INFO *cryptInfo );
Initialise the appropriate private CRYPT_INFO fields.
int initExFunction( CRYPT_INFO *cryptInfo, void *cryptInfoEx );
Initialiase the appropriate private CRYPT_INFO fields based on the extended
information given in the second parameter.
int endFunction( CRYPT_INFO *cryptInfo );
Clear the appropriate private CRYPT_INFO fields.
int initKeyFunction( CRYPT_INFO *cryptInfo );
Initialise the internal key based on the user key. Typically this might
perform one or more of the following:
Hash the user key down to the size of the key used by the algorithm
Perform some type of key schedule operation
Perform endianness conversion for the current operating environment
Load the key into external crypto hardware.
Perform a key selection in external hardware based on the specified key
selector.
For algorithms with asymmetric internal keys, both an encryption and a
decryption key will have to be generated, as a crypt context may be used for
encryption or decryption.
int initIVFunction( CRYPT_INFO *cryptInfo );
Initialise the IV. Typically this might perform one or more of the
following:
Perform endianness conversion for the current operating environment
Load the IV into external crypto hardware.
int encryptFunction( CRYPT_INFO *cryptInfo, void *buffer, int length );
int decryptFunction( CRYPT_INFO *cryptInfo, void *buffer, int length );
Encrypt/decrypt a block of data based on the algorithm and keying information
in CRYPT_INFO. Some algorithms may require special handling for the last
block (eg block truncation in CBC) so both routines should recognise a call
with length = 0 to indicate the end of the encrypted data block.
Acknowledgements
----------------
The DES and 3DES encryption code was contributed by Eric Young
<eay@psych.psy.uq.oz.au> and is part of his libdes package. The primary ftp
site for the full libdes is
ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz. libdes is now also
shipped with SSLeay. The primary site for this is
ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.xx.tar.gz.
The IDEA code was contributed by Colin Plumb.
The SAFER code was written by Richard De Moliner <demoliner@isi.ee.ethz.ch> of
the Signal and Information Processing Laboratory, Swiss Federal Institute of
Technology.
+410
View File
@@ -0,0 +1,410 @@
/*
* idea.c - C source code for IDEA block cipher.
* IDEA (International Data Encryption Algorithm), formerly known as
* IPES (Improved Proposed Encryption Standard).
* Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
* This implementation modified and derived from original C code
* developed by Xuejia Lai.
* Zero-based indexing added, names changed from IPES to IDEA.
* CFB functions added. Random number routines added.
*
* Extensively optimized and restructured by Colin Plumb.
*
* There are two adjustments that can be made to this code to
* speed it up. Defaults may be used for PCs. Only the -DIDEA32
* pays off significantly if selectively set or not set.
* Experiment to see what works best for your machine.
*
* Multiplication: default is inline, -DAVOID_JUMPS uses a
* different version that does not do any conditional
* jumps (a few percent worse on a SPARC), while
* -DSMALL_CACHE takes it out of line to stay
* within a small on-chip code cache.
* Variables: normally, 16-bit variables are used, but some
* machines (notably RISCs) do not have 16-bit registers,
* so they do a great deal of masking. -DIDEA32 uses "int"
* register variables and masks explicitly only where
* necessary. On a SPARC, for example, this boosts
* performace by 30%.
*
* The IDEA(tm) block cipher is covered by patents held by ETH and a
* Swiss company called Ascom-Tech AG. The Swiss patent number is
* PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and
* the U.S. patent number is US005214703. IDEA(tm) is a trademark of
* Ascom-Tech AG. There is no license fee required for noncommercial
* use. Commercial users may obtain licensing details from Dieter
* Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn,
* Switzerland, Tel +41 65 242885, Fax +41 65 235761.
*
* The IDEA block cipher uses a 64-bit block size, and a 128-bit key
* size. It breaks the 64-bit cipher block into four 16-bit words
* because all of the primitive inner operations are done with 16-bit
* arithmetic. It likewise breaks the 128-bit cipher key into eight
* 16-bit words.
*
* For further information on the IDEA cipher, see the book:
* Xuejia Lai, "On the Design and Security of Block Ciphers",
* ETH Series on Information Processing (ed. J.L. Massey) Vol 1,
* Hartung-Gorre Verlag, Konstanz, Switzerland, 1992. ISBN
* 3-89191-573-X.
*
* This code runs on arrays of bytes by taking pairs in big-endian
* order to make the 16-bit words that IDEA uses internally. This
* produces the same result regardless of the byte order of the
* native CPU.
*/
#include <string.h>
#ifdef _MSC_VER
#include "../crypt.h"
#include "idea.h"
#else
#include "crypt.h"
#include "idea/idea.h"
#endif /* _MSC_VER */
#ifdef BIG_ENDIAN /* This code uses slightly different names */
#define HIGHFIRST
#endif /* BIG_ENDIAN */
#ifdef IDEA32 /* Use >16-bit temporaries */
#define low16(x) ((x) & 0xFFFF)
typedef unsigned int uint16; /* at LEAST 16 bits, maybe more */
#else
#define low16(x) (x) /* this is only ever applied to uint16's */
typedef word16 uint16;
#endif
#ifdef _GNUC_
/* __const__ simply means there are no side effects for this function,
* which is useful info for the gcc optimizer
*/
#define CONST __const__
#else
#define CONST
#endif
/*
* Multiplication, modulo (2**16)+1
* Note that this code is structured on the assumption that
* untaken branches are cheaper than taken branches, and the
* compiler doesn't schedule branches.
*/
#ifdef SMALL_CACHE
CONST static uint16
mul(register uint16 a, register uint16 b)
{
register word32 p;
p = (word32)a * b;
if (p) {
b = low16(p);
a = p>>16;
return (b - a) + (b < a);
} else if (a) {
return 1-b;
} else {
return 1-a;
}
} /* mul */
#endif /* SMALL_CACHE */
/*
* Compute the multiplicative inverse of x, modulo 65537, using Euclid's
* algorithm. It is unrolled twice to avoid swapping the registers each
* iteration, and some subtracts of t have been changed to adds.
*/
CONST static uint16
mulInv(uint16 x)
{
uint16 t0, t1;
uint16 q, y;
if (x <= 1)
return x; /* 0 and 1 are self-inverse */
t1 = 0x10001L / x; /* Since x >= 2, this fits into 16 bits */
y = 0x10001L % x;
if (y == 1)
return ( uint16 ) low16(1-t1);
t0 = 1;
do {
q = x / y;
x = x % y;
t0 += q * t1;
if (x == 1)
return t0;
q = y / x;
y = y % x;
t1 += q * t0;
} while (y != 1);
return ( uint16 ) low16(1-t1);
} /* mukInv */
/*
* Expand a 128-bit user key to a working encryption key EK
*/
void
ideaExpandKey(byte const *userkey, word16 *EK)
{
int i,j;
for (j=0; j<8; j++) {
EK[j] = (userkey[0]<<8) + userkey[1];
userkey += 2;
}
for (i=0; j < IDEAKEYLEN; j++) {
i++;
EK[i+7] = (EK[i & 7] << 9) | (EK[i+1 & 7] >> 7);
EK += i & 8;
i &= 7;
}
} /* ideaExpandKey */
/*
* Compute IDEA decryption key DK from an expanded IDEA encryption key EK
* Note that the input and output may be the same. Thus, the key is
* inverted into an internal buffer, and then copied to the output.
*/
void
#ifdef _DCC
ideaInvertKey(word16 *EK, word16 DK[IDEAKEYLEN])
#else
ideaInvertKey(word16 const *EK, word16 DK[IDEAKEYLEN])
#endif
{
int i;
uint16 t1, t2, t3;
word16 temp[IDEAKEYLEN];
word16 *p = temp + IDEAKEYLEN;
t1 = mulInv(*EK++);
t2 = - ( int ) *EK++;
t3 = - ( int ) *EK++;
*--p = mulInv(*EK++);
*--p = t3;
*--p = t2;
*--p = t1;
for (i = 0; i < IDEAROUNDS-1; i++) {
t1 = *EK++;
*--p = *EK++;
*--p = t1;
t1 = mulInv(*EK++);
t2 = - ( int ) *EK++;
t3 = - ( int ) *EK++;
*--p = mulInv(*EK++);
*--p = t2;
*--p = t3;
*--p = t1;
}
t1 = *EK++;
*--p = *EK++;
*--p = t1;
t1 = mulInv(*EK++);
t2 = - ( int ) *EK++;
t3 = - ( int ) *EK++;
*--p = mulInv(*EK++);
*--p = t3;
*--p = t2;
*--p = t1;
/* Copy and destroy temp copy */
memcpy(DK, temp, sizeof(temp));
burn(temp);
} /* ideaInvertKey */
/*
* MUL(x,y) computes x = x*y, modulo 0x10001. Requires two temps,
* t16 and t32. x is modified, and must me a side-effect-free lvalue.
* y may be anything, but unlike x, must be strictly 16 bits even if
* low16() is #defined.
* All of these are equivalent - see which is faster on your machine
*/
#ifdef SMALL_CACHE
#define MUL(x,y) (x = mul(low16(x),y))
#else /* !SMALL_CACHE */
#ifdef AVOID_JUMPS
#define MUL(x,y) (x = low16(x-1), t16 = low16((y)-1), \
t32 = (word32)x*t16 + x + t16 + 1, x = low16(t32), \
t16 = t32>>16, x = (x-t16) + (x<t16) )
#else /* !AVOID_JUMPS (default) */
#define MUL(x,y) \
((t16 = (y)) ? \
(x=low16(x)) ? \
t32 = (word32)x*t16, \
x = low16(t32), \
t16 = t32>>16, \
x = (x-t16)+(x<t16) \
: \
(x = 1-t16) \
: \
(x = 1-x))
#endif
#endif
/* IDEA encryption/decryption algorithm */
/* Note that in and out can be the same buffer */
void
#ifdef _DCC
ideaCipher(byte (inbuf[8]), byte (outbuf[8]), word16 *key)
#else
ideaCipher(byte const (inbuf[8]), byte (outbuf[8]), word16 const *key)
#endif
{
register uint16 x1, x2, x3, x4, s2, s3;
word16 *in, *out;
#ifndef SMALL_CACHE
register uint16 t16; /* Temporaries needed by MUL macro */
register word32 t32;
#endif
int r = IDEAROUNDS;
in = (word16 *)inbuf;
x1 = *in++; x2 = *in++;
x3 = *in++; x4 = *in;
#ifndef HIGHFIRST
x1 = (x1>>8) | (x1<<8);
x2 = (x2>>8) | (x2<<8);
x3 = (x3>>8) | (x3<<8);
x4 = (x4>>8) | (x4<<8);
#endif
do {
MUL(x1,*key++);
x2 += *key++;
x3 += *key++;
MUL(x4, *key++);
s3 = x3;
x3 ^= x1;
MUL(x3, *key++);
s2 = x2;
x2 ^= x4;
x2 += x3;
MUL(x2, *key++);
x3 += x2;
x1 ^= x2; x4 ^= x3;
x2 ^= s3; x3 ^= s2;
} while (--r);
MUL(x1, *key++);
x3 += *key++;
x2 += *key++;
MUL(x4, *key);
out = (word16 *)outbuf;
#ifdef HIGHFIRST
*out++ = x1;
*out++ = x3;
*out++ = x2;
*out = x4;
#else /* !HIGHFIRST */
x1 = low16(x1);
x2 = low16(x2);
x3 = low16(x3);
x4 = low16(x4);
*out++ = (x1>>8) | (x1<<8);
*out++ = (x3>>8) | (x3<<8);
*out++ = (x2>>8) | (x2<<8);
*out = (x4>>8) | (x4<<8);
#endif
} /* ideaCipher */
/*-------------------------------------------------------------*/
#ifdef TEST
#include <stdio.h>
#include <time.h>
/*
* This is the number of Kbytes of test data to encrypt.
* It defaults to 1 MByte.
*/
#ifndef BLOCKS
#ifndef KBYTES
#define KBYTES 1024
#endif
#define BLOCKS (64*KBYTES)
#endif
int
main(void)
{ /* Test driver for IDEA cipher */
int i, j, k;
byte userkey[16];
word16 EK[IDEAKEYLEN], DK[IDEAKEYLEN];
byte XX[8], YY[8], ZZ[8];
clock_t start, end;
long l;
/* Make a sample user key for testing... */
for(i=0; i<16; i++)
userkey[i] = i+1;
/* Compute encryption subkeys from user key... */
ideaExpandKey(userkey, EK);
printf("\nEncryption key subblocks: ");
for (j=0; j<IDEAROUNDS+1; j++) {
printf("\nround %d: ", j+1);
if (j < IDEAROUNDS)
for(i=0; i<6; i++)
printf(" %6u", EK[j*6+i]);
else
for(i=0; i<4; i++)
printf(" %6u", EK[j*6+i]);
}
/* Compute decryption subkeys from encryption subkeys... */
ideaInvertKey(EK, DK);
printf("\nDecryption key subblocks: ");
for (j=0; j<IDEAROUNDS+1; j++) {
printf("\nround %d: ", j+1);
if (j < IDEAROUNDS)
for(i=0; i<6; i++)
printf(" %6u", DK[j*6+i]);
else
for(i=0; i<4; i++)
printf(" %6u", DK[j*6+i]);
}
/* Make a sample plaintext pattern for testing... */
for (k=0; k<8; k++)
XX[k] = k;
printf("\n Encrypting %d bytes (%ld blocks)...", BLOCKS*16, BLOCKS);
fflush(stdout);
start = clock();
memcpy(YY, XX, 8);
for (l = 0; l < BLOCKS; l++)
ideaCipher(YY, YY, EK); /* repeated encryption */
memcpy(ZZ, YY, 8);
for (l = 0; l < BLOCKS; l++)
ideaCipher(ZZ, ZZ, DK); /* repeated decryption */
end = clock() - start;
l = end / (CLOCKS_PER_SEC/1000) + 1;
i = l/1000;
j = l%1000;
l = (16 * BLOCKS * (CLOCKS_PER_SEC/1000)) / (end/1000);
printf("%d.%03d seconds = %ld bytes per second\n", i, j, l);
printf("\nX %3u %3u %3u %3u %3u %3u %3u %3u\n",
XX[0], XX[1], XX[2], XX[3], XX[4], XX[5], XX[6], XX[7]);
printf("\nY %3u %3u %3u %3u %3u %3u %3u %3u\n",
YY[0], YY[1], YY[2], YY[3], YY[4], YY[5], YY[6], YY[7]);
printf("\nZ %3u %3u %3u %3u %3u %3u %3u %3u\n",
ZZ[0], ZZ[1], ZZ[2], ZZ[3], ZZ[4], ZZ[5], ZZ[6], ZZ[7]);
/* Now decrypted ZZ should be same as original XX */
for (k=0; k<8; k++)
if (XX[k] != ZZ[k]) {
printf("\n\07Error! Noninvertable encryption.\n");
exit(-1); /* error exit */
}
printf("\nNormal exit.\n");
return 0; /* normal exit */
} /* main */
#endif /* TEST */
/* end of idea.c */
+34
View File
@@ -0,0 +1,34 @@
#ifndef _IDEA_DEFINED
#define _IDEA_DEFINED
/* Defines for the PGP-style types used in IDEA.C */
#define byte unsigned char
#define word16 unsigned short int
#define word32 unsigned long int
/* Macros from PGP */
#define burn(x) memset( x, 0, sizeof( x ) )
/* IDEA algorithm constants */
#define IDEAKEYSIZE 16
#define IDEABLOCKSIZE 8
#define IDEAROUNDS 8
#define IDEAKEYLEN ( 6 * IDEAROUNDS + 4 )
/* Routines used to implement the IDEA encryption */
void ideaExpandKey( byte const *userkey, word16 *EK );
#ifdef _DCC
void ideaInvertKey( word16 *EK, word16 DK[IDEAKEYLEN] );
void ideaCipher( byte (inbuf[8]), byte (outbuf[8]), word16 *key );
#else
void ideaInvertKey( word16 const *EK, word16 DK[IDEAKEYLEN] );
void ideaCipher( byte const (inbuf[8]), byte (outbuf[8]), word16 const *key );
#endif
#endif /* _IDEA_DEFINED */
+173
View File
@@ -0,0 +1,173 @@
;-------------------------------------------------------------------------
; idea68k.a
;
; 68000 Assembler version of idea cipher, direct translation from c code
; from PGP.
;
; Author: Risto Paasivirta, paasivir@jyu.fi.
;
section text,code
xdef _asm_mul,_asm_inv
xdef _asm_cipher_idea
; key schedule block
ROUNDS equ 8
Z0 equ 0
Z1 equ (ROUNDS+1)*2
Z2 equ (ROUNDS+1)*4
Z3 equ (ROUNDS+1)*6
Z4 equ (ROUNDS+1)*8
Z5 equ (ROUNDS+1)*10
ZSIZE equ (ROUNDS+1)*12
KSSIZE equ ZSIZE*2
;-------------------------------------------------------------------------
;
; idmul da,db -- db = da * db mod 65537, d0 = scratch (da may be d0)
;
idmul macro
tst.w \2
bne.b idmul1.\@
moveq #1,\2
sub.w \1,\2
bra.b idmul3.\@
idmul1.\@ tst.w \1
bne.b idmul2.\@
moveq #1,d0
sub.w \2,d0
move.w d0,\2
bra.b idmul3.\@
idmul2.\@ mulu.w \1,\2
move.l \2,d0
swap d0
sub.w d0,\2
bcc.b idmul3.\@
addq.w #1,\2
idmul3.\@
endm
;-------------------------------------------------------------------------
; idea_cip (a0=inblock,a1=outblock,a2=keyshedule) (d0-d7/a3 scratch)
;
;
;
idea_cip movem.w (a0),d1-d4
moveq #0,d7
idea_cip_loop lea 0(a2,d7.w),a3
idmul (a3),d1
idmul Z3(a3),d4
add.w Z1(a3),d2
add.w Z2(a3),d3
move.w d1,d6
eor.w d3,d6
idmul Z4(a3),d6
move.w d4,d5
eor.w d2,d5
add.w d6,d5
idmul Z5(a3),d5
add.w d5,d6
eor.w d5,d1
eor.w d6,d4
eor.w d6,d2
eor.w d5,d3
exg d2,d3
addq.w #2,d7
cmp.w #ROUNDS*2,d7
bcs idea_cip_loop
lea 0(a2,d7.w),a3
idmul (a3),d1
idmul Z3(a3),d4
add.w Z1(a3),d3
add.w Z2(a3),d2
exg d2,d3
movem.w d1-d4,(a1)
rts
;-------------------------------------------------------------------------
; _asm_cipher_idea(word16 *in,word16 *out,word16 *ks)
;
;
;
_asm_cipher_idea
movem.l a2-a3/d2-d7,-(sp)
movem.l 36(sp),a0-a2
bsr idea_cip
movem.l (sp)+,a2-a3/d2-d7
rts
;-------------------------------------------------------------------------
; word16 _asm_mul(word16, word16);
;
;
_asm_mul move.w 6(sp),d1
idmul 10(sp),d1
moveq #0,d0
move.w d1,d0
rts
;-------------------------------------------------------------------------
; d0:16 = inv(d0)
;
_asm_inv move.w 6(sp),d0
inv cmp.w #2,d0 ; inv(0)=0,inv(1)=1
bcs.b 1$
cmp.w #3,d0
bcc.b 2$
move.w #32769,d0 ; inv(2)
1$ rts
2$ movem.l d1-d7,-(sp)
move.l #$10001,d1 ; d1 = n1
moveq #1,d2 ; d2 = b2
moveq #0,d3 ; d3 = b1
inv_loop divu.w d0,d1
move.l d1,d4
swap d4 ; r = d4
tst.w d4
beq.b inv_done
move.w d2,d5
muls.w d1,d5
exg d3,d2
sub.l d5,d2
moveq #0,d1
move.w d0,d1
move.w d4,d0
bra.b inv_loop
inv_done tst.l d2
bpl.b 1$
move.l #$10001,d0
add.l d2,d0
bra.b 2$
1$ move.l d2,d0
2$ movem.l (sp)+,d1-d7
rts
;-------------------------------------------------------------------------
end
+285
View File
@@ -0,0 +1,285 @@
;A while ago I posted a message claiming a speed of 238,000
;bytes/sec for an implementation of IDEA on a 33Mh 486. Below is
;an explanation and some code to show how it works. The basic
;trick should be useful on many (but not all) processors. I
;expect only those familiar with IDEA and its reference
;implementation will be able to follow the discussion. See:
;
;Lai, Xueja and Massey, James L. A Proposal for a New Block
;Encryption Standard, Eurocrypt 90
;
;For those who have been asking for the code, sorry I kept
;putting it off. I wanted to get it out of Turbo Pascal
;ideal-mode, but I never had the time.
;
;Colin Plum wrote IDEA-386 code which is included in PGP
;2.3a and uses the same tricks. I don't know who's is
;faster, but I expect they will be very close. Now
;here's how it's done.
;
;A major bottleneck in software IDEA is the mul() routine, which
;is used 34 times per 64 bit block. The routine performs
;multiplication in the multiplicative group mod 2^16+1. The two
;factors are each in a 16 bit word, and the output is also in a 16
;bit word. Note that 0 is not a member of the multiplicative
;group and 2^16 does not fit in 16 bits. We therefor use the 0
;word to represent 2^16. Now group elements map one to one onto
;all possible 16 bit words, since 2^16+1 is prime.
;
;Here is (essentially) the reference implementation from [Lai].
;
;
;unsigned mul( unsigned a, unsigned b ) {
; long int p ;
; long unsigned q ;
; if( a==0 ) p= 0x00010001 - b ;
; else if( b==0 ) p= 0x00010001 - a ;
; else {
; q= a*b;
; p= (q & 0xffff) - (q>>16)
; if( p<0 ) p= p + 0x00010001 ;
; }
; return (unsigned)(p & 0xffff) ;
;}
;
;
;Note the method of reducing a 32 bit word modulo 2^16-1. We
;subtract the high word from the low word, and add the modulus
;back if the result is less than 0. [Lai] contains a proof that
;this works, and you can convince yourself fairly easily.
;
;To speed up this routine, we note that the tests for a=0 and b=0
;will rarely be false. With the possible exception of the first 2
;of the 34 multiplications, 0 should be no more likely than any of
;the other 65535 numbers. Note that if (and only if) either a or
;b is 0 then q will also be 0, and we can check for this in one
;instruction if our processor sets a zero flag for multiplication
;(as the 68000 does but 80x86 does not).
;
;Fortunately p will also be zero after the subtraction if and only
;if either a or b is 0. Proof: r will be zero when the high order
;word of q equals the low order word, and that happens when q is
;divisible by 00010001 hex. Since 00010001h = 2^16+1 is prime,
;this happens if either a or b is a multiple of 2^16+1, and 0 is
;the only such multiple which will fit in a 16 bit word.
;
;The speed-up strategy is to proceed under the assumption that a
;and b are not 0, check to be sure in one instruction, and
;recompute if the assumption was wrong. Here's some 8086
;assembler code:
;
; mov ax, [a]
; mul [b] ; ax is implied. q is now in DX AX
; sub ax, dx ; mod 2^16+1
; jnz not0 ; Jump if neither op was 0. Usually taken.
;
; mov ax, 1 ; recompute result knowing one op is 0.
; sub ax, [a]
; sub ax, [b]
; jmp out ; Just jump over adding the carry.
;not0:
; adc ax, 0 ; If r<0 add 1, otherwise do nothing.
;out: ; Result is now in ax
;
;
;Note that when r<0 we add 1 instead of 2^16+1 since the 2^16 part
;overflows out of the result. The "adc ax, 0" does all the work
;of checking for a negative result and adding the modulus if
;needed.
;
;The multiplication takes 9 instructions, 4 of which are rarely
;executed. I believe similar tricks are possible on many
;processors. The one drawback to the check-after-multiply tactic
;is that we can't let the multiply overwrite the only copy of an
;operand.
;
;Note that most software implementations of IDEA will run at
;slightly different speeds when 0's come up in the multiply
;routine. The reference implementation is faster on 0, this one
;is faster on non-zero. This may be a problem for some real-time
;stuff, and also suggests an attack based on timing.
;
;Finally, below is an implementation of the complete encryption
;function in 8086 assembler, to replace the cipher_idea() function
;in PGP. It takes the same parameters as the function from PGP,
;and uses the c language calling conventions. I tested it using
;the debug features of the idea.c file in PGP. You will need to
;add segment/assume directives. This version uses no global data
;and should be reentrant.
;
;The handling of zero multipliers is outside the inner loop so
;that a short conditional jump can loop back to the beginning.
;Forward conditional jumps are usually not taken and backward
;jumps are usually taken, which is consistent with 586 branch
;prediction (or so I've heard). Stalls where the output of one
;instruction is needed for the next seem unavoidable.
;
;Last I heard, IDEA was patent pending. My code is up for grabs,
;although I would get a kick out being credited if you use it.
;On the other hand Colin's code is already tested and ready
;to assemble and link with PGP.
;
;--Bryan
;
;____________________CODE STARTS BELOW THIS LINE_________
; Called as: asmcrypt( inbuff, outbuff, zkey ) just like PGP
PROC _asmcrypt
; establish parameter and local space on stack
; follow c language calling conventions
ARG inblock:Word, outblock:Word, zkey:Word
LOCAL sx1:Word,sx4:Word,skk:Word,done8:Word =stacksize
push bp
mov bp, sp
sub sp, stacksize
; push ax ; My compiler assumes these are not saved.
; push bx
; push cx
; push dx
push si
push di
; Put the 16 bit sub-blocks in registers and/or local variables
mov si, [inblock]
mov ax, [si]
mov [sx1], ax ; x1 is in ax and sx1
mov di, [si+2] ; x2 is in di
mov bx, [si+4] ; x3 is in bx
mov dx, [si+6]
mov [sx4], dx ; x4 is in sx4
mov si, [zkey] ; si points to next subkey
mov [done8], si
add [done8], 96 ; we will be finished with 8 rounds
; when si=done8
@@loop: ; 8 rounds of this
add di, [si+2] ; x2+=zkey[2] is in di
add bx, [si+4] ; x3+=zkey[4] is in bx
mul [Word si] ;x1 *= zkey[0]
sub ax, dx
jz @@x1 ; if 0, use special case multiply
adc ax, 0
@@x1out:
mov [sx1], ax ; x1 is in ax and sx1
xor ax, bx ; ax= x1^x3
mul [Word si+8] ; compute kk
sub ax, dx ; if 0, use special case multiply
jz @@kk
adc ax, 0
@@kkout:
mov cx, ax ; kk is in cx
mov ax, [sx4] ; x4 *= zkey[6]
mul [Word si+6]
sub ax, dx
jz @@x4 ; if 0, use special case multiply
adc ax, 0
@@x4out:
mov [sx4], ax ; x4 is in sx4 and ax
xor ax, di ; x4^x2
add ax, cx ; kk+(x2^x4)
mul [Word si+10] ; compute t1
sub ax, dx
jz @@t1 ; if 0, use special case multiply
adc ax, 0
@@t1out: ; t1 is in ax
add cx, ax ; t2 is in cx kk+t1
xor [sx4], cx ; x4 in sx4
xor di, cx ; new x3 in di
xor bx, ax ; new x2 in bx
xchg bx, di ; x2 in di, x3 in bx
xor ax, [sx1] ; x1 in ax
mov [sx1], ax ; and [sx1]
add si, 12 ; point to next subkey
cmp si, [done8]
jne @@loop
jmp @@out8
;------------------------------------------
; Special case multiplications, when one factor is 0
@@x1: mov ax, 1
sub ax, [sx1]
sub ax, [Word si]
jmp @@x1out
@@kk: mov ax, [sx1] ; rebuild overwritten operand
xor ax, bx
neg ax
inc ax
sub ax, [si+8]
jmp @@kkout
@@x4: mov ax, 1
sub ax, [sx4]
sub ax, [Word si+6]
jmp @@x4out
@@t1: mov ax, [sx4] ; rebuild
xor ax, di
add ax, cx
neg ax
inc ax
sub ax, [si+10]
jmp @@t1out
;---------------------------------------------------
; 8 rounds are done, now that extra pseudo-round
@@out8:
push di
mov di, [outblock]
mul [Word si]
sub ax, dx
jnz @@o1n ; jump over special case code
mov ax, 1
sub ax, [sx1]
sub ax, [si]
jmp @@o1out
@@o1n: adc ax, 0
@@o1out: mov [di], ax ; final ciphertext block 1
mov ax, [sx4]
mul [Word si+6]
sub ax, dx
jnz @@o4n ; jump over special case code
mov ax, 1
sub ax, [sx4]
sub ax, [si+6]
jmp @@o4out
@@o4n: adc ax, 0
@@o4out: mov [di+6], ax ; final ciphertext block 4
add bx, [si+2]
mov [di+2], bx ; final ciphertext block 2
pop ax
add ax, [si+4]
mov [di+4], ax ; final ciphertext block 3
; Restore the stack and return
pop di
pop si
; pop dx
; pop cx
; pop bx
; pop ax
mov sp, bp
pop bp
ret
ENDP _asmcrypt
+443
View File
@@ -0,0 +1,443 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "libdes/des.h"
/* The DES block size */
#define DES_BLOCKSIZE 8
/* A structure to hold the two keyscheduled DES keys */
typedef struct {
Key_schedule desKey1; /* The first DES key */
Key_schedule desKey2; /* The second DES key */
} DES3_KEY;
/* The size of the keyscheduled DES and 3DES keys */
#define DES_KEYSIZE sizeof( Key_schedule )
#define DES3_KEYSIZE sizeof( DES3_KEY )
/****************************************************************************
* *
* 3DES Self-test Routines *
* *
****************************************************************************/
/* Are there any 3DES test vectors? Presumably X9F1 will eventually
publish some... */
int des3SelfTest( void )
{
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int des3InitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
/* Get rid of unused parameter warnings in a compiler-independant manner */
if( cryptInfoEx );
/* Allocate memory for the keyscheduled key */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( DES3_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, DES3_KEYSIZE );
cryptInfo->keyLength = DES3_KEYSIZE;
return( CRYPT_OK );
}
int des3Init( CRYPT_INFO *cryptInfo )
{
/* Just pass the call through to the extended setup routine */
return( des3InitEx( cryptInfo, NULL ) );
}
int des3End( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
return( CRYPT_OK );
}
/****************************************************************************
* *
* 3DES En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data in ECB mode */
int des3EncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Encrypt a block of data */
des_3ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
int des3DecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Decrypt a block of data */
des_3ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
des3Key->desKey1, des3Key->desKey2, DES_DECRYPT );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CBC mode */
int des3EncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < DES_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Encrypt a block of data */
des_3ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* Shift ciphertext into IV */
memcpy( cryptInfo->currentIV, buffer, DES_BLOCKSIZE );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
int des3DecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
BYTE temp[ DES_BLOCKSIZE ];
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* Save the ciphertext */
memcpy( temp, buffer, DES_BLOCKSIZE );
/* Decrypt a block of data */
des_3ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
des3Key->desKey1, des3Key->desKey2, DES_DECRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < DES_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, DES_BLOCKSIZE );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
/* Clear the temporary buffer */
memset( temp, 0, DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CFB mode */
int des3EncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_3ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, buffer, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in CFB mode. Note that the transformation can be made
faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
all in one loop */
int des3DecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
BYTE temp[ DES_BLOCKSIZE ];
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
memcpy( temp, buffer, bytesToUse );
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_3ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* Save the ciphertext */
memcpy( temp, buffer, ivCount );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
/* Clear the temporary buffer */
memset( temp, 0, DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in OFB mode */
int des3EncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_3ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in OFB mode */
int des3DecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_3ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
des3Key->desKey1, des3Key->desKey2, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
/****************************************************************************
* *
* 3DES Key Management Routines *
* *
****************************************************************************/
/* Key schedule two DES keys */
int des3InitKey( CRYPT_INFO *cryptInfo )
{
DES3_KEY *des3Key = ( DES3_KEY * ) cryptInfo->key;
/* Call the libdes key schedule code. Returns with -1 if the key parity
is wrong, -2 if a weak key is used */
if( key_sched( ( C_Block * ) cryptInfo->userKey, des3Key->desKey1 ) )
return( CRYPT_BADPARM );
if( key_sched( ( C_Block * ) ( cryptInfo->userKey + bitsToBytes( 56 ) ),
des3Key->desKey2 ) )
return( CRYPT_BADPARM );
return( CRYPT_OK );
}
+486
View File
@@ -0,0 +1,486 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "libdes/des.h"
/* The DES key and block size */
#define DES_KEYSIZE 7
#define DES_BLOCKSIZE 8
/* The size of the keyscheduled DES key */
#define DES_EXPANDED_KEYSIZE sizeof( Key_schedule )
/****************************************************************************
* *
* DES Self-test Routines *
* *
****************************************************************************/
#include "testdes.h"
/* Test the DES implementation against the test vectors given in NBS Special
Publication 500-20, 1980. We need to perform the tests at a very low
level since the encryption library hasn't been intialized yet */
static int desTestLoop( DES_TEST *testData, int iterations, int operation )
{
BYTE temp[ DES_BLOCKSIZE ];
BYTE key[ DES_EXPANDED_KEYSIZE ];
int i;
for( i = 0; i < iterations; i++ )
{
memcpy( temp, testData[ i ].plaintext, DES_BLOCKSIZE );
key_sched( ( C_Block * ) testData[ i ].key,
*( ( Key_schedule * ) key ) );
des_ecb_encrypt( ( C_Block * ) temp, ( C_Block * ) temp,
*( ( Key_schedule * ) key ), operation );
if( memcmp( testData[ i ].ciphertext, temp, DES_BLOCKSIZE ) )
return( CRYPT_ERROR );
}
return( CRYPT_OK );
}
int desSelfTest( void )
{
/* Check the DES test vectors */
if( ( desTestLoop( testIP, sizeof( testIP ) / sizeof( DES_TEST ),
DES_ENCRYPT ) != CRYPT_OK ) || \
( desTestLoop( testVP, sizeof( testVP ) / sizeof( DES_TEST ),
DES_ENCRYPT ) != CRYPT_OK ) || \
( desTestLoop( testKP, sizeof( testKP ) / sizeof( DES_TEST ),
DES_ENCRYPT ) != CRYPT_OK ) || \
( desTestLoop( testRS, sizeof( testRS ) / sizeof( DES_TEST ),
DES_DECRYPT ) != CRYPT_OK ) || \
( desTestLoop( testDP, sizeof( testDP ) / sizeof( DES_TEST ),
DES_ENCRYPT ) != CRYPT_OK ) || \
( desTestLoop( testSB, sizeof( testSB ) / sizeof( DES_TEST ),
DES_ENCRYPT ) != CRYPT_OK ) )
return( CRYPT_SELFTEST );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int desInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
/* Get rid of unused parameter warnings in a compiler-independant manner */
if( cryptInfoEx );
/* Allocate memory for the keyscheduled key */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( DES_EXPANDED_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, DES_EXPANDED_KEYSIZE );
cryptInfo->keyLength = DES_EXPANDED_KEYSIZE;
return( CRYPT_OK );
}
int desInit( CRYPT_INFO *cryptInfo )
{
/* Just pass the call through to the extended setup routine */
return( desInitEx( cryptInfo, NULL ) );
}
int desEnd( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
return( CRYPT_OK );
}
/****************************************************************************
* *
* DES En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data in ECB mode */
int desEncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Encrypt a block of data */
des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
cryptInfo->key, DES_ENCRYPT );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
int desDecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Decrypt a block of data */
des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
cryptInfo->key, DES_DECRYPT );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CBC mode */
int desEncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < DES_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Encrypt a block of data */
des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
cryptInfo->key, DES_ENCRYPT );
/* Shift ciphertext into IV */
memcpy( cryptInfo->currentIV, buffer, DES_BLOCKSIZE );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
return( CRYPT_OK );
}
int desDecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
BYTE temp[ DES_BLOCKSIZE ];
int blockCount = noBytes / DES_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* Save the ciphertext */
memcpy( temp, buffer, DES_BLOCKSIZE );
/* Decrypt a block of data */
des_ecb_encrypt( ( C_Block * ) buffer, ( C_Block * ) buffer,
cryptInfo->key, DES_DECRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < DES_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, DES_BLOCKSIZE );
/* Move on to next block of data */
buffer += DES_BLOCKSIZE;
}
/* Clear the temporary buffer */
memset( temp, 0, DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CFB mode */
int desEncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
cryptInfo->key, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, buffer, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
int desDecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
BYTE temp[ DES_BLOCKSIZE ];
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
memcpy( temp, buffer, bytesToUse );
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
cryptInfo->key, DES_ENCRYPT );
/* Save the ciphertext */
memcpy( temp, buffer, ivCount );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
/* Clear the temporary buffer */
memset( temp, 0, DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in OFB mode */
int desEncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
cryptInfo->key, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
int desDecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = DES_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > DES_BLOCKSIZE ) ? DES_BLOCKSIZE : noBytes;
/* Encrypt the IV */
des_ecb_encrypt( ( C_Block * ) cryptInfo->currentIV,
( C_Block * ) cryptInfo->currentIV,
cryptInfo->key, DES_ENCRYPT );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % DES_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in PCBC mode */
int desEncryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
/* Encrypt the entire buffer */
des_pcbc_encrypt( ( C_Block *) buffer, ( C_Block * ) buffer,
( long ) noBytes, cryptInfo->key,
( C_Block * ) cryptInfo->currentIV, DES_ENCRYPT );
return( CRYPT_OK );
}
int desDecryptPCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
/* Make sure the data length is a multiple of the block size */
if( noBytes % DES_BLOCKSIZE )
return( CRYPT_BADPARM3 );
/* Decrypt the entire buffer */
des_pcbc_encrypt( ( C_Block *) buffer, ( C_Block * ) buffer,
( long ) noBytes, cryptInfo->key,
( C_Block * ) cryptInfo->currentIV, DES_DECRYPT );
return( CRYPT_OK );
}
/****************************************************************************
* *
* DES Key Management Routines *
* *
****************************************************************************/
/* Key schedule a DES key */
int desInitKey( CRYPT_INFO *cryptInfo )
{
/* Call the libdes key schedule code. Returns with -1 if the key parity
is wrong, -2 if a weak key is used */
if( key_sched( ( C_Block * ) cryptInfo->userKey,
*( ( Key_schedule * ) cryptInfo->key ) ) )
return( CRYPT_BADPARM );
return( CRYPT_OK );
}
+442
View File
@@ -0,0 +1,442 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "idea/idea.h"
/* The IDEA key and block size */
#define IDEA_KEYSIZE IDEAKEYSIZE
#define IDEA_BLOCKSIZE IDEABLOCKSIZE
/* A structure to hold the two expanded IDEA keys */
typedef struct {
WORD eKey[ IDEAKEYLEN ]; /* The encryption key */
WORD dKey[ IDEAKEYLEN ]; /* The decryption key */
} IDEA_KEY;
/* The size of the expanded IDEA keys */
#define IDEA_EXPANDED_KEYSIZE sizeof( IDEA_KEY )
/****************************************************************************
* *
* IDEA Self-test Routines *
* *
****************************************************************************/
#include "testidea.h"
/* Test the IDEA code against the test vectors from the ETH reference
implementation */
int ideaSelfTest( void )
{
BYTE temp[ IDEA_BLOCKSIZE ];
WORD key[ IDEAKEYLEN ];
int i;
for( i = 0; i < sizeof( testIdea ) / sizeof( IDEA_TEST ); i++ )
{
memcpy( temp, testIdea[ i ].plaintext, IDEA_BLOCKSIZE );
ideaExpandKey( testIdea[ i ].key, key );
ideaCipher( temp, temp, key );
if( memcmp( testIdea[ i ].ciphertext, temp, IDEA_BLOCKSIZE ) )
return( CRYPT_ERROR );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int ideaInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
/* Get rid of unused parameter warnings in a compiler-independant manner */
if( cryptInfoEx );
/* Allocate memory for the keyscheduled key */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( IDEA_EXPANDED_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, IDEA_EXPANDED_KEYSIZE );
cryptInfo->keyLength = IDEA_EXPANDED_KEYSIZE;
return( CRYPT_OK );
}
int ideaInit( CRYPT_INFO *cryptInfo )
{
/* Just pass the call through to the extended setup routine */
return( ideaInitEx( cryptInfo, NULL ) );
}
int ideaEnd( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
return( CRYPT_OK );
}
/****************************************************************************
* *
* IDEA En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data in ECB mode */
int ideaEncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int blockCount = noBytes / IDEA_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % IDEA_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Encrypt a block of data */
ideaCipher( buffer, buffer, ideaKey->eKey );
/* Move on to next block of data */
buffer += IDEA_BLOCKSIZE;
}
return( CRYPT_OK );
}
int ideaDecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int blockCount = noBytes / IDEA_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % IDEA_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Decrypt a block of data */
ideaCipher( buffer, buffer, ideaKey->dKey );
/* Move on to next block of data */
buffer += IDEA_BLOCKSIZE;
}
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CBC mode */
int ideaEncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int blockCount = noBytes / IDEA_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % IDEA_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < IDEA_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Encrypt a block of data */
ideaCipher( buffer, buffer, ideaKey->eKey );
/* Shift ciphertext into IV */
memcpy( cryptInfo->currentIV, buffer, IDEA_BLOCKSIZE );
/* Move on to next block of data */
buffer += IDEA_BLOCKSIZE;
}
return( CRYPT_OK );
}
int ideaDecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
BYTE temp[ IDEA_BLOCKSIZE ];
int blockCount = noBytes / IDEA_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % IDEA_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* Save the ciphertext */
memcpy( temp, buffer, IDEA_BLOCKSIZE );
/* Decrypt a block of data */
ideaCipher( buffer, buffer, ideaKey->dKey );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < IDEA_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, IDEA_BLOCKSIZE );
/* Move on to next block of data */
buffer += IDEA_BLOCKSIZE;
}
/* Clear the temporary buffer */
memset( temp, 0, IDEA_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CFB mode */
int ideaEncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = IDEA_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > IDEA_BLOCKSIZE ) ? IDEA_BLOCKSIZE : noBytes;
/* Encrypt the IV */
ideaCipher( cryptInfo->currentIV, cryptInfo->currentIV, ideaKey->eKey );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, buffer, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % IDEA_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in CFB mode. Note that the transformation can be made
faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
all in one loop */
int ideaDecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
BYTE temp[ IDEA_BLOCKSIZE ];
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = IDEA_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
memcpy( temp, buffer, bytesToUse );
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > IDEA_BLOCKSIZE ) ? IDEA_BLOCKSIZE : noBytes;
/* Encrypt the IV */
ideaCipher( cryptInfo->currentIV, cryptInfo->currentIV, ideaKey->eKey );
/* Save the ciphertext */
memcpy( temp, buffer, ivCount );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % IDEA_BLOCKSIZE );
/* Clear the temporary buffer */
memset( temp, 0, IDEA_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in OFB mode */
int ideaEncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = IDEA_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > IDEA_BLOCKSIZE ) ? IDEA_BLOCKSIZE : noBytes;
/* Encrypt the IV */
ideaCipher( cryptInfo->currentIV, cryptInfo->currentIV, ideaKey->eKey );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % IDEA_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in OFB mode */
int ideaDecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = IDEA_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > IDEA_BLOCKSIZE ) ? IDEA_BLOCKSIZE : noBytes;
/* Encrypt the IV */
ideaCipher( cryptInfo->currentIV, cryptInfo->currentIV, ideaKey->eKey );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % IDEA_BLOCKSIZE );
return( CRYPT_OK );
}
/****************************************************************************
* *
* IDEA Key Management Routines *
* *
****************************************************************************/
/* Key schedule an IDEA key */
int ideaInitKey( CRYPT_INFO *cryptInfo )
{
IDEA_KEY *ideaKey = ( IDEA_KEY * ) cryptInfo->key;
/* Generate an expanded IDEA key and its inverse */
ideaExpandKey( cryptInfo->userKey, ideaKey->eKey );
ideaInvertKey( ideaKey->eKey, ideaKey->dKey );
return( CRYPT_OK );
}
+460
View File
@@ -0,0 +1,460 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "mdc/shs.h"
/* The default key setup iteration count. This gives roughly 0.5s delay on
a 10K dhrystone machine */
#define MDCSHS_DEFAULT_ITERATIONS 200
/* The size of an MDCSHS key. If we're running on a machine with a > 32
bit wordsize, we need to store the key as an array of words rather than
an array of bytes which is cast to an array of words */
#ifdef _BIG_WORDS
#define MDCSHS_KEY_WORDS ( SHS_DATASIZE / 4 )
#define MDCSHS_KEYSIZE ( MDCSHS_KEY_WORDS * sizeof( LONG ) )
#else
#define MDCSHS_KEYSIZE SHS_DATASIZE
#endif /* _BIG_WORDS */
/* If we're running on a machine with > 32 bit wordsize we need to jump
through all sorts of hoops to convert data from arrays of bytes to arrays
of longints. The following macros pull bytes out of memory and assemble
them into a longword, and deposit a longword into memory as a series of
bytes. This code really blows on any processors which need to use it */
#ifdef _BIG_WORDS
#ifdef BIG_ENDIAN
#define mgetLong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] << 24 ) | ( ( LONG ) memPtr[ 1 ] << 16 ) | \
( ( LONG ) memPtr[ 2 ] << 8 ) | ( ( LONG ) memPtr[ 3 ] ) ); \
memPtr += 4
#define mputLong(memPtr,data) \
memPtr[ 0 ] = ( ( data ) >> 24 ) & 0xFF; \
memPtr[ 1 ] = ( ( data ) >> 16 ) & 0xFF; \
memPtr[ 2 ] = ( ( data ) >> 8 ) & 0xFF; \
memPtr[ 3 ] = ( data ) & 0xFF; \
memPtr += 4
#else
#define mgetLong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] ) | ( ( LONG ) memPtr[ 1 ] << 8 ) | \
( ( LONG ) memPtr[ 2 ] << 16 ) | ( ( LONG ) memPtr[ 3 ] << 24 ) ); \
memPtr += 4
#define mputLong(memPtr,data) \
memPtr[ 0 ] = ( data ) & 0xFF; \
memPtr[ 1 ] = ( ( data ) >> 8 ) & 0xFF; \
memPtr[ 2 ] = ( ( data ) >> 16 ) & 0xFF; \
memPtr[ 3 ] = ( ( data ) >> 24 ) & 0xFF; \
memPtr += 4
#endif /* BIG_ENDIAN */
/* Versions of the above which are guaranteed to always be big-endian */
#define mgetELong(memPtr) \
( ( ( LONG ) memPtr[ 0 ] << 24 ) | ( ( LONG ) memPtr[ 1 ] << 16 ) | \
( ( LONG ) memPtr[ 2 ] << 8 ) | ( LONG ) memPtr[ 3 ] ); \
memPtr += 4
#define mputELong(memPtr,data) \
memPtr[ 0 ] = ( ( data ) >> 24 ) & 0xFF; \
memPtr[ 1 ] = ( ( data ) >> 16 ) & 0xFF; \
memPtr[ 2 ] = ( ( data ) >> 8 ) & 0xFF; \
memPtr[ 3 ] = ( data ) & 0xFF; \
memPtr += 4
#endif /* _BIG_WORDS */
/* Copy an array of bytes to an array of 32-bit words. We need to take
special precautions when the machine word size is > 32 bits because we
can't just assume BYTE[] == LONG[] */
#ifdef _BIG_WORDS
#define copyToLong(dest,src,count) \
{ \
LONG *destPtr = ( LONG * ) dest; \
BYTE *srcPtr = src; \
int i; \
for( i = 0; i < count / 4; i++ ) \
{ \
destPtr[ i ] = mgetLong( srcPtr ); \
} \
}
#else
#define copyToLong(dest,src,count) \
memcpy( dest, src, count )
#endif /* _BIG_WORDS */
/****************************************************************************
* *
* MDC/SHS Self-test Routines *
* *
****************************************************************************/
/* Test the SHA output against the test vectors given in FIPS 180 */
static LONG shsTestResults[][ 5 ] = {
{ 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L },
{ 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L },
{ 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L }
};
static int compareSHSresults( SHS_INFO *shsInfo, int shsTestLevel )
{
int i;
/* Compare the returned digest and required values */
for( i = 0; i < 5; i++ )
if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] )
return( CRYPT_SELFTEST );
return( CRYPT_OK );
}
int mdcshsSelfTest( void )
{
SHS_INFO shsInfo;
/* Test SHA against values given in FIPS 180 */
shsInit( &shsInfo );
shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 0 ) != CRYPT_OK )
return( CRYPT_SELFTEST );
shsInit( &shsInfo );
shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 1 ) != CRYPT_OK )
return( CRYPT_SELFTEST );
#if 0
/* We skip the third test since this takes several seconds to execute,
which leads to an unacceptable delay in the library startup time */
shsInit( &shsInfo );
for( i = 0; i < 15625; i++ )
shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 2 ) != CRYPT_OK )
return( CRYPT_SELFTEST );
#endif /* 0 */
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int mdcshsInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
CRYPT_INFO_MDCSHS *cryptInfoExPtr = ( CRYPT_INFO_MDCSHS * ) cryptInfoEx;
/* Allocate memory for the key and the algorithm-specific data within
the crypt context and set up any pointers we need */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( MDCSHS_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, MDCSHS_KEYSIZE );
if( ( cryptInfo->privateData = malloc( sizeof( CRYPT_INFO_MDCSHS ) ) ) == NULL )
{
free( cryptInfo->key );
cryptInfo->key = NULL;
return( CRYPT_NOMEM );
}
if( cryptInfoExPtr->keySetupIterations == CRYPT_USE_DEFAULT )
cryptInfoExPtr->keySetupIterations = MDCSHS_DEFAULT_ITERATIONS;
memcpy( cryptInfo->privateData, cryptInfoEx, sizeof( CRYPT_INFO_MDCSHS ) );
cryptInfo->keyLength = MDCSHS_KEYSIZE;
return( CRYPT_OK );
}
int mdcshsInit( CRYPT_INFO *cryptInfo )
{
CRYPT_INFO_MDCSHS cryptInfoEx;
/* Use the default number of setup iterations */
memset( &cryptInfoEx, 0, sizeof( CRYPT_INFO_MDCSHS ) );
cryptInfoEx.keySetupIterations = CRYPT_USE_DEFAULT;
/* Pass through to the extended setup routine */
return( mdcshsInitEx( cryptInfo, &cryptInfoEx ) );
}
int mdcshsEnd( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
secureFree( &cryptInfo->privateData, sizeof( CRYPT_INFO_MDCSHS ) );
return( CRYPT_OK );
}
/****************************************************************************
* *
* MDC/SHS En/Decryption Routines *
* *
****************************************************************************/
/* The SHS transformation. What we're doing here isn't totally correct since
we're forcing the IV to big-endian, transforming it, and returning it to
the local endianness, rather than changing the data to the local
endianness and back as we should. However doing it correctly isn't really
possible since we can only endianness-swap 4 bytes at a time which
precludes swapping the data. The use of the temp variable when the IV is
copied back in the _BIG_WORDS case is to eliminate multiple memory
accesses when the four bytes are extracted from ivLong[ n ], since many
compilers won't risk optimising the loads due to possible aliasing
problems. We declare the necessary ivLong array as part of the actual
encryption function to save it having to be instantiated for every use
of shsTransform() */
#ifdef _BIG_WORDS
#define shsTransform(cI) { \
LONG temp; \
BYTE *ivPtr; \
ivPtr = ( BYTE * ) cI->currentIV; \
for( i = 0; i < 5; i++ ) \
{ \
ivLong[ i ] = mgetELong( ivPtr ); \
} \
SHSTransform( ivLong, cI->key ); \
ivPtr = ( BYTE * ) cI->currentIV; \
for( i = 0; i < 5; i++ ) \
{ \
temp = ivLong[ i ]; \
mputELong( ivPtr, temp ); \
} \
}
#else
#define shsTransform(cI) longReverse( ( LONG * ) cI->currentIV, SHS_DIGESTSIZE ); \
SHSTransform( ( LONG * ) cI->currentIV, ( LONG * ) cI->key ); \
longReverse( ( LONG * ) cI->currentIV, SHS_DIGESTSIZE );
#endif /* _BIG_WORDS */
void SHSTransform( LONG *digest, LONG *data );
/* Encrypt data in CFB mode */
int mdcshsEncrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
int i, ivCount = cryptInfo->ivCount;
#ifdef _BIG_WORDS
LONG ivLong[ 5 ];
#endif /* _BIG_WORDS */
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SHS_DIGESTSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SHS_DIGESTSIZE ) ? SHS_DIGESTSIZE : noBytes;
/* Encrypt the IV */
shsTransform( cryptInfo );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, buffer, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SHS_DIGESTSIZE );
return( CRYPT_OK );
}
/* Decrypt data in CFB mode. Note that the transformation can be made
faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
all in one loop */
int mdcshsDecrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
BYTE temp[ SHS_DIGESTSIZE ];
int i, ivCount = cryptInfo->ivCount;
#ifdef _BIG_WORDS
LONG ivLong[ 5 ];
#endif /* _BIG_WORDS */
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SHS_DIGESTSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
memcpy( temp, buffer, bytesToUse );
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SHS_DIGESTSIZE ) ? SHS_DIGESTSIZE : noBytes;
/* Encrypt the IV */
shsTransform( cryptInfo );
/* Save the ciphertext */
memcpy( temp, buffer, ivCount );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SHS_DIGESTSIZE );
/* Clear the temporary buffer */
memset( temp, 0, SHS_DIGESTSIZE );
return( CRYPT_OK );
}
/****************************************************************************
* *
* MDC/SHS Key Management Routines *
* *
****************************************************************************/
/* The size of the key buffer. Note that increasing this value will result
in a significant increase in the setup time, so it will be necessary to
make a corresponding decrease in the iteration count */
#define KEYBUFFER_SIZE 256
/* Initialise an MDC/SHS key. This is done by repeatedly encrypting the
user key as follows:
IV <- 0
key <- 0
repeat
encrypt userkey with key
key <- userkey
The IV is updated transparently as part of the encryption process */
int mdcshsInitKey( CRYPT_INFO *cryptInfo )
{
BYTE keyData[ KEYBUFFER_SIZE ];
int keySetupIterations = ( ( CRYPT_INFO_MDCSHS * ) cryptInfo->privateData )->keySetupIterations;
int count;
/* Copy the key information into the key data buffer. We silently
truncate the key length to the size of the buffer, but this usually
is some hundreds of bytes so it shouldn't be a problem.
We also correct the endianness of the keyData at this point. From
here on all data is in the local endianness format so there is no need
for further corrections */
memset( keyData, 0, KEYBUFFER_SIZE );
keyData[ 0 ] = ( BYTE ) ( cryptInfo->userKeyLength >> 8 );
keyData[ 1 ] = ( BYTE ) cryptInfo->userKeyLength;
cryptInfo->userKeyLength %= KEYBUFFER_SIZE - 2;
memcpy( keyData + 2, cryptInfo->userKey, cryptInfo->userKeyLength );
/* Set the initial key and IV to null */
memset( cryptInfo->currentIV, 0, CRYPT_MAX_IVSIZE );
memset( cryptInfo->key, 0, MDCSHS_KEYSIZE );
/* Convert the endianness of the input data from the canonical form to
the local form */
longReverse( ( LONG * ) keyData, KEYBUFFER_SIZE );
/* "Encrypt" the keyData with the given IV and then set the key to
the encrypted keyData. The act of encryption also sets the IV.
This is particularly important in the case of SHS, since although only
the first SHS_DATASIZE bytes are copied into the key, the IV is
still affected by the entire buffer */
for( count = 0; count < keySetupIterations; count++ )
{
mdcshsEncrypt( cryptInfo, keyData, KEYBUFFER_SIZE );
copyToLong( cryptInfo->key, keyData, SHS_DATASIZE );
}
/* Perform one last copy in case they've specified zero iterations and
the loop was never executed. For MDCSHS, the transformed key is the
same as the raw encryption key, so we just copy it over */
copyToLong( cryptInfo->key, keyData, SHS_DATASIZE );
#if 0
/* Set the key check byte to the last WORD of the encrypted keyData.
This is never used for anything (it's 191 bytes past the end of the
last value used to set the key) so we're not revealing much to an
attacker */
longReverse( ( LONG * ) ( keyData + KEYBUFFER_SIZE - sizeof( LONG ) ), sizeof( LONG ) );
cryptInfo->keyCheck = ( ( WORD ) keyData[ KEYBUFFER_SIZE - 2 ] << 8 ) | \
keyData[ KEYBUFFER_SIZE - 1 ];
#endif /* 0 */
/* Finally, create a copy of the transformed key in the canonical form
in case the user wants to access it */
memcpy( cryptInfo->transUserKey, keyData, MDCSHS_KEYSIZE );
longReverse( ( LONG * ) cryptInfo->transUserKey, SHS_DATASIZE );
/* Wipe the keyData */
memset( keyData, 0, KEYBUFFER_SIZE );
return( CRYPT_OK );
}
/* Initialise the IV */
int mdcshsInitIV( CRYPT_INFO *cryptInfo )
{
/* Convert the working IV from the canonical to the internal form */
longReverse( ( LONG * ) cryptInfo->currentIV, CRYPT_MAX_IVSIZE );
return( CRYPT_OK );
}
+68
View File
@@ -0,0 +1,68 @@
#include "crypt.h"
/****************************************************************************
* *
* Null En/Decryption Routines *
* *
****************************************************************************/
int nullSelfTest( void )
{
return( CRYPT_OK );
}
int nullInit( CRYPT_INFO *cryptInfo )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo );
return( CRYPT_OK );
}
int nullInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfoEx );
return( nullInit( cryptInfo ) );
}
int nullEnd( CRYPT_INFO *cryptInfo )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo );
return( CRYPT_OK );
}
int nullInitKey( CRYPT_INFO *cryptInfo )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo );
return( CRYPT_OK );
}
int nullInitIV( CRYPT_INFO *cryptInfo )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo );
return( CRYPT_OK );
}
int nullEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo || buffer || length );
return( CRYPT_OK );
}
int nullDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length )
{
/* Get rid of unused parameter warning in a compiler-independant manner */
if( cryptInfo || buffer || length );
return( CRYPT_OK );
}
+134
View File
@@ -0,0 +1,134 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "rc4/rc4.h"
/* The size of the expanded IDEA keys */
#define RC4_EXPANDED_KEYSIZE sizeof( RC4KEY )
/****************************************************************************
* *
* RC4 Self-test Routines *
* *
****************************************************************************/
#include "testrc4.h"
/* Test the RC4 code against the test vectors from the BSAFE2 implementation */
static int rc4Test( BYTE *key, int keySize,
BYTE *plaintext, BYTE *ciphertext, int length )
{
BYTE temp[ 512 ];
RC4KEY rc4key;
memcpy( temp, plaintext, length );
rc4ExpandKey( &rc4key, key, keySize );
rc4Crypt( &rc4key, temp, length );
if( memcmp( ciphertext, temp, length ) )
return( CRYPT_ERROR );
return( CRYPT_OK );
}
int rc4SelfTest( void )
{
/* The testing gets somewhat messy here because of the variable-length
arrays, which isn't normally a problem with the fixed-length keys
and data used in the block ciphers */
if( rc4Test( testRC4key1, sizeof( testRC4key1 ), testRC4plaintext1,
testRC4ciphertext1, sizeof( testRC4plaintext1 ) ) != CRYPT_OK ||
rc4Test( testRC4key2, sizeof( testRC4key2 ), testRC4plaintext2,
testRC4ciphertext2, sizeof( testRC4plaintext2 ) ) != CRYPT_OK ||
rc4Test( testRC4key3, sizeof( testRC4key3 ), testRC4plaintext3,
testRC4ciphertext3, sizeof( testRC4plaintext3 ) ) != CRYPT_OK ||
rc4Test( testRC4key4, sizeof( testRC4key4 ), testRC4plaintext4,
testRC4ciphertext4, sizeof( testRC4plaintext4 ) ) != CRYPT_OK ||
rc4Test( testRC4key5, sizeof( testRC4key5 ), testRC4plaintext5,
testRC4ciphertext5, sizeof( testRC4plaintext5 ) ) != CRYPT_OK )
return( CRYPT_ERROR );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int rc4InitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
/* Get rid of unused parameter warnings in a compiler-independant manner */
if( cryptInfoEx );
/* Allocate memory for the expanded key */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( RC4_EXPANDED_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, RC4_EXPANDED_KEYSIZE );
cryptInfo->keyLength = RC4_EXPANDED_KEYSIZE;
return( CRYPT_OK );
}
int rc4Init( CRYPT_INFO *cryptInfo )
{
/* Just pass the call through to the extended setup routine */
return( rc4InitEx( cryptInfo, NULL ) );
}
int rc4End( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
return( CRYPT_OK );
}
/****************************************************************************
* *
* RC4 En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data. Since RC4 is a stream cipher, encryption and
decryption are one and the same */
int rc4Encrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
rc4Crypt( ( RC4KEY * ) cryptInfo->key, buffer, noBytes );
return( CRYPT_OK );
}
int rc4Decrypt( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
rc4Crypt( ( RC4KEY * ) cryptInfo->key, buffer, noBytes );
return( CRYPT_OK );
}
/****************************************************************************
* *
* RC4 Key Management Routines *
* *
****************************************************************************/
/* Create an expanded RC4 key */
int rc4InitKey( CRYPT_INFO *cryptInfo )
{
rc4ExpandKey( ( RC4KEY * ) cryptInfo->key, cryptInfo->userKey,
cryptInfo->userKeyLength );
return( CRYPT_OK );
}
+489
View File
@@ -0,0 +1,489 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "crypt.h"
#include "safer/safer.h"
/* The SAFER key and block size */
#define SAFER_KEYSIZE SAFER_KEY_LEN
#define SAFER_BLOCKSIZE SAFER_BLOCK_LEN
#define SAFER_KEY safer_key_t
/* The size of the expanded SAFER keys */
#define SAFER_EXPANDED_KEYSIZE sizeof( SAFER_KEY )
/****************************************************************************
* *
* SAFER Self-test Routines *
* *
****************************************************************************/
#include "testsafr.h"
/* Test the SAFER-SK code against the test vectors from the ETH reference
implementation */
int saferSelfTest( void )
{
BYTE temp[ SAFER_BLOCKSIZE ];
SAFER_KEY key;
int i;
Safer_Init_Module();
for( i = 0; i < sizeof( testSafer ) / sizeof( SAFER_TEST ); i++ )
{
memcpy( temp, testSafer[ i ].plaintext, SAFER_BLOCKSIZE );
if( testSafer[ i ].rounds == SAFER_K64_DEFAULT_NOF_ROUNDS )
Safer_Expand_Userkey( testSafer[ i ].key, \
testSafer[ i ].key, \
testSafer[ i ].rounds, TRUE, key );
else
Safer_Expand_Userkey( testSafer[ i ].key, \
testSafer[ i ].key + bitsToBytes( 64 ), \
testSafer[ i ].rounds, TRUE, key );
Safer_Encrypt_Block( temp, key, temp );
if( memcmp( testSafer[ i ].ciphertext, temp, SAFER_BLOCKSIZE ) )
return( CRYPT_ERROR );
}
return( CRYPT_OK );
}
/****************************************************************************
* *
* Init/Shutdown Routines *
* *
****************************************************************************/
/* Perform auxiliary init and shutdown actions on an encryption context */
int saferInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx )
{
CRYPT_INFO_SAFER *cryptInfoExPtr = ( CRYPT_INFO_SAFER * ) cryptInfoEx;
/* Allocate memory for the key and the algorithm-specific data within
the crypt context and set up any pointers we need. We don't process
cryptInfoExPtr->rounds at this point since we set things up when we
perform the saferInitKey() function, as the number of rounds is key-
dependant */
if( cryptInfo->key != NULL || cryptInfo->privateData != NULL )
return( CRYPT_INITED );
if( ( cryptInfo->key = malloc( SAFER_EXPANDED_KEYSIZE ) ) == NULL )
return( CRYPT_NOMEM );
memset( cryptInfo->key, 0, SAFER_EXPANDED_KEYSIZE );
if( ( cryptInfo->privateData = malloc( sizeof( CRYPT_INFO_SAFER ) ) ) == NULL )
{
free( cryptInfo->key );
cryptInfo->key = NULL;
return( CRYPT_NOMEM );
}
if( cryptInfoExPtr->useSaferSK == CRYPT_USE_DEFAULT )
cryptInfoExPtr->useSaferSK = FALSE;
memcpy( cryptInfo->privateData, cryptInfoEx, sizeof( CRYPT_INFO_SAFER ) );
cryptInfo->keyLength = SAFER_EXPANDED_KEYSIZE;
/* Set up the SAFER data tables if necessary */
Safer_Init_Module();
return( CRYPT_OK );
}
int saferInit( CRYPT_INFO *cryptInfo )
{
CRYPT_INFO_SAFER cryptInfoEx;
/* Use the default number of rounds and the non-enhanced SAFER */
memset( &cryptInfoEx, 0, sizeof( CRYPT_INFO_MDCSHS ) );
cryptInfoEx.rounds = CRYPT_USE_DEFAULT;
cryptInfoEx.useSaferSK = CRYPT_USE_DEFAULT;
/* Pass through to the extended setup routine */
return( saferInitEx( cryptInfo, &cryptInfoEx ) );
}
int saferEnd( CRYPT_INFO *cryptInfo )
{
/* Free any allocated memory */
secureFree( &cryptInfo->key, cryptInfo->keyLength );
secureFree( &cryptInfo->privateData, sizeof( CRYPT_INFO_SAFER ) );
return( CRYPT_OK );
}
/****************************************************************************
* *
* SAFER En/Decryption Routines *
* *
****************************************************************************/
/* Encrypt/decrypt data in ECB mode */
int saferEncryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int blockCount = noBytes / SAFER_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % SAFER_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Encrypt a block of data */
Safer_Encrypt_Block( buffer, *saferKey, buffer );
/* Move on to next block of data */
buffer += SAFER_BLOCKSIZE;
}
return( CRYPT_OK );
}
int saferDecryptECB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int blockCount = noBytes / SAFER_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % SAFER_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
/* Decrypt a block of data */
Safer_Decrypt_Block( buffer, *saferKey, buffer );
/* Move on to next block of data */
buffer += SAFER_BLOCKSIZE;
}
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CBC mode */
int saferEncryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int blockCount = noBytes / SAFER_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % SAFER_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < SAFER_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Encrypt a block of data */
Safer_Encrypt_Block( buffer, *saferKey, buffer );
/* Shift ciphertext into IV */
memcpy( cryptInfo->currentIV, buffer, SAFER_BLOCKSIZE );
/* Move on to next block of data */
buffer += SAFER_BLOCKSIZE;
}
return( CRYPT_OK );
}
int saferDecryptCBC( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
BYTE temp[ SAFER_BLOCKSIZE ];
int blockCount = noBytes / SAFER_BLOCKSIZE;
/* Make sure the data length is a multiple of the block size */
if( noBytes % SAFER_BLOCKSIZE )
return( CRYPT_BADPARM3 );
while( blockCount-- )
{
int i;
/* Save the ciphertext */
memcpy( temp, buffer, SAFER_BLOCKSIZE );
/* Decrypt a block of data */
Safer_Decrypt_Block( buffer, *saferKey, buffer );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < SAFER_BLOCKSIZE; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, SAFER_BLOCKSIZE );
/* Move on to next block of data */
buffer += SAFER_BLOCKSIZE;
}
/* Clear the temporary buffer */
memset( temp, 0, SAFER_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in CFB mode */
int saferEncryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SAFER_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, buffer, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
/* Encrypt the IV */
Safer_Encrypt_Block( cryptInfo->currentIV, *saferKey, cryptInfo->currentIV );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, buffer, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in CFB mode. Note that the transformation can be made
faster (but less clear) with temp = buffer, buffer ^= iv, iv = temp
all in one loop */
int saferDecryptCFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
BYTE temp[ SAFER_BLOCKSIZE ];
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SAFER_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
memcpy( temp, buffer, bytesToUse );
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
memcpy( cryptInfo->currentIV + ivCount, temp, bytesToUse );
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
/* Encrypt the IV */
Safer_Encrypt_Block( cryptInfo->currentIV, *saferKey, cryptInfo->currentIV );
/* Save the ciphertext */
memcpy( temp, buffer, ivCount );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Shift the ciphertext into the IV */
memcpy( cryptInfo->currentIV, temp, ivCount );
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
/* Clear the temporary buffer */
memset( temp, 0, SAFER_BLOCKSIZE );
return( CRYPT_OK );
}
/* Encrypt/decrypt data in OFB mode */
int saferEncryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SAFER_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Encrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
/* Encrypt the IV */
Safer_Encrypt_Block( cryptInfo->currentIV, *saferKey, cryptInfo->currentIV );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
return( CRYPT_OK );
}
/* Decrypt data in OFB mode */
int saferDecryptOFB( CRYPT_INFO *cryptInfo, BYTE *buffer, int noBytes )
{
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
int i, ivCount = cryptInfo->ivCount;
/* If there's any encrypted material left in the IV, use it now */
if( ivCount )
{
int bytesToUse;
/* Find out how much material left in the encrypted IV we can use */
bytesToUse = SAFER_BLOCKSIZE - ivCount;
if( noBytes < bytesToUse )
bytesToUse = noBytes;
/* Decrypt the data */
for( i = 0; i < bytesToUse; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i + ivCount ];
/* Adjust the byte count and buffer position */
noBytes -= bytesToUse;
buffer += bytesToUse;
ivCount += bytesToUse;
}
while( noBytes )
{
ivCount = ( noBytes > SAFER_BLOCKSIZE ) ? SAFER_BLOCKSIZE : noBytes;
/* Encrypt the IV */
Safer_Encrypt_Block( cryptInfo->currentIV, *saferKey, cryptInfo->currentIV );
/* XOR the buffer contents with the encrypted IV */
for( i = 0; i < ivCount; i++ )
buffer[ i ] ^= cryptInfo->currentIV[ i ];
/* Move on to next block of data */
noBytes -= ivCount;
buffer += ivCount;
}
/* Remember how much of the IV is still available for use */
cryptInfo->ivCount = ( ivCount % SAFER_BLOCKSIZE );
return( CRYPT_OK );
}
/****************************************************************************
* *
* SAFER Key Management Routines *
* *
****************************************************************************/
/* Key schedule a SAFER key */
int saferInitKey( CRYPT_INFO *cryptInfo )
{
CRYPT_INFO_SAFER *cryptInfoEx = ( CRYPT_INFO_SAFER * ) cryptInfo->privateData;
SAFER_KEY *saferKey = ( SAFER_KEY * ) cryptInfo->key;
BOOLEAN shortKey = cryptInfo->userKeyLength <= bitsToBytes( 64 );
/* If the number of rounds has been preset, use this value */
if( cryptInfoEx->rounds != CRYPT_USE_DEFAULT )
cryptInfoEx->currentRounds = cryptInfoEx->rounds;
else
/* Determine the number of rounds to use based on the key size */
if( cryptInfoEx->useSaferSK )
cryptInfoEx->currentRounds = ( shortKey ) ? \
SAFER_SK64_DEFAULT_NOF_ROUNDS : SAFER_SK128_DEFAULT_NOF_ROUNDS;
else
cryptInfoEx->currentRounds = ( shortKey ) ? \
SAFER_K64_DEFAULT_NOF_ROUNDS : SAFER_K128_DEFAULT_NOF_ROUNDS;
/* Generate an expanded SAFER key */
if( shortKey )
Safer_Expand_Userkey( cryptInfo->userKey, \
cryptInfo->userKey, cryptInfoEx->currentRounds, \
cryptInfoEx->useSaferSK, *saferKey );
else
Safer_Expand_Userkey( cryptInfo->userKey, \
cryptInfo->userKey + bitsToBytes( 64 ), \
cryptInfoEx->currentRounds, \
cryptInfoEx->useSaferSK, *saferKey );
return( CRYPT_OK );
}
+36
View File
@@ -0,0 +1,36 @@
/* 3ecb_enc.c */
/* Copyright (C) 1993 Eric Young - see README for more details */
#ifdef _MSC_VER
#include "des_locl.h"
#else
#include "libdes/des_locl.h"
#endif /* _MSC_VER */
int des_3ecb_encrypt(input,output,ks1,ks2,encrypt)
des_cblock *input;
des_cblock *output;
des_key_schedule ks1,ks2;
int encrypt;
{
register unsigned long l0,l1;
register unsigned char *in,*out;
unsigned long ll[2];
in=(unsigned char *)input;
out=(unsigned char *)output;
c2l(in,l0);
c2l(in,l1);
ll[0]=l0;
ll[1]=l1;
des_encrypt(ll,ll,ks1,encrypt);
des_encrypt(ll,ll,ks2,!encrypt);
des_encrypt(ll,ll,ks1,encrypt);
l0=ll[0];
l1=ll[1];
l2c(l0,out);
l2c(l1,out);
return(0);
}
+50
View File
@@ -0,0 +1,50 @@
Copyright (C) 1995 Eric Young (eay@mincom.oz.au)
All rights reserved.
This package is an DES implementation written by Eric Young (eay@mincom.oz.au).
The implementation was written so as to conform with MIT's libdes.
This library is free for commercial and non-commercial use as long as
the following conditions are aheared to. The following conditions
apply to all code found in this distribution.
Copyright remains Eric Young's, and as such any Copyright notices in
the code are not to be removed.
If this package is used in a product, Eric Young should be given attribution
as the author of that the SSL library. This can be in the form of a textual
message at program startup or in documentation (online or textual) provided
with the package.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Eric Young (eay@mincom.oz.au)
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
The license and distribution terms for any publically available version or
derivative of this code cannot be changed. i.e. this code cannot simply be
copied and put under another distrubution license
[including the GNU Public License.]
The reason behind this being stated in this direct manner is past
experience in code simply being copied and the attribution removed
from it and then being distributed as part of other packages. This
implementation was a non-trivial and unpaid effort.
+98
View File
@@ -0,0 +1,98 @@
/* des.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
#ifndef HEADER_DES_H
#define HEADER_DES_H
typedef unsigned char des_cblock[8];
typedef struct des_ks_struct
{
union {
des_cblock _;
/* make sure things are correct size on machines with
* 8 byte longs */
unsigned long pad[2];
} ks;
#undef _
#define _ ks._
} des_key_schedule[16];
#define DES_KEY_SZ (sizeof(des_cblock))
#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define DES_CBC_MODE 0
#define DES_PCBC_MODE 1
#define C_Block des_cblock
#define Key_schedule des_key_schedule
#define ENCRYPT DES_ENCRYPT
#define DECRYPT DES_DECRYPT
#define KEY_SZ DES_KEY_SZ
#define string_to_key des_string_to_key
#define read_pw_string des_read_pw_string
#define random_key des_random_key
#define pcbc_encrypt des_pcbc_encrypt
#define set_key des_set_key
#define key_sched des_key_sched
#define ecb_encrypt des_ecb_encrypt
#define cbc_encrypt des_cbc_encrypt
#define cbc_cksum des_cbc_cksum
#define quad_cksum des_quad_cksum
/* For compatibility with the MIT lib - eay 20/05/92 */
typedef struct des_ks_struct bit_64;
extern int des_check_key; /* defaults to false */
extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
int des_3ecb_encrypt(des_cblock *input,des_cblock *output,\
des_key_schedule ks1,des_key_schedule ks2,int encrypt);
unsigned long des_cbc_cksum(des_cblock *input,des_cblock *output,\
long length,des_key_schedule schedule,des_cblock *ivec);
int des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,\
des_key_schedule schedule,des_cblock *ivec,int encrypt);
int des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,\
des_key_schedule sk1,des_key_schedule sk2,\
des_cblock *ivec1,des_cblock *ivec2,int encrypt);
int des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,\
long length,des_key_schedule schedule,des_cblock *ivec,int encrypt);
int des_ecb_encrypt(des_cblock *input,des_cblock *output,\
des_key_schedule ks,int encrypt);
int des_encrypt(unsigned long *input,unsigned long *output,
des_key_schedule ks, int encrypt);
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,\
des_cblock *iv);
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,\
des_cblock *iv);
#ifdef PERL5
char *des_crypt(const char *buf,const char *salt);
#else
char *crypt(char *buf,char *salt);
#endif
int des_ofb_encrypt(unsigned char *in,unsigned char *out,\
int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
int des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,\
des_key_schedule schedule,des_cblock *ivec,int encrypt);
unsigned long des_quad_cksum(des_cblock *input,des_cblock *output,\
long length,int out_count,des_cblock *seed);
void des_random_seed(des_cblock key);
int des_random_key(des_cblock ret);
int des_read_password(des_cblock *key,char *prompt,int verify);
int des_read_2passwords(des_cblock *key1,des_cblock *key2, \
char *prompt,int verify);
int des_read_pw_string(char *buf,int length,char *prompt,int verify);
void des_set_odd_parity(des_cblock *key);
int des_is_weak_key(des_cblock *key);
int des_set_key(des_cblock *key,des_key_schedule schedule);
int des_key_sched(des_cblock *key,des_key_schedule schedule);
int des_string_to_key(char *str,des_cblock *key);
int des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
#endif
+204
View File
@@ -0,0 +1,204 @@
/* des_locl.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
#include <stdio.h>
#ifdef _MSC_VER
#include "des.h"
#else
#include "libdes/des.h"
#endif /* _MSC_VER */
/* Force ANSI usage as the rest of the library assumes ANSI anyway - pcg */
#include <string.h>
#define bcopy(b1,b2,len) memcpy(b2, b1, (size_t)(len))
#define bzero(b,len) memset(b, 0, (size_t)(len))
#define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len))
#define index(s1,char) strchr(s1,char)
#if !defined(_LIBC) || defined(NOCONST)
#define const
#endif
#ifdef __STDC__
#define PROTO
#endif
#ifdef RAND
#define random() rand()
#define srandom(s) srand(s)
#endif
#define ITERATIONS 16
#define HALF_ITERATIONS 8
/* used in des_read and des_write */
#define MAXWRITE (1024*16)
#define BSIZE (MAXWRITE+4)
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
l|=((unsigned long)(*((c)++)))<< 8, \
l|=((unsigned long)(*((c)++)))<<16, \
l|=((unsigned long)(*((c)++)))<<24)
/* NOTE - c is not incremented as per c2l */
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((unsigned long)(*(--(c))))<<24; \
case 7: l2|=((unsigned long)(*(--(c))))<<16; \
case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
case 5: l2|=((unsigned long)(*(--(c)))); \
case 4: l1 =((unsigned long)(*(--(c))))<<24; \
case 3: l1|=((unsigned long)(*(--(c))))<<16; \
case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
case 1: l1|=((unsigned long)(*(--(c)))); \
} \
}
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff))
/* replacements for htonl and ntohl since I have no idea what to do
* when faced with machines with 8 byte longs. */
#define HDRSIZE 4
#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \
l|=((unsigned long)(*((c)++)))<<16, \
l|=((unsigned long)(*((c)++)))<< 8, \
l|=((unsigned long)(*((c)++))))
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* NOTE - c is not incremented as per l2c */
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
/* The changes to this macro may help or hinder, depending on the
* compiler and the achitecture. gcc2 always seems to do well :-).
* Inspired by Dana How <how@isl.stanford.edu>
* DO NOT use the alternative version on machines with 8 byte longs. */
#ifdef ALT_ECB
#define D_ENCRYPT(L,R,S) \
u=((R^s[S ])<<2); \
t= R^s[S+1]; \
t=((t>>2)+(t<<30)); \
L^= \
*(unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \
*(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
*(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
*(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
*(unsigned long *)(des_SP+ ((u )&0xfc))+ \
*(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
*(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
*(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
#else /* original version */
#ifdef MSDOS
#define D_ENCRYPT(L,R,S) \
U.l=R^s[S+1]; \
T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \
T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \
U.l=(R^s[S ])&0x3f3f3f3f; \
L^= des_SPtrans[1][(T.c[0])]| \
des_SPtrans[3][(T.c[1])]| \
des_SPtrans[5][(T.c[2])]| \
des_SPtrans[7][(T.c[3])]| \
des_SPtrans[0][(U.c[0])]| \
des_SPtrans[2][(U.c[1])]| \
des_SPtrans[4][(U.c[2])]| \
des_SPtrans[6][(U.c[3])];
#else
#define D_ENCRYPT(L,R,S) \
u=(R^s[S ]); \
t=R^s[S+1]; \
t=((t>>4)+(t<<28)); \
L^= des_SPtrans[1][(t )&0x3f]| \
des_SPtrans[3][(t>> 8)&0x3f]| \
des_SPtrans[5][(t>>16)&0x3f]| \
des_SPtrans[7][(t>>24)&0x3f]| \
des_SPtrans[0][(u )&0x3f]| \
des_SPtrans[2][(u>> 8)&0x3f]| \
des_SPtrans[4][(u>>16)&0x3f]| \
des_SPtrans[6][(u>>24)&0x3f];
#endif
#endif
/* IP and FP
* The problem is more of a geometric problem that random bit fiddling.
0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
The output has been subject to swaps of the form
0 1 -> 3 1 but the odd and even bits have been put into
2 3 2 0
different words. The main trick is to remember that
t=((l>>size)^r)&(mask);
r^=t;
l^=(t<<size);
can be used to swap and move bits between words.
So l = 0 1 2 3 r = 16 17 18 19
4 5 6 7 20 21 22 23
8 9 10 11 24 25 26 27
12 13 14 15 28 29 30 31
becomes (for size == 2 and mask == 0x3333)
t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
6^20 7^21 -- -- 4 5 20 21 6 7 22 23
10^24 11^25 -- -- 8 9 24 25 10 11 24 25
14^28 15^29 -- -- 12 13 28 29 14 15 28 29
Thanks for hints from Richard Outerbridge - he told me IP&FP
could be done in 15 xor, 10 shifts and 5 ands.
When I finally started to think of the problem in 2D
I first got ~42 operations without xors. When I remembered
how to use xors :-) I got it to its final state.
*/
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
(b)^=(t),\
(a)^=((t)<<(n)))
#define IP(l,r,t) \
PERM_OP(r,l,t, 4,0x0f0f0f0fL); \
PERM_OP(l,r,t,16,0x0000ffffL); \
PERM_OP(r,l,t, 2,0x33333333L); \
PERM_OP(l,r,t, 8,0x00ff00ffL); \
PERM_OP(r,l,t, 1,0x55555555L);
#define FP(l,r,t) \
PERM_OP(l,r,t, 1,0x55555555L); \
PERM_OP(r,l,t, 8,0x00ff00ffL); \
PERM_OP(l,r,t, 2,0x33333333L); \
PERM_OP(r,l,t,16,0x0000ffffL); \
PERM_OP(l,r,t, 4,0x0f0f0f0fL);
+112
View File
@@ -0,0 +1,112 @@
/* ecb_enc.c */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
#ifdef _MSC_VER
#include "des_locl.h"
#include "spr.h"
#include "version.h"
#else
#include "libdes/des_locl.h"
#include "libdes/spr.h"
#include "libdes/version.h"
#endif /* _MSC_VER */
int des_ecb_encrypt(input,output,ks,encrypt)
des_cblock *input;
des_cblock *output;
des_key_schedule ks;
int encrypt;
{
register unsigned long l0,l1;
register unsigned char *in,*out;
unsigned long ll[2];
in=(unsigned char *)input;
out=(unsigned char *)output;
c2l(in,l0);
c2l(in,l1);
ll[0]=l0;
ll[1]=l1;
des_encrypt(ll,ll,ks,encrypt);
l0=ll[0];
l1=ll[1];
l2c(l0,out);
l2c(l1,out);
l0=l1=ll[0]=ll[1]=0;
return(0);
}
int des_encrypt(input,output,ks,encrypt)
unsigned long *input;
unsigned long *output;
des_key_schedule ks;
int encrypt;
{
register unsigned long l,r,t,u;
#ifdef ALT_ECB
register unsigned char *des_SP=(unsigned char *)des_SPtrans;
#endif
#ifdef MSDOS
union fudge {
unsigned long l;
unsigned short s[2];
unsigned char c[4];
} U,T;
#endif
register int i;
register unsigned long *s;
l=input[0];
r=input[1];
IP(l,r,t);
/* Things have been modified so that the initial rotate is
* done outside the loop. This required the
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
* One perl script later and things have a 5% speed up on a sparc2.
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
* for pointing this out. */
t=(r<<1)|(r>>31);
r=(l<<1)|(l>>31);
l=t;
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
s=(unsigned long *)ks;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (encrypt)
{
for (i=0; i<32; i+=4)
{
D_ENCRYPT(l,r,i+0); /* 1 */
D_ENCRYPT(r,l,i+2); /* 2 */
}
}
else
{
for (i=30; i>0; i-=4)
{
D_ENCRYPT(l,r,i-0); /* 16 */
D_ENCRYPT(r,l,i-2); /* 15 */
}
}
l=(l>>1)|(l<<31);
r=(r>>1)|(r<<31);
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
FP(r,l,t);
output[0]=l;
output[1]=r;
l=r=t=u=0;
return(0);
}
+83
View File
@@ -0,0 +1,83 @@
/* pcbc_enc.c */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
#ifdef _MSC_VER
#include "des_locl.h"
#else
#include "libdes/des_locl.h"
#endif /* _MSC_VER */
int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
des_cblock *input;
des_cblock *output;
long length;
des_key_schedule schedule;
des_cblock *ivec;
int encrypt;
{
register unsigned long sin0,sin1,xor0,xor1,tout0,tout1;
unsigned long tin[2],tout[2];
unsigned char *in,*out,*iv;
in=(unsigned char *)input;
out=(unsigned char *)output;
iv=(unsigned char *)ivec;
if (encrypt)
{
c2l(iv,xor0);
c2l(iv,xor1);
for (; length>0; length-=8)
{
if (length >= 8)
{
c2l(in,sin0);
c2l(in,sin1);
}
else
c2ln(in,sin0,sin1,length);
tin[0]=sin0^xor0;
tin[1]=sin1^xor1;
des_encrypt((unsigned long *)tin,(unsigned long *)tout,
schedule,encrypt);
tout0=tout[0];
tout1=tout[1];
xor0=sin0^tout[0];
xor1=sin1^tout[1];
l2c(tout0,out);
l2c(tout1,out);
}
}
else
{
c2l(iv,xor0); c2l(iv,xor1);
for (; length>0; length-=8)
{
c2l(in,sin0);
c2l(in,sin1);
tin[0]=sin0;
tin[1]=sin1;
des_encrypt((unsigned long *)tin,(unsigned long *)tout,
schedule,encrypt);
tout0=tout[0]^xor0;
tout1=tout[1]^xor1;
if (length >= 8)
{
l2c(tout0,out);
l2c(tout1,out);
}
else
l2cn(tout0,tout1,out,length);
xor0=tout0^sin0;
xor1=tout1^sin1;
}
}
tin[0]=tin[1]=tout[0]=tout[1]=0;
sin0=sin1=xor0=xor1=tout0=tout1=0;
return(0);
}
+25
View File
@@ -0,0 +1,25 @@
/* podd.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
static const unsigned char odd_parity[256]={
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
+198
View File
@@ -0,0 +1,198 @@
/* set_key.c */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
/* set_key.c v 1.4 eay 24/9/91
* 1.4 Speed up by 400% :-)
* 1.3 added register declarations.
* 1.2 unrolled make_key_sched a bit more
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
#ifdef _MSC_VER
#include "des_locl.h"
#include "podd.h"
#include "sk.h"
#else
#include "libdes/des_locl.h"
#include "libdes/podd.h"
#include "libdes/sk.h"
#endif /* _MSC_VER */
static int check_parity(des_cblock *key);
int des_check_key=0;
void des_set_odd_parity(key)
des_cblock *key;
{
int i;
for (i=0; i<DES_KEY_SZ; i++)
(*key)[i]=odd_parity[(*key)[i]];
}
static int check_parity(key)
des_cblock *key;
{
int i;
for (i=0; i<DES_KEY_SZ; i++)
{
if ((*key)[i] != odd_parity[(*key)[i]])
return(0);
}
return(1);
}
/* Weak and semi week keys as take from
* %A D.W. Davies
* %A W.L. Price
* %T Security for Computer Networks
* %I John Wiley & Sons
* %D 1984
* Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
* (and actual cblock values).
*/
#define NUM_WEAK_KEY 16
static des_cblock weak_keys[NUM_WEAK_KEY]={
/* weak keys */
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
/* semi-weak keys */
0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,
0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,
0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1,
0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E,
0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,
0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01,
0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE,
0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,
0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,
0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01,
0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1};
int des_is_weak_key(key)
des_cblock *key;
{
int i;
for (i=0; i<NUM_WEAK_KEY; i++)
/* Added == 0 to comparision, I obviously don't run
* this section very often :-(, thanks to
* engineering@MorningStar.Com for the fix
* eay 93/06/29 */
if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
return(0);
}
/* NOW DEFINED IN des_local.h
* See ecb_encrypt.c for a pseudo description of these macros.
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
* (b)^=(t),\
* (a)=((a)^((t)<<(n))))
*/
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
(a)=(a)^(t)^(t>>(16-(n))))
static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
/* return 0 if key parity is odd (correct),
* return -1 if key parity error,
* return -2 if illegal weak key.
*/
int des_set_key(key,schedule)
des_cblock *key;
des_key_schedule schedule;
{
register unsigned long c,d,t,s;
register unsigned char *in;
register unsigned long *k;
register int i;
if (des_check_key)
{
if (!check_parity(key))
return(-1);
if (des_is_weak_key(key))
return(-2);
}
k=(unsigned long *)schedule;
in=(unsigned char *)key;
c2l(in,c);
c2l(in,d);
/* do PC1 in 60 simple operations */
/* PERM_OP(d,c,t,4,0x0f0f0f0f);
HPERM_OP(c,t,-2, 0xcccc0000);
HPERM_OP(c,t,-1, 0xaaaa0000);
HPERM_OP(c,t, 8, 0x00ff0000);
HPERM_OP(c,t,-1, 0xaaaa0000);
HPERM_OP(d,t,-8, 0xff000000);
HPERM_OP(d,t, 8, 0x00ff0000);
HPERM_OP(d,t, 2, 0x33330000);
d=((d&0x00aa00aa)<<7)|((d&0x55005500)>>7)|(d&0xaa55aa55);
d=(d>>8)|((c&0xf0000000)>>4);
c&=0x0fffffff; */
/* I now do it in 47 simple operations :-)
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
* for the inspiration. :-) */
PERM_OP (d,c,t,4,0x0f0f0f0fL);
HPERM_OP(c,t,-2,0xcccc0000L);
HPERM_OP(d,t,-2,0xcccc0000L);
PERM_OP (d,c,t,1,0x55555555L);
PERM_OP (c,d,t,8,0x00ff00ffL);
PERM_OP (d,c,t,1,0x55555555L);
d= (((d&0x000000ffL)<<16)| (d&0x0000ff00L) |
((d&0x00ff0000L)>>16)|((c&0xf0000000L)>>4));
c&=0x0fffffffL;
for (i=0; i<ITERATIONS; i++)
{
if (shifts2[i])
{ c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
else
{ c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
c&=0x0fffffffL;
d&=0x0fffffffL;
/* could be a few less shifts but I am to lazy at this
* point in time to investigate */
s= des_skb[0][ (c )&0x3f ]|
des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
((c>>22)&0x38)];
t= des_skb[4][ (d )&0x3f ]|
des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
des_skb[6][ (d>>15)&0x3f ]|
des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];
/* table contained 0213 4657 */
*(k++)=((t<<16)|(s&0x0000ffffL))&0xffffffffL;
s= ((s>>16)|(t&0xffff0000L));
s=(s<<4)|(s>>28);
*(k++)=s&0xffffffffL;
}
return(0);
}
int des_key_sched(key,schedule)
des_cblock *key;
des_key_schedule schedule;
{
return(des_set_key(key,schedule));
}
+146
View File
@@ -0,0 +1,146 @@
/* sk.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
static const unsigned long des_skb[8][64]={
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x00000010L,0x20000000L,0x20000010L,
0x00010000L,0x00010010L,0x20010000L,0x20010010L,
0x00000800L,0x00000810L,0x20000800L,0x20000810L,
0x00010800L,0x00010810L,0x20010800L,0x20010810L,
0x00000020L,0x00000030L,0x20000020L,0x20000030L,
0x00010020L,0x00010030L,0x20010020L,0x20010030L,
0x00000820L,0x00000830L,0x20000820L,0x20000830L,
0x00010820L,0x00010830L,0x20010820L,0x20010830L,
0x00080000L,0x00080010L,0x20080000L,0x20080010L,
0x00090000L,0x00090010L,0x20090000L,0x20090010L,
0x00080800L,0x00080810L,0x20080800L,0x20080810L,
0x00090800L,0x00090810L,0x20090800L,0x20090810L,
0x00080020L,0x00080030L,0x20080020L,0x20080030L,
0x00090020L,0x00090030L,0x20090020L,0x20090030L,
0x00080820L,0x00080830L,0x20080820L,0x20080830L,
0x00090820L,0x00090830L,0x20090820L,0x20090830L,
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
0x00000000L,0x02000000L,0x00002000L,0x02002000L,
0x00200000L,0x02200000L,0x00202000L,0x02202000L,
0x00000004L,0x02000004L,0x00002004L,0x02002004L,
0x00200004L,0x02200004L,0x00202004L,0x02202004L,
0x00000400L,0x02000400L,0x00002400L,0x02002400L,
0x00200400L,0x02200400L,0x00202400L,0x02202400L,
0x00000404L,0x02000404L,0x00002404L,0x02002404L,
0x00200404L,0x02200404L,0x00202404L,0x02202404L,
0x10000000L,0x12000000L,0x10002000L,0x12002000L,
0x10200000L,0x12200000L,0x10202000L,0x12202000L,
0x10000004L,0x12000004L,0x10002004L,0x12002004L,
0x10200004L,0x12200004L,0x10202004L,0x12202004L,
0x10000400L,0x12000400L,0x10002400L,0x12002400L,
0x10200400L,0x12200400L,0x10202400L,0x12202400L,
0x10000404L,0x12000404L,0x10002404L,0x12002404L,
0x10200404L,0x12200404L,0x10202404L,0x12202404L,
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
0x00000000L,0x00000001L,0x00040000L,0x00040001L,
0x01000000L,0x01000001L,0x01040000L,0x01040001L,
0x00000002L,0x00000003L,0x00040002L,0x00040003L,
0x01000002L,0x01000003L,0x01040002L,0x01040003L,
0x00000200L,0x00000201L,0x00040200L,0x00040201L,
0x01000200L,0x01000201L,0x01040200L,0x01040201L,
0x00000202L,0x00000203L,0x00040202L,0x00040203L,
0x01000202L,0x01000203L,0x01040202L,0x01040203L,
0x08000000L,0x08000001L,0x08040000L,0x08040001L,
0x09000000L,0x09000001L,0x09040000L,0x09040001L,
0x08000002L,0x08000003L,0x08040002L,0x08040003L,
0x09000002L,0x09000003L,0x09040002L,0x09040003L,
0x08000200L,0x08000201L,0x08040200L,0x08040201L,
0x09000200L,0x09000201L,0x09040200L,0x09040201L,
0x08000202L,0x08000203L,0x08040202L,0x08040203L,
0x09000202L,0x09000203L,0x09040202L,0x09040203L,
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
0x00000000L,0x00100000L,0x00000100L,0x00100100L,
0x00000008L,0x00100008L,0x00000108L,0x00100108L,
0x00001000L,0x00101000L,0x00001100L,0x00101100L,
0x00001008L,0x00101008L,0x00001108L,0x00101108L,
0x04000000L,0x04100000L,0x04000100L,0x04100100L,
0x04000008L,0x04100008L,0x04000108L,0x04100108L,
0x04001000L,0x04101000L,0x04001100L,0x04101100L,
0x04001008L,0x04101008L,0x04001108L,0x04101108L,
0x00020000L,0x00120000L,0x00020100L,0x00120100L,
0x00020008L,0x00120008L,0x00020108L,0x00120108L,
0x00021000L,0x00121000L,0x00021100L,0x00121100L,
0x00021008L,0x00121008L,0x00021108L,0x00121108L,
0x04020000L,0x04120000L,0x04020100L,0x04120100L,
0x04020008L,0x04120008L,0x04020108L,0x04120108L,
0x04021000L,0x04121000L,0x04021100L,0x04121100L,
0x04021008L,0x04121008L,0x04021108L,0x04121108L,
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x10000000L,0x00010000L,0x10010000L,
0x00000004L,0x10000004L,0x00010004L,0x10010004L,
0x20000000L,0x30000000L,0x20010000L,0x30010000L,
0x20000004L,0x30000004L,0x20010004L,0x30010004L,
0x00100000L,0x10100000L,0x00110000L,0x10110000L,
0x00100004L,0x10100004L,0x00110004L,0x10110004L,
0x20100000L,0x30100000L,0x20110000L,0x30110000L,
0x20100004L,0x30100004L,0x20110004L,0x30110004L,
0x00001000L,0x10001000L,0x00011000L,0x10011000L,
0x00001004L,0x10001004L,0x00011004L,0x10011004L,
0x20001000L,0x30001000L,0x20011000L,0x30011000L,
0x20001004L,0x30001004L,0x20011004L,0x30011004L,
0x00101000L,0x10101000L,0x00111000L,0x10111000L,
0x00101004L,0x10101004L,0x00111004L,0x10111004L,
0x20101000L,0x30101000L,0x20111000L,0x30111000L,
0x20101004L,0x30101004L,0x20111004L,0x30111004L,
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
0x00000000L,0x08000000L,0x00000008L,0x08000008L,
0x00000400L,0x08000400L,0x00000408L,0x08000408L,
0x00020000L,0x08020000L,0x00020008L,0x08020008L,
0x00020400L,0x08020400L,0x00020408L,0x08020408L,
0x00000001L,0x08000001L,0x00000009L,0x08000009L,
0x00000401L,0x08000401L,0x00000409L,0x08000409L,
0x00020001L,0x08020001L,0x00020009L,0x08020009L,
0x00020401L,0x08020401L,0x00020409L,0x08020409L,
0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
0x00000000L,0x00000100L,0x00080000L,0x00080100L,
0x01000000L,0x01000100L,0x01080000L,0x01080100L,
0x00000010L,0x00000110L,0x00080010L,0x00080110L,
0x01000010L,0x01000110L,0x01080010L,0x01080110L,
0x00200000L,0x00200100L,0x00280000L,0x00280100L,
0x01200000L,0x01200100L,0x01280000L,0x01280100L,
0x00200010L,0x00200110L,0x00280010L,0x00280110L,
0x01200010L,0x01200110L,0x01280010L,0x01280110L,
0x00000200L,0x00000300L,0x00080200L,0x00080300L,
0x01000200L,0x01000300L,0x01080200L,0x01080300L,
0x00000210L,0x00000310L,0x00080210L,0x00080310L,
0x01000210L,0x01000310L,0x01080210L,0x01080310L,
0x00200200L,0x00200300L,0x00280200L,0x00280300L,
0x01200200L,0x01200300L,0x01280200L,0x01280300L,
0x00200210L,0x00200310L,0x00280210L,0x00280310L,
0x01200210L,0x01200310L,0x01280210L,0x01280310L,
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
0x00000000L,0x04000000L,0x00040000L,0x04040000L,
0x00000002L,0x04000002L,0x00040002L,0x04040002L,
0x00002000L,0x04002000L,0x00042000L,0x04042000L,
0x00002002L,0x04002002L,0x00042002L,0x04042002L,
0x00000020L,0x04000020L,0x00040020L,0x04040020L,
0x00000022L,0x04000022L,0x00040022L,0x04040022L,
0x00002020L,0x04002020L,0x00042020L,0x04042020L,
0x00002022L,0x04002022L,0x00042022L,0x04042022L,
0x00000800L,0x04000800L,0x00040800L,0x04040800L,
0x00000802L,0x04000802L,0x00040802L,0x04040802L,
0x00002800L,0x04002800L,0x00042800L,0x04042800L,
0x00002802L,0x04002802L,0x00042802L,0x04042802L,
0x00000820L,0x04000820L,0x00040820L,0x04040820L,
0x00000822L,0x04000822L,0x00040822L,0x04040822L,
0x00002820L,0x04002820L,0x00042820L,0x04042820L,
0x00002822L,0x04002822L,0x00042822L,0x04042822L
};
+152
View File
@@ -0,0 +1,152 @@
/* spr.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
static const unsigned long des_SPtrans[8][64]={
/* nibble 0 */
0x00820200L, 0x00020000L, 0x80800000L, 0x80820200L,
0x00800000L, 0x80020200L, 0x80020000L, 0x80800000L,
0x80020200L, 0x00820200L, 0x00820000L, 0x80000200L,
0x80800200L, 0x00800000L, 0x00000000L, 0x80020000L,
0x00020000L, 0x80000000L, 0x00800200L, 0x00020200L,
0x80820200L, 0x00820000L, 0x80000200L, 0x00800200L,
0x80000000L, 0x00000200L, 0x00020200L, 0x80820000L,
0x00000200L, 0x80800200L, 0x80820000L, 0x00000000L,
0x00000000L, 0x80820200L, 0x00800200L, 0x80020000L,
0x00820200L, 0x00020000L, 0x80000200L, 0x00800200L,
0x80820000L, 0x00000200L, 0x00020200L, 0x80800000L,
0x80020200L, 0x80000000L, 0x80800000L, 0x00820000L,
0x80820200L, 0x00020200L, 0x00820000L, 0x80800200L,
0x00800000L, 0x80000200L, 0x80020000L, 0x00000000L,
0x00020000L, 0x00800000L, 0x80800200L, 0x00820200L,
0x80000000L, 0x80820000L, 0x00000200L, 0x80020200L,
/* nibble 1 */
0x10042004L, 0x00000000L, 0x00042000L, 0x10040000L,
0x10000004L, 0x00002004L, 0x10002000L, 0x00042000L,
0x00002000L, 0x10040004L, 0x00000004L, 0x10002000L,
0x00040004L, 0x10042000L, 0x10040000L, 0x00000004L,
0x00040000L, 0x10002004L, 0x10040004L, 0x00002000L,
0x00042004L, 0x10000000L, 0x00000000L, 0x00040004L,
0x10002004L, 0x00042004L, 0x10042000L, 0x10000004L,
0x10000000L, 0x00040000L, 0x00002004L, 0x10042004L,
0x00040004L, 0x10042000L, 0x10002000L, 0x00042004L,
0x10042004L, 0x00040004L, 0x10000004L, 0x00000000L,
0x10000000L, 0x00002004L, 0x00040000L, 0x10040004L,
0x00002000L, 0x10000000L, 0x00042004L, 0x10002004L,
0x10042000L, 0x00002000L, 0x00000000L, 0x10000004L,
0x00000004L, 0x10042004L, 0x00042000L, 0x10040000L,
0x10040004L, 0x00040000L, 0x00002004L, 0x10002000L,
0x10002004L, 0x00000004L, 0x10040000L, 0x00042000L,
/* nibble 2 */
0x41000000L, 0x01010040L, 0x00000040L, 0x41000040L,
0x40010000L, 0x01000000L, 0x41000040L, 0x00010040L,
0x01000040L, 0x00010000L, 0x01010000L, 0x40000000L,
0x41010040L, 0x40000040L, 0x40000000L, 0x41010000L,
0x00000000L, 0x40010000L, 0x01010040L, 0x00000040L,
0x40000040L, 0x41010040L, 0x00010000L, 0x41000000L,
0x41010000L, 0x01000040L, 0x40010040L, 0x01010000L,
0x00010040L, 0x00000000L, 0x01000000L, 0x40010040L,
0x01010040L, 0x00000040L, 0x40000000L, 0x00010000L,
0x40000040L, 0x40010000L, 0x01010000L, 0x41000040L,
0x00000000L, 0x01010040L, 0x00010040L, 0x41010000L,
0x40010000L, 0x01000000L, 0x41010040L, 0x40000000L,
0x40010040L, 0x41000000L, 0x01000000L, 0x41010040L,
0x00010000L, 0x01000040L, 0x41000040L, 0x00010040L,
0x01000040L, 0x00000000L, 0x41010000L, 0x40000040L,
0x41000000L, 0x40010040L, 0x00000040L, 0x01010000L,
/* nibble 3 */
0x00100402L, 0x04000400L, 0x00000002L, 0x04100402L,
0x00000000L, 0x04100000L, 0x04000402L, 0x00100002L,
0x04100400L, 0x04000002L, 0x04000000L, 0x00000402L,
0x04000002L, 0x00100402L, 0x00100000L, 0x04000000L,
0x04100002L, 0x00100400L, 0x00000400L, 0x00000002L,
0x00100400L, 0x04000402L, 0x04100000L, 0x00000400L,
0x00000402L, 0x00000000L, 0x00100002L, 0x04100400L,
0x04000400L, 0x04100002L, 0x04100402L, 0x00100000L,
0x04100002L, 0x00000402L, 0x00100000L, 0x04000002L,
0x00100400L, 0x04000400L, 0x00000002L, 0x04100000L,
0x04000402L, 0x00000000L, 0x00000400L, 0x00100002L,
0x00000000L, 0x04100002L, 0x04100400L, 0x00000400L,
0x04000000L, 0x04100402L, 0x00100402L, 0x00100000L,
0x04100402L, 0x00000002L, 0x04000400L, 0x00100402L,
0x00100002L, 0x00100400L, 0x04100000L, 0x04000402L,
0x00000402L, 0x04000000L, 0x04000002L, 0x04100400L,
/* nibble 4 */
0x02000000L, 0x00004000L, 0x00000100L, 0x02004108L,
0x02004008L, 0x02000100L, 0x00004108L, 0x02004000L,
0x00004000L, 0x00000008L, 0x02000008L, 0x00004100L,
0x02000108L, 0x02004008L, 0x02004100L, 0x00000000L,
0x00004100L, 0x02000000L, 0x00004008L, 0x00000108L,
0x02000100L, 0x00004108L, 0x00000000L, 0x02000008L,
0x00000008L, 0x02000108L, 0x02004108L, 0x00004008L,
0x02004000L, 0x00000100L, 0x00000108L, 0x02004100L,
0x02004100L, 0x02000108L, 0x00004008L, 0x02004000L,
0x00004000L, 0x00000008L, 0x02000008L, 0x02000100L,
0x02000000L, 0x00004100L, 0x02004108L, 0x00000000L,
0x00004108L, 0x02000000L, 0x00000100L, 0x00004008L,
0x02000108L, 0x00000100L, 0x00000000L, 0x02004108L,
0x02004008L, 0x02004100L, 0x00000108L, 0x00004000L,
0x00004100L, 0x02004008L, 0x02000100L, 0x00000108L,
0x00000008L, 0x00004108L, 0x02004000L, 0x02000008L,
/* nibble 5 */
0x20000010L, 0x00080010L, 0x00000000L, 0x20080800L,
0x00080010L, 0x00000800L, 0x20000810L, 0x00080000L,
0x00000810L, 0x20080810L, 0x00080800L, 0x20000000L,
0x20000800L, 0x20000010L, 0x20080000L, 0x00080810L,
0x00080000L, 0x20000810L, 0x20080010L, 0x00000000L,
0x00000800L, 0x00000010L, 0x20080800L, 0x20080010L,
0x20080810L, 0x20080000L, 0x20000000L, 0x00000810L,
0x00000010L, 0x00080800L, 0x00080810L, 0x20000800L,
0x00000810L, 0x20000000L, 0x20000800L, 0x00080810L,
0x20080800L, 0x00080010L, 0x00000000L, 0x20000800L,
0x20000000L, 0x00000800L, 0x20080010L, 0x00080000L,
0x00080010L, 0x20080810L, 0x00080800L, 0x00000010L,
0x20080810L, 0x00080800L, 0x00080000L, 0x20000810L,
0x20000010L, 0x20080000L, 0x00080810L, 0x00000000L,
0x00000800L, 0x20000010L, 0x20000810L, 0x20080800L,
0x20080000L, 0x00000810L, 0x00000010L, 0x20080010L,
/* nibble 6 */
0x00001000L, 0x00000080L, 0x00400080L, 0x00400001L,
0x00401081L, 0x00001001L, 0x00001080L, 0x00000000L,
0x00400000L, 0x00400081L, 0x00000081L, 0x00401000L,
0x00000001L, 0x00401080L, 0x00401000L, 0x00000081L,
0x00400081L, 0x00001000L, 0x00001001L, 0x00401081L,
0x00000000L, 0x00400080L, 0x00400001L, 0x00001080L,
0x00401001L, 0x00001081L, 0x00401080L, 0x00000001L,
0x00001081L, 0x00401001L, 0x00000080L, 0x00400000L,
0x00001081L, 0x00401000L, 0x00401001L, 0x00000081L,
0x00001000L, 0x00000080L, 0x00400000L, 0x00401001L,
0x00400081L, 0x00001081L, 0x00001080L, 0x00000000L,
0x00000080L, 0x00400001L, 0x00000001L, 0x00400080L,
0x00000000L, 0x00400081L, 0x00400080L, 0x00001080L,
0x00000081L, 0x00001000L, 0x00401081L, 0x00400000L,
0x00401080L, 0x00000001L, 0x00001001L, 0x00401081L,
0x00400001L, 0x00401080L, 0x00401000L, 0x00001001L,
/* nibble 7 */
0x08200020L, 0x08208000L, 0x00008020L, 0x00000000L,
0x08008000L, 0x00200020L, 0x08200000L, 0x08208020L,
0x00000020L, 0x08000000L, 0x00208000L, 0x00008020L,
0x00208020L, 0x08008020L, 0x08000020L, 0x08200000L,
0x00008000L, 0x00208020L, 0x00200020L, 0x08008000L,
0x08208020L, 0x08000020L, 0x00000000L, 0x00208000L,
0x08000000L, 0x00200000L, 0x08008020L, 0x08200020L,
0x00200000L, 0x00008000L, 0x08208000L, 0x00000020L,
0x00200000L, 0x00008000L, 0x08000020L, 0x08208020L,
0x00008020L, 0x08000000L, 0x00000000L, 0x00208000L,
0x08200020L, 0x08008020L, 0x08008000L, 0x00200020L,
0x08208000L, 0x00000020L, 0x00200020L, 0x08008000L,
0x08208020L, 0x00200000L, 0x08200000L, 0x08000020L,
0x00208000L, 0x00008020L, 0x08008020L, 0x08200000L,
0x00000020L, 0x08208000L, 0x00208020L, 0x00000000L,
0x08000000L, 0x08200020L, 0x00008000L, 0x00208020L};
+9
View File
@@ -0,0 +1,9 @@
/* version.h */
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au).
* All rights reserved.
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* See the COPYRIGHT file in the libdes distribution for more details.
*/
static const char *version="libdes v 3.14 - eay";
+271
View File
@@ -0,0 +1,271 @@
#****************************************************************************
#* *
#* Makefile for the encryption library *
#* *
#****************************************************************************
PROJ = crypt
LIBNAME = lib$(PROJ).a
CFLAGS = -c -D__UNIX__ -O -I. $(CMDC) # Flags for compiler
LFLAGS = $(CMDL) # Flags for linker
OUTPATH = # Where object files go (/tmp is a good place)
OBJ = .o # Extension for object files
LD = $(CC) # Linker (just use the C compiler)
ECHO = echo # Echo to screen command
MAKE = make # The make command
# The object files which make up the library
OBJS = $(OUTPATH)crypt$(OBJ) $(OUTPATH)lib_3des$(OBJ) \
$(OUTPATH)lib_des$(OBJ) $(OUTPATH)lib_idea$(OBJ) \
$(OUTPATH)lib_mdc$(OBJ) $(OUTPATH)lib_null$(OBJ) \
$(OUTPATH)lib_rc4$(OBJ) $(OUTPATH)lib_safr$(OBJ) \
$(OUTPATH)idea$(OBJ) $(OUTPATH)3ecb_enc$(OBJ) \
$(OUTPATH)ecb_enc$(OBJ) $(OUTPATH)pcbc_enc$(OBJ) \
$(OUTPATH)set_key$(OBJ) $(OUTPATH)rc4$(OBJ) \
$(OUTPATH)safer$(OBJ) $(OUTPATH)shs$(OBJ)
#****************************************************************************
#* *
#* If no args are given, print a usage message and exit *
#* *
#****************************************************************************
default:
@$(ECHO)
@$(ECHO) "Usage: make <system-type>"
@$(ECHO)
@$(ECHO) "To create the encryption library, you have to enter the Unix system type"
@$(ECHO) "you want to build it for. Possible options are: aix, aix370, aix386,"
@$(ECHO) "bsd386, convex, irix, hpux, hpux-gcc, isc, linux, mint, mipsbsd, next, osf1,"
@$(ECHO) "qnx, sco, sun, svr4, ultrix, and uts4. If none of the above fit, try 'make "
@$(ECHO) "generic', and send a copy of any changes necessary to the author, "
@$(ECHO) "pgut01@cs.auckland.ac.nz"
@$(ECHO)
@$(ECHO) "After the library has been created, use 'make test' to build a test program"
@$(ECHO) "with it."
# Frohe Ostern.
babies:
@$(ECHO) "Good grief, what do you think I am? The Unix environment is capable, but"
@$(ECHO) "not that capable."
cookies:
@$(ECHO) "Mix 250g flour, 150g sugar, 125g butter, an egg, a few drops of vanilla"
@$(ECHO) "essence, and 1 tsp baking powder into a dough, cut cookies from rolls of"
@$(ECHO) "dough, bake for about 15 minutes at 180C until they turn very light brown"
@$(ECHO) "at the edges."
love:
@$(ECHO) "Nicht wahr?"
@$(ECHO)
#****************************************************************************
#* *
#* Rules to build the encryption library *
#* *
#****************************************************************************
# Main directory
$(OUTPATH)crypt$(OBJ): crypt.h crypt.c
$(CC) $(CFLAGS) crypt.c
$(OUTPATH)lib_3des$(OBJ): crypt.h libdes/des.h lib_3des.c
$(CC) $(CFLAGS) lib_3des.c
$(OUTPATH)lib_des$(OBJ): crypt.h testdes.h libdes/des.h lib_des.c
$(CC) $(CFLAGS) lib_des.c
$(OUTPATH)lib_idea$(OBJ): crypt.h idea/idea.h testidea.h lib_idea.c
$(CC) $(CFLAGS) lib_idea.c
$(OUTPATH)lib_mdc$(OBJ): crypt.h mdc/shs.h lib_mdc.c
$(CC) $(CFLAGS) lib_mdc.c
$(OUTPATH)lib_null$(OBJ): crypt.h lib_null.c
$(CC) $(CFLAGS) lib_null.c
$(OUTPATH)lib_rc4$(OBJ): crypt.h testrc4.h rc4/rc4.h lib_rc4.c
$(CC) $(CFLAGS) lib_rc4.c
$(OUTPATH)lib_safr$(OBJ): crypt.h testsafr.h safer/safer.h lib_safr.c
$(CC) $(CFLAGS) lib_safr.c
$(OUTPATH)test$(OBJ): crypt.h test.c
$(CC) $(CFLAGS) test.c
# idea subdirectory
$(OUTPATH)idea$(OBJ): idea/idea.h idea/idea.c
$(CC) $(CFLAGS) idea/idea.c
# libdes subdirectory
$(OUTPATH)3ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/3ecb_enc.c
$(CC) $(CFLAGS) libdes/3ecb_enc.c
$(OUTPATH)ecb_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/spr.h \
libdes/version.h libdes/ecb_enc.c
$(CC) $(CFLAGS) libdes/ecb_enc.c
$(OUTPATH)pcbc_enc$(OBJ): libdes/des.h libdes/des_locl.h libdes/pcbc_enc.c
$(CC) $(CFLAGS) libdes/pcbc_enc.c
$(OUTPATH)set_key$(OBJ): libdes/des.h libdes/des_locl.h libdes/podd.h \
libdes/sk.h libdes/set_key.c
$(CC) $(CFLAGS) libdes/set_key.c
# rc4 subdirectory
$(OUTPATH)rc4$(OBJ): rc4/rc4.h rc4/rc4.c
$(CC) $(CFLAGS) rc4/rc4.c
# safer subdirectory
$(OUTPATH)safer$(OBJ): safer/safer.h safer/safer.c
$(CC) $(CFLAGS) safer/safer.c
# mdc subdirectory
$(OUTPATH)shs$(OBJ): mdc/shs.h mdc/shs.c
$(CC) $(CFLAGS) mdc/shs.c
# Create the library. The test program is also listed as a dependancy
# since we need to use OS-specific compiler options for it which a
# simple 'make test' won't give us (yuck).
$(LIBNAME): $(OBJS) $(OUTPATH)test$(OBJ)
ar rc $(LIBNAME) $(OBJS)
# Link everything into a test program
test: $(LIBNAME) $(OUTPATH)test$(OBJ)
@$(LD) -o testcrypt $(LFLAGS) $(OUTPATH)test$(OBJ) -L. -l$(PROJ)
#****************************************************************************
#* *
#* Defines for each variation of Unix *
#* *
#****************************************************************************
# AIX for the RS6000: Use cc. Differs from AIX370/386 in endianness
aix:
@$(MAKE) $(LIBNAME) CC="cc"
# AIX370, AIX386: Use cc
aix370:
@$(MAKE) $(LIBNAME) CC="cc"
aix386:
@$(MAKE) $(LIBNAME) CC="cc"
# AUX: The only Unix so bloated it has /etc.etc.etc
# BSD 386: Use cc
bsd386:
@$(MAKE) $(LIBNAME) CC="cc"
# Convex: Use cc (cc has some bugs)
convex:
@$(MAKE) $(LIBNAME) CC="cc"
# Esix: Run away!! Run away!!
# Generic: Generic BSD-ish system running gcc
generic:
@$(MAKE) $(LIBNAME) CC="gcc"
# HPUX: Use cc if you have the ANSI C compiler, otherwise use gcc
# Need to use '-Aa -D_HPUX_SOURCE' as compiler options to get
# C compiler into ANSI C mode with UNIX symbols.
hpux:
@$(MAKE) $(LIBNAME) CMDC="-Aa -D_HPUX_SOURCE +O3" CC="cc"
hpux-gcc:
@$(MAKE) $(LIBNAME) CC="gcc"
# Irix: Use cc with the -acpp flag for maximum ANSI-ness
irix:
@$(MAKE) $(LIBNAME) CMDC="-acpp" CC="cc"
# ISC Unix: Use gcc
isc:
@$(MAKE) $(LIBNAME) CC="gcc"
# Linux: Use gcc
linux:
@$(MAKE) $(LIBNAME) CC="gcc"
# MiNT: Use gcc
mint:
@$(MAKE) $(LIBNAME) CC="gcc"
# Risc/OS 4: Use gcc
mipsbsd:
@$(MAKE) $(LIBNAME) CC="gcc"
# NeXT 3.0: Use cc
next:
@$(MAKE) $(LIBNAME) CMDC="-O2" CMDL="-object -s" CC="cc"
# OSF 1: Use gcc
osf1:
@$(MAKE) $(LIBNAME) CC="gcc"
# QNX 4.x: Use cc -ml, ld -N32768 -ml
qnx:
@$(MAKE) $(LIBNAME) CMDC="-ml" CMDL="-N32768 -ml" CC="cc"
# SCO: Use cc.
sco:
@$(MAKE) $(LIBNAME) CC="cc"
# Sun/Slowaris: Use gcc
sun:
@$(MAKE) $(LIBNAME) CC="gcc"
# SVR4: Use cc. Better results can be obtained by upgrading your OS to
# 4.4 BSD.
svr4:
@$(MAKE) $(LIBNAME) CC="cc"
# Ultrix: Use vcc or gcc
ultrix:
@$(MAKE) $(LIBNAME) CC="gcc"
# Amdahl UTS 4: Use cc
uts4:
@$(MAKE) $(LIBNAME) CMDC="-Xc", CC="cc"
#****************************************************************************
#* *
#* Cleanup after make has finished *
#* *
#****************************************************************************
clean:
rm -f *.o core testcrypt $(LIBNAME)
+540
View File
@@ -0,0 +1,540 @@
#include <string.h>
#ifdef _MSC_VER
#include "../crypt.h"
#include "shs.h"
#else
#include "crypt.h"
#include "mdc/shs.h"
#endif /* _MSC_VER */
/* The SHS f()-functions. The f1 and f3 functions can be optimized to
save one boolean operation each - thanks to Rich Schroeppel,
rcs@cs.arizona.edu for discovering this */
/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
/* The SHS Mysterious Constants */
#define K1 0x5A827999UL /* Rounds 0-19 */
#define K2 0x6ED9EBA1UL /* Rounds 20-39 */
#define K3 0x8F1BBCDCUL /* Rounds 40-59 */
#define K4 0xCA62C1D6UL /* Rounds 60-79 */
/* SHS initial values */
#define h0init 0x67452301UL
#define h1init 0xEFCDAB89UL
#define h2init 0x98BADCFEUL
#define h3init 0x10325476UL
#define h4init 0xC3D2E1F0UL
/* Note that it may be necessary to add parentheses to these macros if they
are to be called with expressions as arguments */
/* 32-bit rotate left - kludged with shifts */
#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
/* The initial expanding function. The hash function is defined over an
80-word expanded input array W, where the first 16 are copies of the input
data, and the remaining 64 are defined by
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
This implementation generates these values on the fly in a circular
buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
optimization.
The updated SHS changes the expanding function by adding a rotate of 1
bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
for this information */
#ifdef NEW_SHS
#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ i - 14 & 15 ] ^ \
W[ i - 8 & 15 ] ^ W[ i - 3 & 15 ] ) ) )
#else
#define expand(W,i) ( W[ i & 15 ] ^= W[ i - 14 & 15 ] ^ W[ i - 8 & 15 ] ^ W[ i - 3 & 15 ] )
#endif /* NEW_SHS */
/* The prototype SHS sub-round. The fundamental sub-round is:
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
b' = a;
c' = ROTL( 30, b );
d' = c;
e' = d;
but this is implemented by unrolling the loop 5 times and renaming the
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
This code is then replicated 20 times for each of the 4 functions, using
the next 20 values from the W[] array each time */
#ifdef _BIG_WORDS
#define subRound(a, b, c, d, e, f, k, data) \
e += ROTL( 5, a ) + f( b, c, d ) + k + data; \
e &= 0xFFFFFFFFUL; \
b = ROTL( 30, b ) & 0xFFFFFFFFUL
#else
#define subRound(a, b, c, d, e, f, k, data) \
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
#endif /* _BIG_WORDS */
/* Initialize the SHS values */
void shsInit( SHS_INFO *shsInfo )
{
/* Set the h-vars to their initial values */
shsInfo->digest[ 0 ] = h0init;
shsInfo->digest[ 1 ] = h1init;
shsInfo->digest[ 2 ] = h2init;
shsInfo->digest[ 3 ] = h3init;
shsInfo->digest[ 4 ] = h4init;
/* Initialise bit count */
shsInfo->countLo = shsInfo->countHi = 0;
}
#ifndef ASM_SHS
/* Perform the SHS transformation. Note that this code, like MD5, seems to
break some optimizing compilers due to the complexity of the expressions
and the size of the basic block. It may be necessary to split it into
sections, e.g. based on the four subrounds */
void SHSTransform( LONG *digest, LONG *data )
{
LONG A, B, C, D, E; /* Local vars */
LONG eData[ 16 ]; /* Expanded data */
int i;
/* Set up first buffer and local data buffer */
A = digest[ 0 ];
B = digest[ 1 ];
C = digest[ 2 ];
D = digest[ 3 ];
E = digest[ 4 ];
for( i = 0; i < 16; i++ )
eData[ i ] = data[ i ];
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
/* Build message digest */
#ifdef _BIG_WORDS
digest[ 0 ] = ( digest[ 0 ] + A ) & 0xFFFFFFFFUL;
digest[ 1 ] = ( digest[ 1 ] + B ) & 0xFFFFFFFFUL;
digest[ 2 ] = ( digest[ 2 ] + C ) & 0xFFFFFFFFUL;
digest[ 3 ] = ( digest[ 3 ] + D ) & 0xFFFFFFFFUL;
digest[ 4 ] = ( digest[ 4 ] + E ) & 0xFFFFFFFFUL;
#else
digest[ 0 ] += A;
digest[ 1 ] += B;
digest[ 2 ] += C;
digest[ 3 ] += D;
digest[ 4 ] += E;
#endif /* _BIG_WORDS */
}
#else
void SHSTransform( LONG *digest, LONG *data );
#endif /* !ASM_SHS */
#ifdef TEST_SHS
/* When run on a little-endian CPU we need to perform byte reversal on an
array of longwords. It is possible to make the code endianness-
independant by fiddling around with data at the byte level, but this
makes for very slow code, so we rely on the user to sort out endianness
at compile time */
#if defined( LITTLE_ENDIAN )
void longReverse( LONG *buffer, int byteCount )
{
LONG value;
byteCount /= sizeof( LONG );
while( byteCount-- )
{
value = *buffer;
value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
( ( value & 0x00FF00FFL ) << 8 );
*buffer++ = ( value << 16 ) | ( value >> 16 );
}
}
#else
#define longReverse(buf, count)
#endif /* LITTLE_ENDIAN */
#endif /* TEST_SHS */
#ifdef _BIG_WORDS
/* When run on a CPU with > 32 bit word size, we need to move the data from
the byte-aligned buffer to the final word-aligned data buffer. We perform
the endianness-reversal at the same time */
static void extractData( SHS_INFO *shsInfo )
{
BYTE *bufferPtr = shsInfo->dataBuffer;
int i;
for( i = 0; i < 16; i++ )
{
shsInfo->data[ i ] = ( ( LONG ) bufferPtr[ 0 ] << 24 ) | \
( ( LONG ) bufferPtr[ 1 ] << 16 ) | \
( ( LONG ) bufferPtr[ 2 ] << 8 ) | \
( ( LONG ) bufferPtr[ 3 ] );
bufferPtr += 4;
}
}
#endif /* _BIG_WORDS */
/* Update SHS for a block of data */
void shsUpdate( SHS_INFO *shsInfo, BYTE *buffer, int count )
{
LONG tmp;
int dataCount;
/* Update bitcount */
tmp = shsInfo->countLo;
if ( ( shsInfo->countLo = tmp + ( ( LONG ) count << 3 ) ) < tmp )
shsInfo->countHi++; /* Carry from low to high */
shsInfo->countHi += count >> 29;
/* Get count of bytes already in data */
dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
/* Handle any leading odd-sized chunks */
if( dataCount )
{
#ifdef _BIG_WORDS
BYTE *p = shsInfo->dataBuffer + dataCount;
#else
BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
#endif /* _BIG_WORDS */
dataCount = SHS_DATASIZE - dataCount;
if( count < dataCount )
{
memcpy( p, buffer, count );
return;
}
memcpy( p, buffer, dataCount );
#ifdef _BIG_WORDS
extractData( shsInfo );
#else
longReverse( shsInfo->data, SHS_DATASIZE );
#endif /* _BIG_WORDS */
SHSTransform( shsInfo->digest, shsInfo->data );
buffer += dataCount;
count -= dataCount;
}
/* Process data in SHS_DATASIZE chunks */
while( count >= SHS_DATASIZE )
{
#ifdef _BIG_WORDS
memcpy( shsInfo->dataBuffer, buffer, SHS_DATASIZE );
extractData( shsInfo );
#else
memcpy( shsInfo->data, buffer, SHS_DATASIZE );
longReverse( shsInfo->data, SHS_DATASIZE );
#endif /* _BIG_WORDS */
SHSTransform( shsInfo->digest, shsInfo->data );
buffer += SHS_DATASIZE;
count -= SHS_DATASIZE;
}
/* Handle any remaining bytes of data. */
#ifdef _BIG_WORDS
memcpy( shsInfo->dataBuffer, buffer, count );
#else
memcpy( shsInfo->data, buffer, count );
#endif /* _BIG_WORDS */
}
/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
1 0* (64-bit count of bits processed, MSB-first) */
void shsFinal( SHS_INFO *shsInfo )
{
int count;
BYTE *dataPtr;
/* Compute number of bytes mod 64 */
count = ( int ) shsInfo->countLo;
count = ( count >> 3 ) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
#ifdef _BIG_WORDS
dataPtr = shsInfo->dataBuffer + count;
#else
dataPtr = ( BYTE * ) shsInfo->data + count;
#endif /* _BIG_WORDS */
*dataPtr++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = SHS_DATASIZE - 1 - count;
/* Pad out to 56 mod 64 */
if( count < 8 )
{
/* Two lots of padding: Pad the first block to 64 bytes */
memset( dataPtr, 0, count );
#ifdef _BIG_WORDS
extractData( shsInfo );
#else
longReverse( shsInfo->data, SHS_DATASIZE );
#endif /* _BIG_WORDS */
SHSTransform( shsInfo->digest, shsInfo->data );
/* Now fill the next block with 56 bytes */
#ifdef _BIG_WORDS
memset( shsInfo->dataBuffer, 0, SHS_DATASIZE - 8 );
#else
memset( shsInfo->data, 0, SHS_DATASIZE - 8 );
#endif /* _BIG_WORDS */
}
else
/* Pad block to 56 bytes */
memset( dataPtr, 0, count - 8 );
#ifdef _BIG_WORDS
extractData( shsInfo );
#endif /* _BIG_WORDS */
/* Append length in bits and transform */
shsInfo->data[ 14 ] = shsInfo->countHi;
shsInfo->data[ 15 ] = shsInfo->countLo;
#ifndef _BIG_WORDS
longReverse( shsInfo->data, SHS_DATASIZE - 8 );
#endif /* _BIG_WORDS */
SHSTransform( shsInfo->digest, shsInfo->data );
}
/****************************************************************************
* *
* SHS Test Code *
* *
****************************************************************************/
#ifdef TEST_SHS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Defines for the standalone test version */
#define ERROR -1
#define OK 0
/* Test the SHS implementation */
#ifdef NEW_SHS
static LONG shsTestResults[][ 5 ] = {
{ 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, },
{ 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, },
{ 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, }
};
#else
static LONG shsTestResults[][ 5 ] = {
{ 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L },
{ 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L },
{ 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L }
};
#endif /* NEW_SHS */
static int compareSHSresults( SHS_INFO *shsInfo, int shsTestLevel )
{
int i;
/* Compare the returned digest and required values */
for( i = 0; i < 5; i++ )
if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] )
return( ERROR );
return( OK );
}
void main( void )
{
SHS_INFO shsInfo;
unsigned int i;
time_t secondCount;
BYTE data[ 200 ];
/* Make sure we've got the endianness set right. If the machine is
big-endian (up to 64 bits) the following value will be signed,
otherwise it will be unsigned. Unfortunately we can't test for odd
things like middle-endianness without knowing the size of the data
types */
#ifdef LITTLE_ENDIAN
if( *( long * ) "\x80\x00\x00\x00\x00\x00\x00\x00" < 0 )
{
puts( "Error: Comment out the LITTLE_ENDIAN define in SHS.H and recompile" );
exit( ERROR );
}
#else
if( *( long * ) "\x80\x00\x00\x00\x00\x00\x00\x00" >= 0 )
{
puts( "Error: Uncomment the LITTLE_ENDIAN define in SHS.H and recompile" );
exit( ERROR );
}
#endif /* LITTLE_ENDIAN */
/* Test SHS against values given in SHS standards document */
printf( "Running SHS test 1 ... " );
shsInit( &shsInfo );
shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 0 ) == ERROR )
{
putchar( '\n' );
puts( "SHS test 1 failed" );
exit( ERROR );
}
#ifdef NEW_SHS
puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" );
#else
puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" );
#endif /* NEW_SHS */
printf( "Running SHS test 2 ... " );
shsInit( &shsInfo );
shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 1 ) == ERROR )
{
putchar( '\n' );
puts( "SHS test 2 failed" );
exit( ERROR );
}
#ifdef NEW_SHS
puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" );
#else
puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" );
#endif /* NEW_SHS */
printf( "Running SHS test 3 ... " );
shsInit( &shsInfo );
for( i = 0; i < 15625; i++ )
shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
shsFinal( &shsInfo );
if( compareSHSresults( &shsInfo, 2 ) == ERROR )
{
putchar( '\n' );
puts( "SHS test 3 failed" );
exit( ERROR );
}
#ifdef NEW_SHS
puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" );
#else
puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" );
#endif /* NEW_SHS */
printf( "\nTesting speed for 10MB data... " );
shsInit( &shsInfo );
secondCount = time( NULL );
for( i = 0; i < 50000U; i++ )
shsUpdate( &shsInfo, data, 200 );
secondCount = time( NULL ) - secondCount;
printf( "done. Time = %ld seconds, %ld kbytes/second\n", \
secondCount, 10050L / secondCount );
puts( "\nAll SHS tests passed" );
exit( OK );
}
#endif /* TEST_SHS */
+35
View File
@@ -0,0 +1,35 @@
#ifndef _SHS_DEFINED
#define _SHS_DEFINED
/* Define the following to compile the SHS test code */
/*#define TEST_SHS*/
/* Define the following to use the updated SHS implementation */
/*#define NEW_SHS*/
/* The SHS block size and message digest sizes, in bytes */
#define SHS_DATASIZE 64
#define SHS_DIGESTSIZE 20
/* The structure for storing SHS info */
typedef struct {
LONG digest[ 5 ]; /* Message digest */
LONG countLo, countHi; /* 64-bit bit count */
LONG data[ 16 ]; /* SHS data buffer */
#ifdef _BIG_WORDS
BYTE dataBuffer[ SHS_DATASIZE ]; /* Byte buffer for data */
#endif /* _BIG_WORDS */
} SHS_INFO;
/* Message digest functions */
void shsInit( SHS_INFO *shsInfo );
void shsUpdate( SHS_INFO *shsInfo, BYTE *buffer, int count );
void shsFinal( SHS_INFO *shsInfo );
#endif /* _SHS_DEFINED */
+137
View File
@@ -0,0 +1,137 @@
; Simple RC4 implementation, Peter Gutmann, 21 September 1995.
; This code was written in about 30 minutes as a testbed for an asm.RC4. It
; uses a static data area as the key so it's not terribly practical as it
; stands. In addition, the RC4 algorithm leads to an almost solid block of
; pipeline stalls on anything >= '486, so I wouldn't recommend using it on
; anything except perhaps 8-bit microcontrollers and smart cards.
INCLUDE MISC.INC
MODULE RC4
PUBLIC _rc4expandKey, _rc4crypt
DATA
; The RC4 keying information
rc4key DB 256 DUP (?)
rc4x DB 0
rc4y DB 0
CODE
; void rc4ExpandKey( unsigned char const *key, int keylen )
_rc4expandKey PROCEDURE
push bp
mov bp, sp
push si
push di ; Save register vars
les si, [bp+4] ; ES:SI = key
mov dx, [bp+8] ; DX = keylen
mov dh, dl ; keylenTmp = keylen
; rc4word y = 0;
xor ax, ax ; y = 0
sub di, di ; DI = AX as an index register
; for( x = 0; x < 256; x++ )
; rc4key[ x ] = x;
xor bx, bx ; x = 0
@@initLoop:
mov rc4key[bx], bl ; rc4key[ x ] = x
inc bl ; x++
jnz SHORT @@initLoop
; for( x = 0; x < 256; x++ )
; {
; sx = rc4key[ x ];
; y += sx + key[ keypos ];
; rc4key[ x ] = rc4key[ y ];
; rc4key[ y ] = sx;
;
; if( ++keypos == keylen )
; keypos = 0;
; }
@@keyLoop:
mov cl, rc4key[bx] ; sx = rc4key[ x ]
add al, es:[si] ; y += key[ keypos ]
add al, cl ; y += sx
mov di, ax
mov ch, rc4key[di] ; temp = rc4key[ y ]
mov rc4key[bx], ch ; rc4key[ x ] = temp
mov rc4key[di], cl ; rc4key[ y ] = sx
inc si ; ++keypos
dec dh ; keylenTmp--
jnz SHORT @@noResetKeypos ; if( !keylenTmp )
sub si, dx ; keypos = 0
mov dh, dl ; keylenTmp = keylen
@@noResetKeypos:
inc bl ; x++
jnz SHORT @@keyLoop
; rc4->x = rc4->y = 0;
mov rc4x, bl ; rc4->x = 0
mov rc4y, bl ; rc4->y = 0
pop di
pop si ; Restore register vars
pop bp
ret
_rc4expandKey ENDP
; void rc4Crypt( unsigned char *data, int len )
_rc4crypt PROCEDURE
push bp
mov bp, sp
push si
push di ; Save register vars
les si, [bp+4] ; ES:SI = data
mov dx, [bp+8] ; DX = len
test dx, dx ; Check that len != 0
jz SHORT @@exit ; Yes, exit now
xor bx, bx
mov bl, rc4x ; BX = rc4x
xor ax, ax
mov al, rc4y ; AX = rc4y
xor di, di ; DI = AX as an index register
; while( len-- )
; {
; x++;
; sx = rc4key[ x ];
; y += sx;
; sy = rc4key[ y ];
; rc4key[ y ] = sx;
; rc4key[ x ] = sy;
; *data++ ^= rc4key[ ( sx + sy ) & 0xFF ];
; }
@@rc4loop:
inc bl ; x++
mov cl, rc4key[bx] ; sx = rc4key[ x ]
add al, cl ; y += sx
mov di, ax
mov ch, rc4key[di] ; sy = rc4key[ y ]
mov rc4key[di], cl ; rc4key[ y ] = sx
mov rc4key[bx], ch ; rc4key[ x ] = sy
add cl, ch
xor ch, ch
mov di, cx ; temp = ( sx + sy ) & 0xFF
mov cl, rc4key[di]
xor es:[si], cl ; *data ^= rc4key[ temp ]
inc si ; data++
dec dx ; len--
jnz SHORT @@rc4loop
mov rc4x, bl
mov rc4y, al ; Remember x and y values
@@exit:
pop di
pop si ; Restore register vars
pop bp
ret
_rc4crypt ENDP
ENDMODULE
+65
View File
@@ -0,0 +1,65 @@
/* Optimized RC4 code, from an unknown source ("and they knew not from whence
it had come...") */
#ifdef _MSC_VER
#include "rc4.h"
#else
#include "rc4/rc4.h"
#endif /* _MSC_VER */
void rc4ExpandKey( RC4KEY *rc4, unsigned char const *key, int keylen )
{
int x, keypos = 0;
rc4word sx, y = 0;
rc4word *state = &rc4->state[ 0 ];
rc4->x = rc4->y = 0;
for( x = 0; x < 256; x++ )
state[ x ] = x;
for( x = 0; x < 256; x++ )
{
sx = state[ x ];
y += sx + key[ keypos ];
#ifdef USE_LONG_RC4
y &= 0xFF;
#endif /* USE_LONG_RC4 */
state[ x ] = state[ y ];
state[ y ] = sx;
if( ++keypos == keylen )
keypos = 0;
}
}
void rc4Crypt( RC4KEY *rc4, unsigned char *data, int len )
{
rc4word x = rc4->x, y = rc4->y;
rc4word sx, sy;
rc4word *state = &rc4->state[ 0 ];
while (len--) {
x++;
#ifdef USE_LONG_RC4
x &= 0xFF;
#endif /* USE_LONG_RC4 */
sx = state[ x ];
y += sx;
#ifdef USE_LONG_RC4
y &= 0xFF;
#endif /* USE_LONG_RC4 */
sy = state[ y ];
state[ y ] = sx;
state[ x ] = sy;
#ifdef USE_LONG_RC4
*data++ ^= state[ ( unsigned char ) ( sx+sy ) ];
#else
*data++ ^= state[ ( sx+sy ) & 0xFF ];
#endif /* USE_LONG_RC4 */
}
rc4->x = x;
rc4->y = y;
}
+23
View File
@@ -0,0 +1,23 @@
#include <limits.h>
/* If the system can handle byte ops, we use those so we don't have to do a
lot of masking. Otherwise, we use machine-word-size ops which will be
faster on RISC machines */
#if UINT_MAX > 0xFFFFL /* System has 32-bit ints */
#define USE_LONG_RC4
typedef unsigned int rc4word;
#else
typedef unsigned char rc4word;
#endif /* UINT_MAX > 0xFFFFL */
/* The scheduled RC4 key */
typedef struct {
rc4word state[ 256 ];
rc4word x, y;
} RC4KEY ;
void rc4ExpandKey( RC4KEY *rc4, unsigned char const *key, int keylen );
void rc4Crypt( RC4KEY *rc4, unsigned char *data, int len );
+203
View File
@@ -0,0 +1,203 @@
/*******************************************************************************
*
* FILE: safer.c
*
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
* Routine) in its four versions: SAFER K-64, SAFER K-128,
* SAFER SK-64 and SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
/******************* External Headers *****************************************/
/******************* Local Headers ********************************************/
#ifdef _MSC_VER
#include "safer.h"
#else
#include "safer/safer.h"
#endif /* _MSC_VER */
/******************* Constants ************************************************/
#define TAB_LEN 256
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
#define ROL(x, n) ((unsigned char)(((unsigned int)(x) << (n))\
|((unsigned int)((x) & 0xFF) >> (8 - (n)))))
#define EXP(x) exp_tab[(x) & 0xFF]
#define LOG(x) log_tab[(x) & 0xFF]
#define PHT(x, y) { y += x; x += y; }
#define IPHT(x, y) { x -= y; y -= x; }
/******************* Types ****************************************************/
static unsigned char exp_tab[TAB_LEN];
static unsigned char log_tab[TAB_LEN];
/******************* Module Data **********************************************/
static int init_called = 0;
/******************* Functions ************************************************/
/******************************************************************************/
#ifndef NOT_ANSI_C
void Safer_Init_Module(void)
#else
Safer_Init_Module()
#endif
{ unsigned int i, exp;
if (init_called) return;
exp = 1;
for (i = 0; i < TAB_LEN; i++)
{
exp_tab[i] = (unsigned char)(exp & 0xFF);
log_tab[exp_tab[i]] = (unsigned char)i;
exp = exp * 45 % 257;
}
init_called = 1;
} /* Safer_Init_Module */
/******************************************************************************/
#ifndef NOT_ANSI_C
void Safer_Expand_Userkey(safer_block_t userkey_1,
safer_block_t userkey_2,
unsigned int nof_rounds,
int strengthened,
safer_key_t key)
#else
Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key)
safer_block_t userkey_1;
safer_block_t userkey_2;
unsigned int nof_rounds;
int strengthened;
safer_key_t key;
#endif
{ unsigned int i, j;
unsigned char ka[SAFER_BLOCK_LEN + 1];
unsigned char kb[SAFER_BLOCK_LEN + 1];
if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
nof_rounds = SAFER_MAX_NOF_ROUNDS;
*key++ = (unsigned char)nof_rounds;
ka[SAFER_BLOCK_LEN] = 0;
kb[SAFER_BLOCK_LEN] = 0;
for (j = 0; j < SAFER_BLOCK_LEN; j++)
{
ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL(userkey_1[j], 5);
kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey_2[j];
}
for (i = 1; i <= nof_rounds; i++)
{
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
{
ka[j] = ROL(ka[j], 6);
kb[j] = ROL(kb[j], 6);
}
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ = (ka[(j + 2 * i - 1) % (SAFER_BLOCK_LEN + 1)]
+ exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF;
else
*key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF;
for (j = 0; j < SAFER_BLOCK_LEN; j++)
if (strengthened)
*key++ = (kb[(j + 2 * i) % (SAFER_BLOCK_LEN + 1)]
+ exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF;
else
*key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF;
}
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
ka[j] = kb[j] = 0;
} /* Safer_Expand_Userkey */
/******************************************************************************/
#ifndef NOT_ANSI_C
void Safer_Encrypt_Block(safer_block_t block_in, safer_key_t key,
safer_block_t block_out)
#else
Safer_Encrypt_Block(block_in, key, block_out)
safer_block_t block_in;
safer_key_t key;
safer_block_t block_out;
#endif
{ unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS;
while(round--)
{
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
a = EXP(a) + *++key; b = LOG(b) ^ *++key;
c = LOG(c) ^ *++key; d = EXP(d) + *++key;
e = EXP(e) + *++key; f = LOG(f) ^ *++key;
g = LOG(g) ^ *++key; h = EXP(h) + *++key;
PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h);
PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h);
PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h);
t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
}
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
} /* Safer_Encrypt_Block */
/******************************************************************************/
#ifndef NOT_ANSI_C
void Safer_Decrypt_Block(safer_block_t block_in, safer_key_t key,
safer_block_t block_out)
#else
Safer_Decrypt_Block(block_in, key, block_out)
safer_block_t block_in;
safer_key_t key;
safer_block_t block_out;
#endif
{ unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS;
key += SAFER_BLOCK_LEN * (1 + 2 * round);
h ^= *key; g -= *--key; f -= *--key; e ^= *--key;
d ^= *--key; c -= *--key; b -= *--key; a ^= *--key;
while (round--)
{
t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h);
IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h);
IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h);
h -= *--key; g ^= *--key; f ^= *--key; e -= *--key;
d -= *--key; c ^= *--key; b ^= *--key; a -= *--key;
h = LOG(h) ^ *--key; g = EXP(g) - *--key;
f = EXP(f) - *--key; e = LOG(e) ^ *--key;
d = LOG(d) ^ *--key; c = EXP(c) - *--key;
b = EXP(b) - *--key; a = LOG(a) ^ *--key;
}
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
} /* Safer_Decrypt_Block */
/******************************************************************************/
+114
View File
@@ -0,0 +1,114 @@
/*******************************************************************************
*
* FILE: safer.h
*
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
* Routine) in its four versions: SAFER K-64, SAFER K-128,
* SAFER SK-64 and SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
#ifndef SAFER_H
#define SAFER_H
/******************* External Headers *****************************************/
/******************* Local Headers ********************************************/
/******************* Constants ************************************************/
#define SAFER_K64_DEFAULT_NOF_ROUNDS 6
#define SAFER_K128_DEFAULT_NOF_ROUNDS 10
#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8
#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10
#define SAFER_MAX_NOF_ROUNDS 13
#define SAFER_BLOCK_LEN 8
#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS))
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
/******************* Types ****************************************************/
typedef unsigned char safer_block_t[SAFER_BLOCK_LEN];
typedef unsigned char safer_key_t[SAFER_KEY_LEN];
/******************* Module Data **********************************************/
/******************* Prototypes ***********************************************/
/*******************************************************************************
* void Safer_Init_Module(void)
*
* initializes this module.
*
********************************************************************************
* void Safer_Expand_Userkey(safer_block_t userkey_1,
* safer_block_t userkey_2,
* unsigned int nof_rounds,
* int strengthened,
* safer_key_t key)
*
* expands a user-selected key of length 64 bits or 128 bits to a encryption /
* decryption key. If your user-selected key is of length 64 bits, then give
* this key to both arguments 'userkey_1' and 'userkey_2', e.g.
* 'Safer_Expand_Userkey(z, z, key)'. Note: SAFER K-64 and SAFER SK-64 with a
* user-selected key 'z' of length 64 bits are identical to SAFER K-128 and
* SAFER SK-128 with a user-selected key 'z z' of length 128 bits,
* respectively.
* pre: 'userkey_1' contains the first 64 bits of user key.
* 'userkey_2' contains the second 64 bits of user key.
* 'nof_rounds' contains the number of encryption rounds
* 'nof_rounds' <= 'SAFER_MAX_NOF_ROUNDS'
* 'strengthened' is non-zero if the strengthened key schedule should be
* used and zero if the original key schedule should be
* used.
* post: 'key' contains the expanded key.
*
********************************************************************************
* void Safer_Encrypt_Block(safer_block_t block_in, safer_key_t key,
* safer_block_t block_out)
*
* encryption algorithm.
* pre: 'block_in' contains the plain-text block.
* 'key' contains the expanded key.
* post: 'block_out' contains the cipher-text block.
*
********************************************************************************
* void Safer_Decrypt_Block(safer_block_t block_in, safer_key_t key,
* safer_block_t block_out)
*
* decryption algorithm.
* pre: 'block_in' contains the cipher-text block.
* 'key' contains the expanded key.
* post: 'block_out' contains the plain-text block.
*
*******************************************************************************/
#ifndef NOT_ANSI_C
extern void Safer_Init_Module(void);
extern void Safer_Expand_Userkey(safer_block_t userkey_1,
safer_block_t userkey_2,
unsigned int nof_rounds,
int strengthened,
safer_key_t key);
extern void Safer_Encrypt_Block (safer_block_t block_in, safer_key_t key,
safer_block_t block_out);
extern void Safer_Decrypt_Block (safer_block_t block_in, safer_key_t key,
safer_block_t block_out);
#else
Safer_Init_Module();
Safer_Expand_Userkey();
Safer_Encrypt_Block();
Safer_Decrypt_Block();
#endif
/******************************************************************************/
#endif /* SAFER_H */
+519
View File
@@ -0,0 +1,519 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "crypt.h"
/* The size of the test buffers */
#define TESTBUFFER_SIZE 256
/* Work routines: Set a pair of encrypt/decrypt buffers to a known state,
and make sure they're still in that known state */
static void initTestBuffers( BYTE *buffer1, BYTE *buffer2 )
{
/* Set the buffers to a known state */
memset( buffer1, '*', TESTBUFFER_SIZE );
memcpy( buffer1, "12345678", 8 ); /* For endianness check */
memcpy( buffer2, buffer1, TESTBUFFER_SIZE );
}
static void checkTestBuffers( BYTE *buffer1, BYTE *buffer2 )
{
/* Make sure everything went OK */
if( memcmp( buffer1, buffer2, TESTBUFFER_SIZE ) )
{
puts( "Warning: Decrypted data != original plaintext." );
/* Try and guess at block chaining problems */
if( !memcmp( buffer1, "12345678****", 12 ) )
puts( "\t It looks like there's a problem with block chaining." );
else
/* Try and guess at endianness problems - we want "1234" */
if( !memcmp( buffer1, "4321", 4 ) )
puts( "\t It looks like the 32-bit word endianness is "
"reversed." );
else
if( !memcmp( buffer1, "2143", 4 ) )
puts( "\t It looks like the 16-bit word endianness is "
"reversed." );
else
if( buffer1[ 0 ] >= '1' && buffer1[ 0 ] <= '9' )
puts( "\t It looks like there's some sort of endianness "
"problem which is\n\t more complex than just a "
"reversal." );
else
puts( "\t It's probably more than just an endianness "
"problem." );
}
}
/* Report information on the encryption algorithm */
static void reportAlgorithmInformation( char *algorithmName,
CRYPT_QUERY_INFO *cryptQueryInfo )
{
char speedFactor[ 50 ];
/* Determine the speed factor relative to a block copy */
if( cryptQueryInfo->speed == CRYPT_ERROR )
strcpy( speedFactor, "unknown speed factor" );
else
sprintf( speedFactor, "0.%03d times the speed of a block copy",
cryptQueryInfo->speed );
printf( "%s algorithm is available with\n"
" name `%s', block size %d bits, %s,\n"
" min key size %d bits, recommended key size %d bits, "
"max key size %d bits,\n"
" min IV size %d bits, recommended IV size %d bits, "
"max IV size %d bits.\n",
algorithmName, cryptQueryInfo->algoName,
bytesToBits( cryptQueryInfo->blockSize ), speedFactor,
bytesToBits( cryptQueryInfo->minKeySize ),
bytesToBits( cryptQueryInfo->keySize ),
bytesToBits( cryptQueryInfo->maxKeySize ),
bytesToBits( cryptQueryInfo->minIVsize ),
bytesToBits( cryptQueryInfo->ivSize ),
bytesToBits( cryptQueryInfo->maxIVsize ) );
}
/* Check the library for an algorithm/mode */
static BOOLEAN checkLibraryInfo( char *name, char *longName,
CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode )
{
CRYPT_QUERY_INFO cryptQueryInfo;
int status;
status = queryAlgoAvailability( cryptAlgo );
if( isStatusError( status ) )
{
printf( "queryAlgoAvailability() reports %s is not available: "
"Code %d.\n", name, status );
return( FALSE );
}
status = queryModeAvailability( cryptAlgo, cryptMode );
if( isStatusError( status ) )
{
printf( "queryModeAvailability() reports %s is not available: "
"Code %d.\n", longName, status );
return( FALSE );
}
status = queryAlgoModeInformation( cryptAlgo, cryptMode, &cryptQueryInfo );
printf( "queryModeAvailability() reports " );
if( isStatusOK( status ) )
reportAlgorithmInformation( longName, &cryptQueryInfo );
else
{
printf( "no information available on %s algorithm: Code %d.\n",
name, status );
return( FALSE );
}
return( TRUE );
}
/* Load the encryption contexts */
static BOOLEAN loadContexts( CRYPT_INFO *cryptInfo, CRYPT_INFO *decryptInfo,
CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode,
BYTE *key, int length )
{
int status;
/* Create the encryption context */
status = initCryptContext( cryptInfo, cryptAlgo, cryptMode );
if( isStatusError( status ) )
{
printf( "initCryptContext(): Failed with error code %d.\n", status );
return( FALSE );
}
status = loadCryptContext( cryptInfo, key, length );
if( isStatusError( status ) )
{
printf( "loadCryptContext(): Failed with error code %d.\n", status );
return( FALSE );
}
/* Create the decryption context */
status = initCryptContext( decryptInfo, cryptAlgo, cryptMode );
if( isStatusError( status ) )
{
printf( "initCryptContext(): Failed with error code %d.\n", status );
return( FALSE );
}
status = loadCryptContext( decryptInfo, key, length );
if( isStatusError( status ) )
{
printf( "loadCryptContext(): Failed with error code %d.\n", status );
return( FALSE );
}
return( TRUE );
}
/* Perform a test en/decryption */
static void testCrypt( CRYPT_INFO *cryptInfo, CRYPT_INFO *decryptInfo,
BYTE *buffer )
{
CRYPT_QUERY_INFO cryptQueryInfo;
BYTE iv[ 100 ];
int status;
/* Find out about the algorithm we're using */
queryContextInformation( cryptInfo, &cryptQueryInfo );
if( cryptQueryInfo.cryptMode == CRYPT_MODE_CFB ||
cryptQueryInfo.cryptMode == CRYPT_MODE_OFB ||
cryptQueryInfo.cryptMode == CRYPT_MODE_STREAM )
{
/* Encrypt the buffer in two odd-sized chunks */
status = encryptBuffer( cryptInfo, buffer, 79 );
if( isStatusError( status ) )
printf( "Couldn't encrypt data: Code %d.\n", status );
status = encryptBuffer( cryptInfo, buffer + 79, TESTBUFFER_SIZE - 79 );
if( isStatusError( status ) )
printf( "Couldn't encrypt data: Code %d.\n", status );
status = encryptBuffer( cryptInfo, buffer + TESTBUFFER_SIZE, 0 );
/* Copy the IV from the encryption to the decryption context */
status = retrieveIV( cryptInfo, iv );
if( isStatusError( status ) )
printf( "Couldn't retrieve IV after encryption: Code %d.\n",
status );
status = loadIV( decryptInfo, iv, cryptQueryInfo.ivSize );
if( isStatusError( status ) )
printf( "Couldn't load IV for decryption: Code %d.\n", status );
/* Decrypt the buffer in different odd-size chunks */
status = decryptBuffer( decryptInfo, buffer, 125 );
if( isStatusError( status ) )
printf( "Couldn't decrypt data: Code %d.\n", status );
status = decryptBuffer( decryptInfo, buffer + 125, TESTBUFFER_SIZE - 125 );
if( isStatusError( status ) )
printf( "Couldn't decrypt data: Code %d.\n", status );
return;
}
if( cryptQueryInfo.cryptMode == CRYPT_MODE_ECB ||
cryptQueryInfo.cryptMode == CRYPT_MODE_CBC ||
cryptQueryInfo.cryptMode == CRYPT_MODE_PCBC )
{
/* Encrypt the buffer in two odd-sized chunks */
status = encryptBuffer( cryptInfo, buffer, 80 );
if( isStatusError( status ) )
printf( "Couldn't encrypt data: Code %d.\n", status );
status = encryptBuffer( cryptInfo, buffer + 80, TESTBUFFER_SIZE - 80 );
if( isStatusError( status ) )
printf( "Couldn't encrypt data: Code %d.\n", status );
status = encryptBuffer( cryptInfo, buffer + TESTBUFFER_SIZE, 0 );
/* Copy the IV from the encryption to the decryption context */
status = retrieveIV( cryptInfo, iv );
if( isStatusError( status ) )
printf( "Couldn't retrieve IV after encryption: Code %d.\n",
status );
status = loadIV( decryptInfo, iv, cryptQueryInfo.ivSize );
if( isStatusError( status ) )
printf( "Couldn't load IV for decryption: Code %d.\n", status );
/* Decrypt the buffer in different odd-size chunks */
status = decryptBuffer( decryptInfo, buffer, 128 );
if( isStatusError( status ) )
printf( "Couldn't decrypt data: Code %d.\n", status );
status = decryptBuffer( decryptInfo, buffer + 128, TESTBUFFER_SIZE - 128 );
if( isStatusError( status ) )
printf( "Couldn't decrypt data: Code %d.\n", status );
return;
}
puts( "Unknown encryption mode found in test code." );
}
/* Destroy the encryption contexts */
static void destroyContexts( CRYPT_INFO *cryptInfo, CRYPT_INFO *decryptInfo )
{
int status;
status = destroyCryptContext( cryptInfo );
if( isStatusError( status ) )
printf( "destroyCryptContext(): Failed with error code %d.\n", status );
status = destroyCryptContext( decryptInfo );
if( isStatusError( status ) )
printf( "destroyCryptContext(): Failed with error code %d.\n", status );
}
/* Sample code to test an algorithm/mode implementation */
static int testLibrary( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode,
char *name, char *longName )
{
BYTE buffer[ TESTBUFFER_SIZE ], testBuffer[ TESTBUFFER_SIZE ];
CRYPT_INFO cryptInfo, decryptInfo;
CRYPT_INFO_MDCSHS cryptInfoEx;
int status;
/* Initialise the test buffers */
initTestBuffers( buffer, testBuffer );
/* Check the capabilities of the library */
putchar( '\n' );
if( !checkLibraryInfo( name, longName, cryptAlgo, cryptMode ) )
return( FALSE );
/* Set up an encryption context, load a user key into it, and perform a
key setup */
switch( cryptAlgo )
{
case CRYPT_ALGO_MDCSHS:
/* We use an extended setup with reduced iteration count for
people who have to run this thing 2000 times while debugging */
cryptInfoEx.keySetupIterations = 10;
status = initCryptContextEx( &cryptInfo, cryptAlgo, cryptMode,
&cryptInfoEx );
if( isStatusError( status ) )
{
printf( "initCryptContext(): Failed with error code %d.\n",
status );
return( FALSE );
}
status = loadCryptContext( &cryptInfo, "Test key", 8 );
if( isStatusError( status ) )
{
printf( "loadCryptContext(): Failed with error code %d.\n",
status );
return( FALSE );
}
/* Create another crypt context for decryption. The error
checking here is a bit less picky to save space */
cryptInfoEx.keySetupIterations = 10;
initCryptContextEx( &decryptInfo, cryptAlgo, cryptMode,
&cryptInfoEx );
status = loadCryptContext( &decryptInfo, "Test key", 8 );
if( isStatusError( status ) )
{
printf( "loadCryptContext(): Failed with error code %d.\n",
status );
return( FALSE );
}
break;
case CRYPT_ALGO_DES:
if( !loadContexts( &cryptInfo, &decryptInfo, cryptAlgo, cryptMode,
( BYTE * ) "1234567", 7 ) )
return( FALSE );
break;
case CRYPT_ALGO_3DES:
if( !loadContexts( &cryptInfo, &decryptInfo, cryptAlgo, cryptMode,
( BYTE * ) "12345677654321", 14 ) )
return( FALSE );
break;
case CRYPT_ALGO_IDEA:
if( !loadContexts( &cryptInfo, &decryptInfo, cryptAlgo, cryptMode,
( BYTE * ) "1234567887654321", 16 ) )
return( FALSE );
break;
case CRYPT_ALGO_RC4:
if( !loadContexts( &cryptInfo, &decryptInfo, cryptAlgo, cryptMode,
( BYTE * ) "12345678900987654321", 20 ) )
return( FALSE );
break;
case CRYPT_ALGO_SAFER:
if( !loadContexts( &cryptInfo, &decryptInfo, cryptAlgo, cryptMode,
( BYTE * ) "1234567887654321", 16 ) )
return( FALSE );
break;
default:
printf( "Unknown encryption algorithm = ID %d, cannot perform "
"encryption test\n", cryptAlgo );
return( FALSE );
}
/* Perform a test en/decryption */
testCrypt( &cryptInfo, &decryptInfo, buffer );
/* Make sure everything went OK */
checkTestBuffers( buffer, testBuffer );
/* Destroy the encryption contexts */
destroyContexts( &cryptInfo, &decryptInfo );
return( TRUE );
}
/* Exercise various aspects of the encryption library */
int main( int argc, char **argv )
{
int status, bigEndian;
/* Get rid of compiler warning */
if( argc || argv );
/* Make sure we've got the endianness set right. If the machine is
big-endian (up to 64 bits) the following value will be signed,
otherwise it will be unsigned. Unfortunately we can't test for
things like middle-endianness without knowing the size of the data
types */
bigEndian = ( *( long * ) "\x80\x00\x00\x00\x00\x00\x00\x00" < 0 );
#ifdef LITTLE_ENDIAN
if( bigEndian )
{
puts( "The CPU endianness define is set wrong in crypt.h, this "
"machine appears to be\nbig-endian, not little-endian. Edit "
"the file and rebuild the library." );
exit( EXIT_FAILURE );
}
#else
if( !bigEndian )
{
puts( "The CPU endianness define is set wrong in crypt.h, this "
"machine appears to be\nlittle-endian, not big-endian. Edit "
"the file and rebuild the library." );
exit( EXIT_FAILURE );
}
#endif /* LITTLE_ENDIAN */
/* If we're compiling under Windoze, make sure that this weeks version
of Visual C gets the LONG type right */
#ifdef __WINDOWS__
{
LONG test = 0x80000000L;
if( test < 0 )
{
puts( "typeof( LONG ) is incorrect. It evaluates to a signed 32-bit "
"value rather\nthan an unsigned 32-bit value. You need to edit "
"crypt.h and recompile the\nencryption library" );
exit( EXIT_FAILURE );
}
}
#endif /* __WINDOWS__ */
/* Initialise the library */
status = initLibrary();
if( isStatusError( status ) )
{
printf( "Couldn't init library, code %d.\n", status );
exit( EXIT_FAILURE );
}
/* Test the encryption routines contained in the library */
#if 1
if( !testLibrary( CRYPT_ALGO_MDCSHS, CRYPT_MODE_CFB, "MDC/SHS",
"MDC/SHS-CFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_DES, CRYPT_MODE_ECB, "DES", "DES-ECB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_DES, CRYPT_MODE_CBC, "DES", "DES-CBC" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_DES, CRYPT_MODE_CFB, "DES", "DES-CFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_DES, CRYPT_MODE_OFB, "DES", "DES-OFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_DES, CRYPT_MODE_PCBC, "DES", "DES-PCBC" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_3DES, CRYPT_MODE_ECB, "3DES", "3DES-ECB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_3DES, CRYPT_MODE_CBC, "3DES", "3DES-CBC" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_3DES, CRYPT_MODE_CFB, "3DES", "3DES-CFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_3DES, CRYPT_MODE_OFB, "3DES", "3DES-OFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_IDEA, CRYPT_MODE_ECB, "IDEA", "IDEA-ECB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_IDEA, CRYPT_MODE_CBC, "IDEA", "IDEA-CBC" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_IDEA, CRYPT_MODE_CFB, "IDEA", "IDEA-CFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_IDEA, CRYPT_MODE_OFB, "IDEA", "IDEA-OFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_RC4, CRYPT_MODE_STREAM, "RC4", "RC4" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_SAFER, CRYPT_MODE_ECB, "SAFER", "SAFER-ECB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_SAFER, CRYPT_MODE_CBC, "SAFER", "SAFER-CBC" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_SAFER, CRYPT_MODE_CFB, "SAFER", "SAFER-CFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
if( !testLibrary( CRYPT_ALGO_SAFER, CRYPT_MODE_OFB, "SAFER", "SAFER-OFB" ) )
{
puts( "Tests aborted due to encryption library error." );
exit( EXIT_FAILURE );
}
#endif /* 0 or 1 */
/* Shut down the library */
status = endLibrary();
if( isStatusError( status ) )
{
printf( "endLibrary(): Failed with error code %d.\n", status );
exit( EXIT_FAILURE );
}
return( EXIT_SUCCESS );
}
+928
View File
@@ -0,0 +1,928 @@
/* DES test vectors, derived from "Validating the Correctness of Hardware
Implementations of the NBS Data Encryption Standard", NBS Special
Publication 500-20, 1980 */
/* The data structure for the ( key, plaintext, ciphertext ) triplets. Each
set of tests also includes a string describing the test, suitable for
printing as "Testing <description string>" during the testing process */
typedef struct {
BYTE key[ DES_BLOCKSIZE ];
BYTE plaintext[ DES_BLOCKSIZE ];
BYTE ciphertext[ DES_BLOCKSIZE ];
} DES_TEST;
/* Initial Permutation and Expansion test: Encrypt */
static char *testIPname = "Initial Permutation and Expansion";
static DES_TEST testIP[] = {
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA },
{ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F },
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 },
{ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF },
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F },
{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 },
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A },
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x42, 0x42, 0x50, 0xB3, 0x7C, 0x3D, 0xD9, 0x51 },
{ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xB8, 0x06, 0x1B, 0x7E, 0xCD, 0x9A, 0x21, 0xE5 },
{ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xF1, 0x5D, 0x0F, 0x28, 0x6B, 0x65, 0xBD, 0x28 },
{ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xAD, 0xD0, 0xCC, 0x8D, 0x6E, 0x5D, 0xEB, 0xA1 },
{ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE6, 0xD5, 0xF8, 0x27, 0x52, 0xAD, 0x63, 0xD1 },
{ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xEC, 0xBF, 0xE3, 0xBD, 0x3F, 0x59, 0x1A, 0x5E },
{ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xF3, 0x56, 0x83, 0x43, 0x79, 0xD1, 0x65, 0xCD },
{ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x2B, 0x9F, 0x98, 0x2F, 0x20, 0x03, 0x7F, 0xA9 },
{ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x88, 0x9D, 0xE0, 0x68, 0xA1, 0x6F, 0x0B, 0xE6 },
{ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE1, 0x9E, 0x27, 0x5D, 0x84, 0x6A, 0x12, 0x98 },
{ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x32, 0x9A, 0x8E, 0xD5, 0x23, 0xD7, 0x1A, 0xEC },
{ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE7, 0xFC, 0xE2, 0x25, 0x57, 0xD2, 0x3C, 0x97 },
{ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x12, 0xA9, 0xF5, 0x81, 0x7F, 0xF2, 0xD6, 0x5D },
{ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xA4, 0x84, 0xC3, 0xAD, 0x38, 0xDC, 0x9C, 0x19 },
{ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xFB, 0xE0, 0x0A, 0x8A, 0x1E, 0xF8, 0xAD, 0x72 },
{ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x75, 0x0D, 0x07, 0x94, 0x07, 0x52, 0x13, 0x63 },
{ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x64, 0xFE, 0xED, 0x9C, 0x72, 0x4C, 0x2F, 0xAF },
{ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xF0, 0x2B, 0x26, 0x3B, 0x32, 0x8E, 0x2B, 0x60 },
{ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x9D, 0x64, 0x55, 0x5A, 0x9A, 0x10, 0xB8, 0x52 },
{ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xD1, 0x06, 0xFF, 0x0B, 0xED, 0x52, 0x55, 0xD7 },
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE1, 0x65, 0x2C, 0x6B, 0x13, 0x8C, 0x64, 0xA5 },
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE4, 0x28, 0x58, 0x11, 0x86, 0xEC, 0x8F, 0x46 },
{ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xAE, 0xB5, 0xF5, 0xED, 0xE2, 0x2D, 0x1A, 0x36 },
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE9, 0x43, 0xD7, 0x56, 0x8A, 0xEC, 0x0C, 0x5C },
{ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xDF, 0x98, 0xC8, 0x27, 0x6F, 0x54, 0xB0, 0x4B },
{ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xB1, 0x60, 0xE4, 0x68, 0x0F, 0x6C, 0x69, 0x6F },
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xFA, 0x07, 0x52, 0xB0, 0x7D, 0x9C, 0x4A, 0xB8 },
{ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCA, 0x3A, 0x2B, 0x03, 0x6D, 0xBC, 0x85, 0x02 },
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x5E, 0x09, 0x05, 0x51, 0x7B, 0xB5, 0x9B, 0xCF },
{ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x81, 0x4E, 0xEB, 0x3B, 0x91, 0xD9, 0x07, 0x26 },
{ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x4D, 0x49, 0xDB, 0x15, 0x32, 0x91, 0x9C, 0x9F },
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x25, 0xEB, 0x5F, 0xC3, 0xF8, 0xCF, 0x06, 0x21 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xAB, 0x6A, 0x20, 0xC0, 0x62, 0x0D, 0x1C, 0x6F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x79, 0xE9, 0x0D, 0xBC, 0x98, 0xF9, 0x2C, 0xCA },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x86, 0x6E, 0xCE, 0xDD, 0x80, 0x72, 0xBB, 0x0E },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x8B, 0x54, 0x53, 0x6F, 0x2F, 0x3E, 0x64, 0xA8 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xEA, 0x51, 0xD3, 0x97, 0x55, 0x95, 0xB8, 0x6B },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCA, 0xFF, 0xC6, 0xAC, 0x45, 0x42, 0xDE, 0x31 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x8D, 0xD4, 0x5A, 0x2D, 0xDF, 0x90, 0x79, 0x6C },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x10, 0x29, 0xD5, 0x5E, 0x88, 0x0E, 0xC2, 0xD0 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x5D, 0x86, 0xCB, 0x23, 0x63, 0x9D, 0xBE, 0xA9 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x1D, 0x1C, 0xA8, 0x53, 0xAE, 0x7C, 0x0C, 0x5F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCE, 0x33, 0x23, 0x29, 0x24, 0x8F, 0x32, 0x28 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x84, 0x05, 0xD1, 0xAB, 0xE2, 0x4F, 0xB9, 0x42 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE6, 0x43, 0xD7, 0x80, 0x90, 0xCA, 0x42, 0x07 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x48, 0x22, 0x1B, 0x99, 0x37, 0x74, 0x8A, 0x23 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xDD, 0x7C, 0x0B, 0xBD, 0x61, 0xFA, 0xFD, 0x54 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x2F, 0xBC, 0x29, 0x1A, 0x57, 0x0D, 0xB5, 0xC4 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xE0, 0x7C, 0x30, 0xD7, 0xE4, 0xE2, 0x6E, 0x12 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x09, 0x53, 0xE2, 0x25, 0x8E, 0x8E, 0x90, 0xA1 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x5B, 0x71, 0x1B, 0xC4, 0xCE, 0xEB, 0xF2, 0xEE },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCC, 0x08, 0x3F, 0x1E, 0x6D, 0x9E, 0x85, 0xF6 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xD2, 0xFD, 0x88, 0x67, 0xD5, 0x0D, 0x2D, 0xFE },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x06, 0xE7, 0xEA, 0x22, 0xCE, 0x92, 0x70, 0x8F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x16, 0x6B, 0x40, 0xB4, 0x4A, 0xBA, 0x4B, 0xD6 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
};
/* Inverse Permutation and Expansion test: Encrypt */
static char *testVPname = "Inverse Permutation and Expansion";
static DES_TEST testVP[] = {
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x42, 0x42, 0x50, 0xB3, 0x7C, 0x3D, 0xD9, 0x51 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB8, 0x06, 0x1B, 0x7E, 0xCD, 0x9A, 0x21, 0xE5 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xF1, 0x5D, 0x0F, 0x28, 0x6B, 0x65, 0xBD, 0x28 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAD, 0xD0, 0xCC, 0x8D, 0x6E, 0x5D, 0xEB, 0xA1 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE6, 0xD5, 0xF8, 0x27, 0x52, 0xAD, 0x63, 0xD1 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xEC, 0xBF, 0xE3, 0xBD, 0x3F, 0x59, 0x1A, 0x5E } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xF3, 0x56, 0x83, 0x43, 0x79, 0xD1, 0x65, 0xCD } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x2B, 0x9F, 0x98, 0x2F, 0x20, 0x03, 0x7F, 0xA9 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x88, 0x9D, 0xE0, 0x68, 0xA1, 0x6F, 0x0B, 0xE6 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE1, 0x9E, 0x27, 0x5D, 0x84, 0x6A, 0x12, 0x98 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x32, 0x9A, 0x8E, 0xD5, 0x23, 0xD7, 0x1A, 0xEC } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE7, 0xFC, 0xE2, 0x25, 0x57, 0xD2, 0x3C, 0x97 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x12, 0xA9, 0xF5, 0x81, 0x7F, 0xF2, 0xD6, 0x5D } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA4, 0x84, 0xC3, 0xAD, 0x38, 0xDC, 0x9C, 0x19 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xFB, 0xE0, 0x0A, 0x8A, 0x1E, 0xF8, 0xAD, 0x72 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 },
{ 0x75, 0x0D, 0x07, 0x94, 0x07, 0x52, 0x13, 0x63 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00 },
{ 0x64, 0xFE, 0xED, 0x9C, 0x72, 0x4C, 0x2F, 0xAF } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 },
{ 0xF0, 0x2B, 0x26, 0x3B, 0x32, 0x8E, 0x2B, 0x60 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00 },
{ 0x9D, 0x64, 0x55, 0x5A, 0x9A, 0x10, 0xB8, 0x52 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 },
{ 0xD1, 0x06, 0xFF, 0x0B, 0xED, 0x52, 0x55, 0xD7 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 },
{ 0xE1, 0x65, 0x2C, 0x6B, 0x13, 0x8C, 0x64, 0xA5 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 },
{ 0xE4, 0x28, 0x58, 0x11, 0x86, 0xEC, 0x8F, 0x46 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 },
{ 0xAE, 0xB5, 0xF5, 0xED, 0xE2, 0x2D, 0x1A, 0x36 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },
{ 0xE9, 0x43, 0xD7, 0x56, 0x8A, 0xEC, 0x0C, 0x5C } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00 },
{ 0xDF, 0x98, 0xC8, 0x27, 0x6F, 0x54, 0xB0, 0x4B } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 },
{ 0xB1, 0x60, 0xE4, 0x68, 0x0F, 0x6C, 0x69, 0x6F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 },
{ 0xFA, 0x07, 0x52, 0xB0, 0x7D, 0x9C, 0x4A, 0xB8 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
{ 0xCA, 0x3A, 0x2B, 0x03, 0x6D, 0xBC, 0x85, 0x02 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 },
{ 0x5E, 0x09, 0x05, 0x51, 0x7B, 0xB5, 0x9B, 0xCF } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 },
{ 0x81, 0x4E, 0xEB, 0x3B, 0x91, 0xD9, 0x07, 0x26 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 },
{ 0x4D, 0x49, 0xDB, 0x15, 0x32, 0x91, 0x9C, 0x9F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 },
{ 0x25, 0xEB, 0x5F, 0xC3, 0xF8, 0xCF, 0x06, 0x21 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 },
{ 0xAB, 0x6A, 0x20, 0xC0, 0x62, 0x0D, 0x1C, 0x6F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 },
{ 0x79, 0xE9, 0x0D, 0xBC, 0x98, 0xF9, 0x2C, 0xCA } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 },
{ 0x86, 0x6E, 0xCE, 0xDD, 0x80, 0x72, 0xBB, 0x0E } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00 },
{ 0x8B, 0x54, 0x53, 0x6F, 0x2F, 0x3E, 0x64, 0xA8 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 },
{ 0xEA, 0x51, 0xD3, 0x97, 0x55, 0x95, 0xB8, 0x6B } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 },
{ 0xCA, 0xFF, 0xC6, 0xAC, 0x45, 0x42, 0xDE, 0x31 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 },
{ 0x8D, 0xD4, 0x5A, 0x2D, 0xDF, 0x90, 0x79, 0x6C } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00 },
{ 0x10, 0x29, 0xD5, 0x5E, 0x88, 0x0E, 0xC2, 0xD0 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00 },
{ 0x5D, 0x86, 0xCB, 0x23, 0x63, 0x9D, 0xBE, 0xA9 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00 },
{ 0x1D, 0x1C, 0xA8, 0x53, 0xAE, 0x7C, 0x0C, 0x5F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00 },
{ 0xCE, 0x33, 0x23, 0x29, 0x24, 0x8F, 0x32, 0x28 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 },
{ 0x84, 0x05, 0xD1, 0xAB, 0xE2, 0x4F, 0xB9, 0x42 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00 },
{ 0xE6, 0x43, 0xD7, 0x80, 0x90, 0xCA, 0x42, 0x07 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 },
{ 0x48, 0x22, 0x1B, 0x99, 0x37, 0x74, 0x8A, 0x23 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 },
{ 0xDD, 0x7C, 0x0B, 0xBD, 0x61, 0xFA, 0xFD, 0x54 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0x2F, 0xBC, 0x29, 0x1A, 0x57, 0x0D, 0xB5, 0xC4 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40 },
{ 0xE0, 0x7C, 0x30, 0xD7, 0xE4, 0xE2, 0x6E, 0x12 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 },
{ 0x09, 0x53, 0xE2, 0x25, 0x8E, 0x8E, 0x90, 0xA1 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 },
{ 0x5B, 0x71, 0x1B, 0xC4, 0xCE, 0xEB, 0xF2, 0xEE } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 },
{ 0xCC, 0x08, 0x3F, 0x1E, 0x6D, 0x9E, 0x85, 0xF6 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 },
{ 0xD2, 0xFD, 0x88, 0x67, 0xD5, 0x0D, 0x2D, 0xFE } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 },
{ 0x06, 0xE7, 0xEA, 0x22, 0xCE, 0x92, 0x70, 0x8F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0x16, 0x6B, 0x40, 0xB4, 0x4A, 0xBA, 0x4B, 0xD6 } }
};
/* Key Permutation tests: Encrypt */
static char *testKPname = "Key Permutation";
static DES_TEST testKP[] = {
{ { 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x95, 0xA8, 0xD7, 0x28, 0x13, 0xDA, 0xA9, 0x4D } },
{ { 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x0E, 0xEC, 0x14, 0x87, 0xDD, 0x8C, 0x26, 0xD5 } },
{ { 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x7A, 0xD1, 0x6F, 0xFB, 0x79, 0xC4, 0x59, 0x26 } },
{ { 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xD3, 0x74, 0x62, 0x94, 0xCA, 0x6A, 0x6C, 0xF3 } },
{ { 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x80, 0x9F, 0x5F, 0x87, 0x3C, 0x1F, 0xD7, 0x61 } },
{ { 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xC0, 0x2F, 0xAF, 0xFE, 0xC9, 0x89, 0xD1, 0xFC } },
{ { 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x46, 0x15, 0xAA, 0x1D, 0x33, 0xE7, 0x2F, 0x10 } },
{ { 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x20, 0x55, 0x12, 0x33, 0x50, 0xC0, 0x08, 0x58 } },
{ { 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xDF, 0x3B, 0x99, 0xD6, 0x57, 0x73, 0x97, 0xC8 } },
{ { 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x31, 0xFE, 0x17, 0x36, 0x9B, 0x52, 0x88, 0xC9 } },
{ { 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xDF, 0xDD, 0x3C, 0xC6, 0x4D, 0xAE, 0x16, 0x42 } },
{ { 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x17, 0x8C, 0x83, 0xCE, 0x2B, 0x39, 0x9D, 0x94 } },
{ { 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x50, 0xF6, 0x36, 0x32, 0x4A, 0x9B, 0x7F, 0x80 } },
{ { 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA8, 0x46, 0x8E, 0xE3, 0xBC, 0x18, 0xF0, 0x6D } },
{ { 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA2, 0xDC, 0x9E, 0x92, 0xFD, 0x3C, 0xDE, 0x92 } },
{ { 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xCA, 0xC0, 0x9F, 0x79, 0x7D, 0x03, 0x12, 0x87 } },
{ { 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x90, 0xBA, 0x68, 0x0B, 0x22, 0xAE, 0xB5, 0x25 } },
{ { 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xCE, 0x7A, 0x24, 0xF3, 0x50, 0xE2, 0x80, 0xB6 } },
{ { 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x88, 0x2B, 0xFF, 0x0A, 0xA0, 0x1A, 0x0B, 0x87 } },
{ { 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xC2 } },
{ { 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xC7, 0x15, 0x16, 0xC2, 0x9C, 0x75, 0xD1, 0x70 } },
{ { 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x51, 0x99, 0xC2, 0x9A, 0x52, 0xC9, 0xF0, 0x59 } },
{ { 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xC2, 0x2F, 0x0A, 0x29, 0x4A, 0x71, 0xF2, 0x9F } },
{ { 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xEE, 0x37, 0x14, 0x83, 0x71, 0x4C, 0x02, 0xEA } },
{ { 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA8, 0x1F, 0xBD, 0x44, 0x8F, 0x9E, 0x52, 0x2F } },
{ { 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x4F, 0x64, 0x4C, 0x92, 0xE1, 0x92, 0xDF, 0xED } },
{ { 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x1A, 0xFA, 0x9A, 0x66, 0xA6, 0xDF, 0x92, 0xAE } },
{ { 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB3, 0xC1, 0xCC, 0x71, 0x5C, 0xB8, 0x79, 0xD8 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x19, 0xD0, 0x32, 0xE6, 0x4A, 0xB0, 0xBD, 0x8B } },
{ { 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x3C, 0xFA, 0xA7, 0xA7, 0xDC, 0x87, 0x20, 0xDC } },
{ { 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB7, 0x26, 0x5F, 0x7F, 0x44, 0x7A, 0xC6, 0xF3 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x9D, 0xB7, 0x3B, 0x3C, 0x0D, 0x16, 0x3F, 0x54 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x81, 0x81, 0xB6, 0x5B, 0xAB, 0xF4, 0xA9, 0x75 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x93, 0xC9, 0xB6, 0x40, 0x42, 0xEA, 0xA2, 0x40 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x86, 0x38, 0x80, 0x9E, 0x87, 0x87, 0x87, 0xA0 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x41, 0xB9, 0xA7, 0x9A, 0xF7, 0x9A, 0xC2, 0x08 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x7A, 0x9B, 0xE4, 0x2F, 0x20, 0x09, 0xA8, 0x92 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x29, 0x03, 0x8D, 0x56, 0xBA, 0x6D, 0x27, 0x45 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x54, 0x95, 0xC6, 0xAB, 0xF1, 0xE5, 0xDF, 0x51 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAE, 0x13, 0xDB, 0xD5, 0x61, 0x48, 0x89, 0x33 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x4D, 0x1F, 0xFA, 0x89, 0x04, 0xE3, 0x89 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xD1, 0x39, 0x97, 0x12, 0xF9, 0x9B, 0xF0, 0x2E } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x14, 0xC1, 0xD7, 0xC1, 0xCF, 0xFE, 0xC7, 0x9E } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x1D, 0xE5, 0x27, 0x9D, 0xAE, 0x3B, 0xED, 0x6F } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE9, 0x41, 0xA3, 0x3F, 0x85, 0x50, 0x13, 0x03 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xDA, 0x99, 0xDB, 0xBC, 0x9A, 0x03, 0xF3, 0x79 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB7, 0xFC, 0x92, 0xF9, 0x1D, 0x8E, 0x92, 0xE9 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAE, 0x8E, 0x5C, 0xAA, 0x3C, 0xA0, 0x4E, 0x85 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x9C, 0xC6, 0x2D, 0xF4, 0x3B, 0x6E, 0xED, 0x74 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xD8, 0x63, 0xDB, 0xB5, 0xC5, 0x9A, 0x91, 0xA0 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA1, 0xAB, 0x21, 0x90, 0x54, 0x5B, 0x91, 0xD7 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x08, 0x75, 0x04, 0x1E, 0x64, 0xC5, 0x70, 0xF7 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x5A, 0x59, 0x45, 0x28, 0xBE, 0xBE, 0xF1, 0xCC } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xFC, 0xDB, 0x32, 0x91, 0xDE, 0x21, 0xF0, 0xC0 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x86, 0x9E, 0xFD, 0x7F, 0x9F, 0x26, 0x5A, 0x09 } }
};
/* Test of right-shifts in Decryption: Decrypt */
static char *testRSname = "Right-shifts in Decryption";
static DES_TEST testRS[] = {
{ { 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x95, 0xA8, 0xD7, 0x28, 0x13, 0xDA, 0xA9, 0x4D },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x0E, 0xEC, 0x14, 0x87, 0xDD, 0x8C, 0x26, 0xD5 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x7A, 0xD1, 0x6F, 0xFB, 0x79, 0xC4, 0x59, 0x26 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xD3, 0x74, 0x62, 0x94, 0xCA, 0x6A, 0x6C, 0xF3 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x80, 0x9F, 0x5F, 0x87, 0x3C, 0x1F, 0xD7, 0x61 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xC0, 0x2F, 0xAF, 0xFE, 0xC9, 0x89, 0xD1, 0xFC },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x46, 0x15, 0xAA, 0x1D, 0x33, 0xE7, 0x2F, 0x10 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x20, 0x55, 0x12, 0x33, 0x50, 0xC0, 0x08, 0x58 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xDF, 0x3B, 0x99, 0xD6, 0x57, 0x73, 0x97, 0xC8 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x31, 0xFE, 0x17, 0x36, 0x9B, 0x52, 0x88, 0xC9 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xDF, 0xDD, 0x3C, 0xC6, 0x4D, 0xAE, 0x16, 0x42 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x17, 0x8C, 0x83, 0xCE, 0x2B, 0x39, 0x9D, 0x94 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x50, 0xF6, 0x36, 0x32, 0x4A, 0x9B, 0x7F, 0x80 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xA8, 0x46, 0x8E, 0xE3, 0xBC, 0x18, 0xF0, 0x6D },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xA2, 0xDC, 0x9E, 0x92, 0xFD, 0x3C, 0xDE, 0x92 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCA, 0xC0, 0x9F, 0x79, 0x7D, 0x03, 0x12, 0x87 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x90, 0xBA, 0x68, 0x0B, 0x22, 0xAE, 0xB5, 0x25 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xCE, 0x7A, 0x24, 0xF3, 0x50, 0xE2, 0x80, 0xB6 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x88, 0x2B, 0xFF, 0x0A, 0xA0, 0x1A, 0x0B, 0x87 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xC2 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01 },
{ 0xC7, 0x15, 0x16, 0xC2, 0x9C, 0x75, 0xD1, 0x70 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01 },
{ 0x51, 0x99, 0xC2, 0x9A, 0x52, 0xC9, 0xF0, 0x59 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01 },
{ 0xC2, 0x2F, 0x0A, 0x29, 0x4A, 0x71, 0xF2, 0x9F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01 },
{ 0xEE, 0x37, 0x14, 0x83, 0x71, 0x4C, 0x02, 0xEA },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01 },
{ 0xA8, 0x1F, 0xBD, 0x44, 0x8F, 0x9E, 0x52, 0x2F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01 },
{ 0x4F, 0x64, 0x4C, 0x92, 0xE1, 0x92, 0xDF, 0xED },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01 },
{ 0x1A, 0xFA, 0x9A, 0x66, 0xA6, 0xDF, 0x92, 0xAE },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01 },
{ 0xB3, 0xC1, 0xCC, 0x71, 0x5C, 0xB8, 0x79, 0xD8 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01 },
{ 0x19, 0xD0, 0x32, 0xE6, 0x4A, 0xB0, 0xBD, 0x8B },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01 },
{ 0x3C, 0xFA, 0xA7, 0xA7, 0xDC, 0x87, 0x20, 0xDC },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01 },
{ 0xB7, 0x26, 0x5F, 0x7F, 0x44, 0x7A, 0xC6, 0xF3 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01 },
{ 0x9D, 0xB7, 0x3B, 0x3C, 0x0D, 0x16, 0x3F, 0x54 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01 },
{ 0x81, 0x81, 0xB6, 0x5B, 0xAB, 0xF4, 0xA9, 0x75 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01 },
{ 0x93, 0xC9, 0xB6, 0x40, 0x42, 0xEA, 0xA2, 0x40 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01 },
{ 0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01 },
{ 0x86, 0x38, 0x80, 0x9E, 0x87, 0x87, 0x87, 0xA0 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01 },
{ 0x41, 0xB9, 0xA7, 0x9A, 0xF7, 0x9A, 0xC2, 0x08 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01 },
{ 0x7A, 0x9B, 0xE4, 0x2F, 0x20, 0x09, 0xA8, 0x92 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01 },
{ 0x29, 0x03, 0x8D, 0x56, 0xBA, 0x6D, 0x27, 0x45 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01 },
{ 0x54, 0x95, 0xC6, 0xAB, 0xF1, 0xE5, 0xDF, 0x51 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01 },
{ 0xAE, 0x13, 0xDB, 0xD5, 0x61, 0x48, 0x89, 0x33 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01 },
{ 0x02, 0x4D, 0x1F, 0xFA, 0x89, 0x04, 0xE3, 0x89 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01 },
{ 0xD1, 0x39, 0x97, 0x12, 0xF9, 0x9B, 0xF0, 0x2E },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01 },
{ 0x14, 0xC1, 0xD7, 0xC1, 0xCF, 0xFE, 0xC7, 0x9E },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01 },
{ 0x1D, 0xE5, 0x27, 0x9D, 0xAE, 0x3B, 0xED, 0x6F },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01 },
{ 0xE9, 0x41, 0xA3, 0x3F, 0x85, 0x50, 0x13, 0x03 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01 },
{ 0xDA, 0x99, 0xDB, 0xBC, 0x9A, 0x03, 0xF3, 0x79 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01 },
{ 0xB7, 0xFC, 0x92, 0xF9, 0x1D, 0x8E, 0x92, 0xE9 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01 },
{ 0xAE, 0x8E, 0x5C, 0xAA, 0x3C, 0xA0, 0x4E, 0x85 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80 },
{ 0x9C, 0xC6, 0x2D, 0xF4, 0x3B, 0x6E, 0xED, 0x74 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40 },
{ 0xD8, 0x63, 0xDB, 0xB5, 0xC5, 0x9A, 0x91, 0xA0 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20 },
{ 0xA1, 0xAB, 0x21, 0x90, 0x54, 0x5B, 0x91, 0xD7 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10 },
{ 0x08, 0x75, 0x04, 0x1E, 0x64, 0xC5, 0x70, 0xF7 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08 },
{ 0x5A, 0x59, 0x45, 0x28, 0xBE, 0xBE, 0xF1, 0xCC },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04 },
{ 0xFC, 0xDB, 0x32, 0x91, 0xDE, 0x21, 0xF0, 0xC0 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02 },
{ 0x86, 0x9E, 0xFD, 0x7F, 0x9F, 0x26, 0x5A, 0x09 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
};
/* Data Permutation test: Encrypt */
static char *testDPname = "Data Permutation";
static DES_TEST testDP[] = {
{ { 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x88, 0xD5, 0x5E, 0x54, 0xF5, 0x4C, 0x97, 0xB4 } },
{ { 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x0C, 0x0C, 0xC0, 0x0C, 0x83, 0xEA, 0x48, 0xFD } },
{ { 0x10, 0x07, 0x10, 0x34, 0xC8, 0x98, 0x01, 0x20 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x83, 0xBC, 0x8E, 0xF3, 0xA6, 0x57, 0x01, 0x83 } },
{ { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xDF, 0x72, 0x5D, 0xCA, 0xD9, 0x4E, 0xA2, 0xE9 } },
{ { 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE6, 0x52, 0xB5, 0x3B, 0x55, 0x0B, 0xE8, 0xB0 } },
{ { 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAF, 0x52, 0x71, 0x20, 0xC4, 0x85, 0xCB, 0xB0 } },
{ { 0x51, 0x07, 0xB0, 0x15, 0x19, 0x58, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x0F, 0x04, 0xCE, 0x39, 0x3D, 0xB9, 0x26, 0xD5 } },
{ { 0x10, 0x07, 0xB0, 0x15, 0x19, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xC9, 0xF0, 0x0F, 0xFC, 0x74, 0x07, 0x90, 0x67 } },
{ { 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x7C, 0xFD, 0x82, 0xA5, 0x93, 0x25, 0x2B, 0x4E } },
{ { 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xCB, 0x49, 0xA2, 0xF9, 0xE9, 0x13, 0x63, 0xE3 } },
{ { 0x10, 0x07, 0x91, 0x15, 0xB9, 0x08, 0x01, 0x40 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0xB5, 0x88, 0xBE, 0x70, 0xD2, 0x3F, 0x56 } },
{ { 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x40, 0x6A, 0x9A, 0x6A, 0xB4, 0x33, 0x99, 0xAE } },
{ { 0x10, 0x07, 0xD0, 0x15, 0x89, 0x98, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6C, 0xB7, 0x73, 0x61, 0x1D, 0xCA, 0x9A, 0xDA } },
{ { 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x67, 0xFD, 0x21, 0xC1, 0x7D, 0xBB, 0x5D, 0x70 } },
{ { 0x91, 0x07, 0xD0, 0x15, 0x89, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x95, 0x92, 0xCB, 0x41, 0x10, 0x43, 0x07, 0x87 } },
{ { 0x10, 0x07, 0xD0, 0x15, 0x98, 0x98, 0x01, 0x20 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xA6, 0xB7, 0xFF, 0x68, 0xA3, 0x18, 0xDD, 0xD3 } },
{ { 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x4D, 0x10, 0x21, 0x96, 0xC9, 0x14, 0xCA, 0x16 } },
{ { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x2D, 0xFA, 0x9F, 0x45, 0x73, 0x59, 0x49, 0x65 } },
{ { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB4, 0x66, 0x04, 0x81, 0x6C, 0x0E, 0x07, 0x74 } },
{ { 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6E, 0x7E, 0x62, 0x21, 0xA4, 0xF3, 0x4E, 0x87 } },
{ { 0x19, 0x07, 0x92, 0x10, 0x98, 0x1A, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAA, 0x85, 0xE7, 0x46, 0x43, 0x23, 0x31, 0x99 } },
{ { 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x2E, 0x5A, 0x19, 0xDB, 0x4D, 0x19, 0x62, 0xD6 } },
{ { 0x10, 0x07, 0x91, 0x19, 0x98, 0x1A, 0x08, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x23, 0xA8, 0x66, 0xA8, 0x09, 0xD3, 0x08, 0x94 } },
{ { 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xD8, 0x12, 0xD9, 0x61, 0xF0, 0x17, 0xD3, 0x20 } },
{ { 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0B },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x05, 0x56, 0x05, 0x81, 0x6E, 0x58, 0x60, 0x8F } },
{ { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAB, 0xD8, 0x8E, 0x8B, 0x1B, 0x77, 0x16, 0xF1 } },
{ { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x53, 0x7A, 0xC9, 0x5B, 0xE6, 0x9D, 0xA1, 0xE1 } },
{ { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xAE, 0xD0, 0xF6, 0xAE, 0x3C, 0x25, 0xCD, 0xD8 } },
{ { 0x10, 0x02, 0x91, 0x14, 0x98, 0x10, 0x01, 0x04 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB3, 0xE3, 0x5A, 0x5E, 0xE5, 0x3E, 0x7B, 0x8D } },
{ { 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x61, 0xC7, 0x9C, 0x71, 0x92, 0x1A, 0x2E, 0xF8 } },
{ { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xE2, 0xF5, 0x72, 0x8F, 0x09, 0x95, 0x01, 0x3C } },
{ { 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x1A, 0xEA, 0xC3, 0x9A, 0x61, 0xF0, 0xA4, 0x64 } }
};
/* S-Box test: Encrypt */
static char *testSBname = "S-Boxes";
static DES_TEST testSB[] = {
{ { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57 },
{ 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42 },
{ 0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B } },
{ { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E },
{ 0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA },
{ 0x7A, 0x38, 0x9D, 0x10, 0x35, 0x4B, 0xD2, 0x71 } },
{ { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86 },
{ 0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72 },
{ 0x86, 0x8E, 0xBB, 0x51, 0xCA, 0xB4, 0x59, 0x9A } },
{ { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E },
{ 0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A },
{ 0x71, 0x78, 0x87, 0x6E, 0x01, 0xF1, 0x9B, 0x2A } },
{ { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6 },
{ 0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2 },
{ 0xAF, 0x37, 0xFB, 0x42, 0x1F, 0x8C, 0x40, 0x95 } },
{ { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE },
{ 0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A },
{ 0x86, 0xA5, 0x60, 0xF1, 0x0E, 0xC6, 0xD8, 0x5B } },
{ { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6 },
{ 0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2 },
{ 0x0C, 0xD3, 0xDA, 0x02, 0x00, 0x21, 0xDC, 0x09 } },
{ { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE },
{ 0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A },
{ 0xEA, 0x67, 0x6B, 0x2C, 0xB7, 0xDB, 0x2B, 0x7A } },
{ { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16 },
{ 0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02 },
{ 0xDF, 0xD6, 0x4A, 0x81, 0x5C, 0xAF, 0x1A, 0x0F } },
{ { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F },
{ 0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A },
{ 0x5C, 0x51, 0x3C, 0x9C, 0x48, 0x86, 0xC0, 0x88 } },
{ { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46 },
{ 0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32 },
{ 0x0A, 0x2A, 0xEE, 0xAE, 0x3F, 0xF4, 0xAB, 0x77 } },
{ { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E },
{ 0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA },
{ 0xEF, 0x1B, 0xF0, 0x3E, 0x5D, 0xFA, 0x57, 0x5A } },
{ { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76 },
{ 0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62 },
{ 0x88, 0xBF, 0x0D, 0xB6, 0xD7, 0x0D, 0xEE, 0x56 } },
{ { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07 },
{ 0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2 },
{ 0xA1, 0xF9, 0x91, 0x55, 0x41, 0x02, 0x0B, 0x56 } },
{ { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F },
{ 0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA },
{ 0x6F, 0xBF, 0x1C, 0xAF, 0xCF, 0xFD, 0x05, 0x56 } },
{ { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7 },
{ 0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92 },
{ 0x2F, 0x22, 0xE4, 0x9B, 0xAB, 0x7C, 0xA1, 0xAC } },
{ { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF },
{ 0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A },
{ 0x5A, 0x6B, 0x61, 0x2C, 0xC2, 0x6C, 0xCE, 0x4A } },
{ { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6 },
{ 0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2 },
{ 0x5F, 0x4C, 0x03, 0x8E, 0xD1, 0x2B, 0x2E, 0x41 } },
{ { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF },
{ 0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A },
{ 0x63, 0xFA, 0xC0, 0xD0, 0x34, 0xD9, 0xF7, 0x93 } }
};
+56
View File
@@ -0,0 +1,56 @@
/* IDEA test vectors, from the ETH reference implementation */
/* The data structure for the ( key, plaintext, ciphertext ) triplets */
typedef struct {
BYTE key[ IDEA_KEYSIZE ];
BYTE plaintext[ IDEA_BLOCKSIZE ];
BYTE ciphertext[ IDEA_BLOCKSIZE ];
} IDEA_TEST;
static IDEA_TEST testIdea[] = {
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
{ 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
{ 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
{ 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
{ 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
{ 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
{ { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
{ 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
{ 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
{ { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
{ { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
{ { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
{ 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
{ 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
{ { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
{ 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
};
+162
View File
@@ -0,0 +1,162 @@
/* RC4 test vectors from the BSAFE2 implementation */
BYTE testRC4key1[] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
BYTE testRC4plaintext1[] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
BYTE testRC4ciphertext1[] =
{ 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 };
BYTE testRC4key2[] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
BYTE testRC4plaintext2[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
BYTE testRC4ciphertext2[] =
{ 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 };
BYTE testRC4key3[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
BYTE testRC4plaintext3[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
BYTE testRC4ciphertext3[] =
{ 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A };
BYTE testRC4key4[] =
{ 0xEF, 0x01, 0x23, 0x45 };
BYTE testRC4plaintext4[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
BYTE testRC4ciphertext4[] =
{ 0xD6, 0xA1, 0x41, 0xA7, 0xEC, 0x3C, 0x38, 0xDF, 0xBD, 0x61 };
BYTE testRC4key5[] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
BYTE testRC4plaintext5[] =
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
BYTE testRC4ciphertext5[] =
{ 0x75, 0x95, 0xC3, 0xE6, 0x11, 0x4A, 0x09, 0x78,
0x0C, 0x4A, 0xD4, 0x52, 0x33, 0x8E, 0x1F, 0xFD,
0x9A, 0x1B, 0xE9, 0x49, 0x8F, 0x81, 0x3D, 0x76,
0x53, 0x34, 0x49, 0xB6, 0x77, 0x8D, 0xCA, 0xD8,
0xC7, 0x8A, 0x8D, 0x2B, 0xA9, 0xAC, 0x66, 0x08,
0x5D, 0x0E, 0x53, 0xD5, 0x9C, 0x26, 0xC2, 0xD1,
0xC4, 0x90, 0xC1, 0xEB, 0xBE, 0x0C, 0xE6, 0x6D,
0x1B, 0x6B, 0x1B, 0x13, 0xB6, 0xB9, 0x19, 0xB8,
0x47, 0xC2, 0x5A, 0x91, 0x44, 0x7A, 0x95, 0xE7,
0x5E, 0x4E, 0xF1, 0x67, 0x79, 0xCD, 0xE8, 0xBF,
0x0A, 0x95, 0x85, 0x0E, 0x32, 0xAF, 0x96, 0x89,
0x44, 0x4F, 0xD3, 0x77, 0x10, 0x8F, 0x98, 0xFD,
0xCB, 0xD4, 0xE7, 0x26, 0x56, 0x75, 0x00, 0x99,
0x0B, 0xCC, 0x7E, 0x0C, 0xA3, 0xC4, 0xAA, 0xA3,
0x04, 0xA3, 0x87, 0xD2, 0x0F, 0x3B, 0x8F, 0xBB,
0xCD, 0x42, 0xA1, 0xBD, 0x31, 0x1D, 0x7A, 0x43,
0x03, 0xDD, 0xA5, 0xAB, 0x07, 0x88, 0x96, 0xAE,
0x80, 0xC1, 0x8B, 0x0A, 0xF6, 0x6D, 0xFF, 0x31,
0x96, 0x16, 0xEB, 0x78, 0x4E, 0x49, 0x5A, 0xD2,
0xCE, 0x90, 0xD7, 0xF7, 0x72, 0xA8, 0x17, 0x47,
0xB6, 0x5F, 0x62, 0x09, 0x3B, 0x1E, 0x0D, 0xB9,
0xE5, 0xBA, 0x53, 0x2F, 0xAF, 0xEC, 0x47, 0x50,
0x83, 0x23, 0xE6, 0x71, 0x32, 0x7D, 0xF9, 0x44,
0x44, 0x32, 0xCB, 0x73, 0x67, 0xCE, 0xC8, 0x2F,
0x5D, 0x44, 0xC0, 0xD0, 0x0B, 0x67, 0xD6, 0x50,
0xA0, 0x75, 0xCD, 0x4B, 0x70, 0xDE, 0xDD, 0x77,
0xEB, 0x9B, 0x10, 0x23, 0x1B, 0x6B, 0x5B, 0x74,
0x13, 0x47, 0x39, 0x6D, 0x62, 0x89, 0x74, 0x21,
0xD4, 0x3D, 0xF9, 0xB4, 0x2E, 0x44, 0x6E, 0x35,
0x8E, 0x9C, 0x11, 0xA9, 0xB2, 0x18, 0x4E, 0xCB,
0xEF, 0x0C, 0xD8, 0xE7, 0xA8, 0x77, 0xEF, 0x96,
0x8F, 0x13, 0x90, 0xEC, 0x9B, 0x3D, 0x35, 0xA5,
0x58, 0x5C, 0xB0, 0x09, 0x29, 0x0E, 0x2F, 0xCD,
0xE7, 0xB5, 0xEC, 0x66, 0xD9, 0x08, 0x4B, 0xE4,
0x40, 0x55, 0xA6, 0x19, 0xD9, 0xDD, 0x7F, 0xC3,
0x16, 0x6F, 0x94, 0x87, 0xF7, 0xCB, 0x27, 0x29,
0x12, 0x42, 0x64, 0x45, 0x99, 0x85, 0x14, 0xC1,
0x5D, 0x53, 0xA1, 0x8C, 0x86, 0x4C, 0xE3, 0xA2,
0xB7, 0x55, 0x57, 0x93, 0x98, 0x81, 0x26, 0x52,
0x0E, 0xAC, 0xF2, 0xE3, 0x06, 0x6E, 0x23, 0x0C,
0x91, 0xBE, 0xE4, 0xDD, 0x53, 0x04, 0xF5, 0xFD,
0x04, 0x05, 0xB3, 0x5B, 0xD9, 0x9C, 0x73, 0x13,
0x5D, 0x3D, 0x9B, 0xC3, 0x35, 0xEE, 0x04, 0x9E,
0xF6, 0x9B, 0x38, 0x67, 0xBF, 0x2D, 0x7B, 0xD1,
0xEA, 0xA5, 0x95, 0xD8, 0xBF, 0xC0, 0x06, 0x6F,
0xF8, 0xD3, 0x15, 0x09, 0xEB, 0x0C, 0x6C, 0xAA,
0x00, 0x6C, 0x80, 0x7A, 0x62, 0x3E, 0xF8, 0x4C,
0x3D, 0x33, 0xC1, 0x95, 0xD2, 0x3E, 0xE3, 0x20,
0xC4, 0x0D, 0xE0, 0x55, 0x81, 0x57, 0xC8, 0x22,
0xD4, 0xB8, 0xC5, 0x69, 0xD8, 0x49, 0xAE, 0xD5,
0x9D, 0x4E, 0x0F, 0xD7, 0xF3, 0x79, 0x58, 0x6B,
0x4B, 0x7F, 0xF6, 0x84, 0xED, 0x6A, 0x18, 0x9F,
0x74, 0x86, 0xD4, 0x9B, 0x9C, 0x4B, 0xAD, 0x9B,
0xA2, 0x4B, 0x96, 0xAB, 0xF9, 0x24, 0x37, 0x2C,
0x8A, 0x8F, 0xFF, 0xB1, 0x0D, 0x55, 0x35, 0x49,
0x00, 0xA7, 0x7A, 0x3D, 0xB5, 0xF2, 0x05, 0xE1,
0xB9, 0x9F, 0xCD, 0x86, 0x60, 0x86, 0x3A, 0x15,
0x9A, 0xD4, 0xAB, 0xE4, 0x0F, 0xA4, 0x89, 0x34,
0x16, 0x3D, 0xDD, 0xE5, 0x42, 0xA6, 0x58, 0x55,
0x40, 0xFD, 0x68, 0x3C, 0xBF, 0xD8, 0xC0, 0x0F,
0x12, 0x12, 0x9A, 0x28, 0x4D, 0xEA, 0xCC, 0x4C,
0xDE, 0xFE, 0x58, 0xBE, 0x71, 0x37, 0x54, 0x1C,
0x04, 0x71, 0x26, 0xC8, 0xD4, 0x9E, 0x27, 0x55,
0xAB, 0x18, 0x1A, 0xB7, 0xE9, 0x40, 0xB0, 0xC0 };
+36
View File
@@ -0,0 +1,36 @@
/* SAFER-SK64 test vectors, from the ETH reference implementation */
/* The data structure for the ( key, plaintext, ciphertext ) triplets */
typedef struct {
int rounds;
BYTE key[ SAFER_KEYSIZE ];
BYTE plaintext[ SAFER_BLOCKSIZE ];
BYTE ciphertext[ SAFER_BLOCKSIZE ];
} SAFER_TEST;
static SAFER_TEST testSafer[] = {
{ SAFER_K64_DEFAULT_NOF_ROUNDS,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x15, 0x1B, 0xFF, 0x02, 0xAD, 0x11, 0xBF, 0x2D } },
{ SAFER_K64_DEFAULT_NOF_ROUNDS,
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x5F, 0xCE, 0x9B, 0xA2, 0x05, 0x84, 0x38, 0xC7 } },
{ SAFER_K128_DEFAULT_NOF_ROUNDS,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x41, 0x4C, 0x54, 0x5A, 0xB6, 0x99, 0x4A, 0xF7 } },
{ SAFER_K128_DEFAULT_NOF_ROUNDS,
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0xFF, 0x78, 0x11, 0xE4, 0xB3, 0xA7, 0x2E, 0x71 } },
{ SAFER_K128_DEFAULT_NOF_ROUNDS,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
{ 0x49, 0xC9, 0x9D, 0x98, 0xA5, 0xBC, 0x59, 0x08 } },
};
+193
View File
@@ -0,0 +1,193 @@
/*
* UNDES V1.1.0 - reconstructed from undes.exe
* Original executable: (C) 1998 H.N.M. Dijkema, GPL
*
* IMPORTANT: despite the program name, the executable selects
* CRYPT_ALGO_3DES + CRYPT_MODE_CBC, i.e. two-key triple DES in CBC mode.
*
* This is reconstructed source, not the original source text. Control flow,
* constants, CRYPTLIB calls and file-format behaviour are derived from the
* 16-bit Turbo C executable and verified against CRYPTLIB 0.99 source.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include "crypt.h"
#include "des_common.h"
int main( int argc, char **argv )
{
char *password;
char *inputName;
char *outputName;
FILE *input;
FILE *output;
unsigned char *buffer;
unsigned char *payload;
BYTE key[ CRYPT_MAX_KEYSIZE ];
BYTE iv[ CRYPT_MAX_IVSIZE ];
BYTE passwordBlock[ CRYPT_MAX_KEYSIZE ];
CRYPT_INFO cryptInfo;
CRYPT_QUERY_INFO queryInfo;
CRYPT_ALGO algorithm = CRYPT_ALGO_3DES;
CRYPT_MODE mode = CRYPT_MODE_CBC;
DES_INT32 fileVersion;
DES_INT32 plainLength;
int keySize;
int ivSize;
int bytesRead;
int firstTime;
int inputFd;
int i;
if( argc == 2 )
{
if( strcmp( argv[ 1 ], "--copyright" ) == 0 )
{
printf( "%s\n\n", desProgramVersion );
printf( "%s", desCopyrightText );
exit( 0 );
}
if( strcmp( argv[ 1 ], "--version" ) == 0 )
{
printf( "%s\n", desProgramVersion );
exit( 0 );
}
}
if( argc != 4 )
{
fprintf( stderr,
"usage: undes <passwd> <file in> <file out>\n"
" undes --copyright\n"
" undes --version\n"
" '-' for file --> stdin/stdout\n" );
exit( argc == 1 ? 0 : 2 );
}
password = argv[ 1 ];
inputName = argv[ 2 ];
outputName = argv[ 3 ];
if( strcmp( inputName, "-" ) != 0 &&
strcmp( inputName, outputName ) == 0 )
{
fprintf( stderr, "<file in> and <file out> cannot be the same\n" );
exit( 1 );
}
input = ( strcmp( inputName, "-" ) == 0 ) ?
stdin : fopen( inputName, "rb" );
output = ( strcmp( outputName, "-" ) == 0 ) ?
stdout : fopen( outputName, "wb" );
checkOpen( input, inputName );
checkOpen( output, outputName );
algorithm = CRYPT_ALGO_3DES;
mode = CRYPT_MODE_CBC;
firstTime = TRUE;
buffer = (unsigned char *) malloc( DES_BUFFER_SIZE );
if( buffer == NULL )
{
fprintf( stderr, "Can't allocate buffer\n" );
exit( 1 );
}
payload = buffer + DES_PREFIX_SIZE;
initLibrary();
queryAlgoModeInformation( algorithm, mode, &queryInfo );
keySize = queryInfo.keySize; /* 14 bytes */
ivSize = queryInfo.ivSize; /* 4 bytes */
i = 0;
while( i < keySize && password[ i ] != '\0' )
{
key[ i ] = (BYTE) password[ i ];
i++;
}
while( i < keySize )
key[ i++ ] = 0;
fileVersion = (DES_INT32) -1;
inputFd = fileno( input );
bytesRead = read( inputFd, &fileVersion, 4 );
checkRead( bytesRead );
checkVersion( fileVersion );
initCryptContext( &cryptInfo, algorithm, mode );
loadCryptContext( &cryptInfo, key, keySize );
queryContextInformation( &cryptInfo, &queryInfo );
ivSize = queryInfo.ivSize;
bytesRead = read( inputFd, iv, ivSize );
checkRead( bytesRead );
loadIV( &cryptInfo, iv, ivSize );
bytesRead = read( inputFd, passwordBlock, CRYPT_MAX_KEYSIZE );
checkRead( bytesRead );
bytesRead = read( inputFd, buffer, DES_BUFFER_SIZE );
checkRead( bytesRead );
while( bytesRead != 0 )
{
/*
* This ordering is intentional. DES encrypts the first data block
* before passwordBlock, although passwordBlock is stored first in the
* file. Decrypting in the same crypto order preserves CBC state.
*/
decryptBuffer( &cryptInfo, buffer, DES_BUFFER_SIZE );
memcpy( &plainLength, buffer, 4 );
if( plainLength < 0 )
plainLength = DES_PAYLOAD_SIZE;
if( firstTime )
{
decryptBuffer( &cryptInfo, passwordBlock, CRYPT_MAX_KEYSIZE );
i = 0;
while( i < keySize && passwordBlock[ i ] == key[ i ] )
i++;
if( i != keySize )
{
fprintf( stderr,
"Password is not correct, no decryption possible\n" );
exit( 1 );
}
firstTime = FALSE;
}
fwrite( payload, (DES_UINT16) plainLength, 1, output );
checkWrite( output );
fflush( output );
bytesRead = read( inputFd, buffer, DES_BUFFER_SIZE );
checkRead( bytesRead );
}
decryptBuffer( &cryptInfo, buffer, 0 );
destroyCryptContext( &cryptInfo );
endLibrary();
free( buffer );
if( input != stdin )
fclose( input );
if( output != stdout )
fclose( output );
return( 0 );
}
+50
View File
@@ -0,0 +1,50 @@
# Validation
The reconstructed sources were checked in two ways.
## 1. Header/API syntax check
`des.c`, `undes.c` and the common support compile syntactically against the
actual `crypt.h` from the supplied `cryptl99.zip`. There are no remaining
placeholder CRYPTLIB declarations.
## 2. Full CRYPTLIB round-trip on a modern compiler
For a behavioural sanity check, the supplied CRYPTLIB 0.99 source and libdes
3.14 source were compiled with GCC 14.2 together with the reconstruction.
A binary test file was then processed as:
```text
plain.bin -> des_v2 -> encrypted.bin -> undes_v2 -> roundtrip.bin
```
`plain.bin` and `roundtrip.bin` compare byte-for-byte equal.
The generated single-block encrypted file has the expected size:
```text
4 version
4 IV
256 password-check block
16384 encrypted data block
-----
16648 bytes total
```
The prefix begins with `75 27 00 00`, i.e. file version `0x00002775` in the
little-endian format used by the DOS executable.
A second test with an incorrect password exits with status 1 and prints the
same executable string:
`Password is not correct, no decryption possible`
## Scope of this validation
This confirms that the reconstructed control flow is internally consistent
with the supplied CRYPTLIB source. It does **not** prove that a modern GCC
build produces ciphertext byte-for-byte identical to the original Turbo C
build. The strongest compatibility test would be to decrypt an actual file
created by the 1998 `des.exe`, or run the original executable in a DOS
environment and compare outputs.