diff --git a/.gitignore b/.gitignore index e257658..a973259 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ *.out *.app +build/ +*.bak +.qtcreator diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fcadac0 --- /dev/null +++ b/CMakeLists.txt @@ -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 , read() +# and fileno() calls. POSIX systems have these declarations in , 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 \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) diff --git a/MSDOS/asm/des-main.asm b/MSDOS/asm/des-main.asm new file mode 100644 index 0000000..169ba4d --- /dev/null +++ b/MSDOS/asm/des-main.asm @@ -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 diff --git a/MSDOS/asm/undes-main.asm b/MSDOS/asm/undes-main.asm new file mode 100644 index 0000000..4606b31 --- /dev/null +++ b/MSDOS/asm/undes-main.asm @@ -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] diff --git a/README.md b/README.md index 12fc265..e7363f2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,38 @@ -# des_undes +# DES/UNDES V1.1.0 source reconstruction — v2 -Old des/undes code based on libdes-3.14. \ No newline at end of file +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. diff --git a/SHA256SUMS.txt b/SHA256SUMS.txt new file mode 100644 index 0000000..3aafd83 --- /dev/null +++ b/SHA256SUMS.txt @@ -0,0 +1,3 @@ +d118d9b9a618d7e758229642c0585e005b0ab4d458ef369f44d1f4de7012c034 /mnt/data/des.exe +2e54e8820857a1391ac6ce12444f11f75a8a65bfcc58226edd51d6f495c4aa84 /mnt/data/undes.exe +3cd4d36c75916a2c6050b75bd3ad2706e284d3993fbaa68fbde4343a7056f629 /mnt/data/cryptl99.zip diff --git a/cryptlib-api-map.md b/cryptlib-api-map.md new file mode 100644 index 0000000..624b6eb --- /dev/null +++ b/cryptlib-api-map.md @@ -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. diff --git a/des.c b/des.c new file mode 100644 index 0000000..b36805c --- /dev/null +++ b/des.c @@ -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 +#include +#include +#include +#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 \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, " and 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 ); +} diff --git a/des_common.c b/des_common.c new file mode 100644 index 0000000..86e4c98 --- /dev/null +++ b/des_common.c @@ -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 +#include +#include +#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" + " 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 ); +} diff --git a/des_common.h b/des_common.h new file mode 100644 index 0000000..f442aab --- /dev/null +++ b/des_common.h @@ -0,0 +1,37 @@ +#ifndef DES_COMMON_H +#define DES_COMMON_H + +#include +#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 +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 diff --git a/gcc-syntax-check.txt b/gcc-syntax-check.txt new file mode 100644 index 0000000..e69de29 diff --git a/reconstruction-notes.md b/reconstruction-notes.md new file mode 100644 index 0000000..9087404 --- /dev/null +++ b/reconstruction-notes.md @@ -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. diff --git a/third_party/cryptl99.zip b/third_party/cryptl99.zip new file mode 100644 index 0000000..ddebfe1 Binary files /dev/null and b/third_party/cryptl99.zip differ diff --git a/third_party/cryptlib-0.99/DMakefile b/third_party/cryptlib-0.99/DMakefile new file mode 100644 index 0000000..c8925bf --- /dev/null +++ b/third_party/cryptlib-0.99/DMakefile @@ -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) diff --git a/third_party/cryptlib-0.99/SCOptions b/third_party/cryptlib-0.99/SCOptions new file mode 100644 index 0000000..2e1a6ef --- /dev/null +++ b/third_party/cryptlib-0.99/SCOptions @@ -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 diff --git a/third_party/cryptlib-0.99/SMakefile b/third_party/cryptlib-0.99/SMakefile new file mode 100644 index 0000000..8a5c2fe --- /dev/null +++ b/third_party/cryptlib-0.99/SMakefile @@ -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) diff --git a/third_party/cryptlib-0.99/crypt.bas b/third_party/cryptlib-0.99/crypt.bas new file mode 100644 index 0000000..36f2f34 --- /dev/null +++ b/third_party/cryptlib-0.99/crypt.bas @@ -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 diff --git a/third_party/cryptlib-0.99/crypt.c b/third_party/cryptlib-0.99/crypt.c new file mode 100644 index 0000000..418844c --- /dev/null +++ b/third_party/cryptlib-0.99/crypt.c @@ -0,0 +1,1049 @@ +#include +#include +#include +#include +#include "crypt.h" + +/**************************************************************************** +* * +* General Work Routines * +* * +****************************************************************************/ + +/* Get an IV value. It doesn't matter much what it is, as long as it's + completely different for each call. We use the first built-in encrypt + capability we find (actually we just assume it's there to save some time) */ + +static void getIV( void *iv, int ivLength ) + { + static BOOLEAN initialised = FALSE; + static BYTE ivBuffer[ CRYPT_MAX_IVSIZE ]; + CRYPT_INFO cryptInfo; + CRYPT_INFO_MDCSHS cryptInfoEx; + + if( !initialised ) + { + /* Seed the data with a value which is guaranteed to be different + each time (unless the entire program is rerun more than twice a + second, which is doubtful) */ + memset( ivBuffer, 0, CRYPT_MAX_IVSIZE ); + time( ( time_t * ) ivBuffer ); + initialised = TRUE; + } + + /* Use an extended setup call to only perform 2 setup iterations for + speed, since we're not concerned about security */ + cryptInfoEx.keySetupIterations = 2; + + /* Shuffle the bits and return them to the user. Since the encryption + will force a call to getIV() again, we cheat a bit by poking around + the cryptInfo internals to fool encryptBuffer() into thinking the IV + is already set */ + initCryptContextEx( &cryptInfo, CRYPT_ALGO_MDCSHS, CRYPT_MODE_CFB, + &cryptInfoEx ); + loadCryptContext( &cryptInfo, ivBuffer, CRYPT_MAX_IVSIZE ); + cryptInfo.ivSet = TRUE; /* Nasty hack to stop recursion */ + encryptBuffer( &cryptInfo, ivBuffer, CRYPT_MAX_IVSIZE ); + destroyCryptContext( &cryptInfo ); + memcpy( iv, ivBuffer, ivLength ); + } + +#ifdef LITTLE_ENDIAN + +/* Byte-reverse an array of 16- and 32-bit words to/from network byte order + to account for processor endianness. These routines assume the given + count is a multiple of 16 or 32 bits. They are safe even for CPU's with + a word size > 32 bits since on a little-endian CPU the important 32 bits + are stored first, so that by zeroizing the first 32 bits and oring the + reversed value back in we don't need to rely on the processor only writing + 32 bits into memory */ + +void longReverse( LONG *buffer, int count ) + { +#ifdef _BIG_WORDS + BYTE *bufPtr = ( BYTE * ) buffer, temp; + + count /= 4; /* sizeof( LONG ) != 4 */ + while( count-- ) + { + #if 0 + LONG temp; + + /* This code is cursed */ + temp = value = *buffer & 0xFFFFFFFFUL; + value = ( ( value & 0xFF00FF00UL ) >> 8 ) | \ + ( ( value & 0x00FF00FFUL ) << 8 ); + value = ( ( value << 16 ) | ( value >> 16 ) ) ^ temp; + *buffer ^= value; + buffer = ( LONG * ) ( ( BYTE * ) buffer + 4 ); + #endif /* 0 */ + /* There's really no nice way to do this - the above code generates + misaligned accesses on processors with a word size > 32 bits, so + we have to work at the byte level (either that or turn misaligned + access warnings off by trapping the signal the access corresponds + to. However a context switch per memory access is probably + somewhat slower than the current byte-twiddling mess) */ + temp = bufPtr[ 3 ]; + bufPtr[ 3 ] = bufPtr[ 0 ]; + bufPtr[ 0 ] = temp; + temp = bufPtr[ 2 ]; + bufPtr[ 2 ] = bufPtr[ 1 ]; + bufPtr[ 1 ] = temp; + bufPtr += 4; + } +#else + LONG value; + + count /= sizeof( LONG ); + while( count-- ) + { + value = *buffer; + value = ( ( value & 0xFF00FF00UL ) >> 8 ) | \ + ( ( value & 0x00FF00FFUL ) << 8 ); + *buffer++ = ( value << 16 ) | ( value >> 16 ); + } +#endif /* _BIG_WORDS */ + } + +void wordReverse( WORD *buffer, int count ) + { + WORD value; + + count /= sizeof( WORD ); + while( count-- ) + { + value = *buffer; + *buffer++ = ( value << 8 ) | ( value >> 8 ); + } + } +#endif /* LITTLE_ENDIAN */ + +/* A safe free function which scrubs memory and zeroes the pointer */ + +void secureFree( void **pointer, int count ) + { + if( *pointer != NULL ) + { + /* Scrub the memory, free it, and zero the pointer */ + memset( *pointer, 0, count ); + free( *pointer ); + *pointer = NULL; + } + } + +/**************************************************************************** +* * +* Capability Management Functions * +* * +****************************************************************************/ + +/* The parameters of most encryption algorithms are traditionally specified + in bytes, so we define a shorter form of the bitsToBytes() macro to allow + the capability information to be specified in bits */ + +#define bits(x) bitsToBytes(x) + +/* The functions used to implement the null encryption routines */ + +int nullSelfTest( void ); +int nullInit( CRYPT_INFO *cryptInfo ); +int nullInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int nullEnd( CRYPT_INFO *cryptInfo ); +int nullInitKey( CRYPT_INFO *cryptInfo ); +int nullInitIV( CRYPT_INFO *cryptInfo ); +int nullEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int nullDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the MDC/SHS encryption routines */ + +int mdcshsSelfTest( void ); +int mdcshsInit( CRYPT_INFO *cryptInfo ); +int mdcshsInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int mdcshsEnd( CRYPT_INFO *cryptInfo ); +int mdcshsInitKey( CRYPT_INFO *cryptInfo ); +int mdcshsInitIV( CRYPT_INFO *cryptInfo ); +int mdcshsEncrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int mdcshsDecrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the DES encryption routines */ + +int desSelfTest( void ); +int desInit( CRYPT_INFO *cryptInfo ); +int desInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int desEnd( CRYPT_INFO *cryptInfo ); +int desInitKey( CRYPT_INFO *cryptInfo ); +int desEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desEncryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int desDecryptPCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the two-key triple DES encryption + routines */ + +int des3SelfTest( void ); +int des3Init( CRYPT_INFO *cryptInfo ); +int des3InitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int des3End( CRYPT_INFO *cryptInfo ); +int des3InitKey( CRYPT_INFO *cryptInfo ); +int des3EncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3DecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3EncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3DecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3EncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3DecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3EncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int des3DecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the IDEA encryption routines */ + +int ideaSelfTest( void ); +int ideaInit( CRYPT_INFO *cryptInfo ); +int ideaInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int ideaEnd( CRYPT_INFO *cryptInfo ); +int ideaInitKey( CRYPT_INFO *cryptInfo ); +int ideaEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int ideaDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the RC4 encryption routines */ + +int rc4SelfTest( void ); +int rc4Init( CRYPT_INFO *cryptInfo ); +int rc4InitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int rc4End( CRYPT_INFO *cryptInfo ); +int rc4InitKey( CRYPT_INFO *cryptInfo ); +int rc4Encrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int rc4Decrypt( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The functions used to implement the SAFER and SAFER_SK encryption + routines */ + +int saferSelfTest( void ); +int saferInit( CRYPT_INFO *cryptInfo ); +int saferInitEx( CRYPT_INFO *cryptInfo, void *cryptInfoEx ); +int saferEnd( CRYPT_INFO *cryptInfo ); +int saferInitKey( CRYPT_INFO *cryptInfo ); +int saferEncryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferDecryptECB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferEncryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferDecryptCBC( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferEncryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferDecryptCFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferEncryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); +int saferDecryptOFB( CRYPT_INFO *cryptInfo, void *buffer, int length ); + +/* The encryption library intrinsic capability list */ + +static CAPABILITY_INFO intrinsicCapabilities[] = { + /* The no-encryption capability */ + { CRYPT_ALGO_NONE, CRYPT_MODE_NONE, 0, "None", CRYPT_MAX_SPEED, + 0, 0, 0, + 0, 0, 0, + nullSelfTest, nullInit, nullInitEx, nullEnd, nullInitKey, nullInitIV, + nullEncrypt, nullDecrypt, CRYPT_ERROR, NULL }, + + /* The MDC/SHS capabilities */ + { CRYPT_ALGO_MDCSHS, CRYPT_MODE_CFB, bits( 8 ), "MDC/SHS", CRYPT_ERROR, + bits( 40 ), bits( 512 ), bits( 2048 ), + bits( 32 ), bits( 64 ), bits( 160 ), + mdcshsSelfTest, mdcshsInit, mdcshsInitEx, mdcshsEnd, + mdcshsInitKey, mdcshsInitIV, mdcshsEncrypt, mdcshsDecrypt, + CRYPT_ERROR, NULL }, + + /* The DES capabilities */ + { CRYPT_ALGO_DES, CRYPT_MODE_ECB, bits( 64 ), "DES-ECB", CRYPT_ERROR, + bits( 40 ), bits( 56 ), bits( 56 ), + bits( 0 ), bits( 0 ), bits( 0 ), + desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL, + desEncryptECB, desDecryptECB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_DES, CRYPT_MODE_CBC, bits( 64 ), "DES-CBC", CRYPT_ERROR, + bits( 40 ), bits( 56 ), bits( 56 ), + bits( 16 ), bits( 32 ), bits( 64 ), + desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL, + desEncryptCBC, desDecryptCBC, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_DES, CRYPT_MODE_CFB, bits( 8 ), "DES-CFB", CRYPT_ERROR, + bits( 40 ), bits( 56 ), bits( 56 ), + bits( 16 ), bits( 32 ), bits( 64 ), + desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL, + desEncryptCFB, desDecryptCFB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_DES, CRYPT_MODE_OFB, bits( 8 ), "DES-OFB", CRYPT_ERROR, + bits( 40 ), bits( 56 ), bits( 56 ), + bits( 16 ), bits( 32 ), bits( 64 ), + desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL, + desEncryptOFB, desDecryptOFB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_DES, CRYPT_MODE_PCBC, bits( 64 ), "DES-PCBC", CRYPT_ERROR, + bits( 40 ), bits( 56 ), bits( 56 ), + bits( 16 ), bits( 32 ), bits( 64 ), + desSelfTest, desInit, desInitEx, desEnd, desInitKey, NULL, + desEncryptPCBC, desDecryptPCBC, CRYPT_ERROR, NULL }, + + /* The two-key triple DES capabilities */ + { CRYPT_ALGO_3DES, CRYPT_MODE_ECB, bits( 64 ), "3DES-ECB", CRYPT_ERROR, + bits( 40 ), bits( 112 ), bits( 112 ), + bits( 0 ), bits( 0 ), bits( 0 ), + des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL, + des3EncryptECB, des3DecryptECB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_3DES, CRYPT_MODE_CBC, bits( 64 ), "3DES-CBC", CRYPT_ERROR, + bits( 40 ), bits( 112 ), bits( 112 ), + bits( 16 ), bits( 32 ), bits( 64 ), + des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL, + des3EncryptCBC, des3DecryptCBC, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_3DES, CRYPT_MODE_CFB, bits( 64 ), "3DES-CFB", CRYPT_ERROR, + bits( 40 ), bits( 112 ), bits( 112 ), + bits( 16 ), bits( 32 ), bits( 64 ), + des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL, + des3EncryptCFB, des3DecryptCFB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_3DES, CRYPT_MODE_OFB, bits( 64 ), "3DES-OFB", CRYPT_ERROR, + bits( 40 ), bits( 112 ), bits( 112 ), + bits( 16 ), bits( 32 ), bits( 64 ), + des3SelfTest, des3Init, des3InitEx, des3End, des3InitKey, NULL, + des3EncryptOFB, des3DecryptOFB, CRYPT_ERROR, NULL }, + + /* The IDEA capabilities */ + { CRYPT_ALGO_IDEA, CRYPT_MODE_ECB, bits( 64 ), "IDEA-ECB", CRYPT_ERROR, + bits( 40 ), bits( 128 ), bits( 128 ), + bits( 0 ), bits( 0 ), bits( 0 ), + ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL, + ideaEncryptECB, ideaDecryptECB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_IDEA, CRYPT_MODE_CBC, bits( 64 ), "IDEA-CBC", CRYPT_ERROR, + bits( 40 ), bits( 128 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL, + ideaEncryptCBC, ideaDecryptCBC, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_IDEA, CRYPT_MODE_CFB, bits( 8 ), "IDEA-CFB", CRYPT_ERROR, + bits( 40 ), bits( 128 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL, + ideaEncryptCFB, ideaDecryptCFB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_IDEA, CRYPT_MODE_OFB, bits( 8 ), "IDEA-OFB", CRYPT_ERROR, + bits( 40 ), bits( 128 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + ideaSelfTest, ideaInit, ideaInitEx, ideaEnd, ideaInitKey, NULL, + ideaEncryptOFB, ideaDecryptOFB, CRYPT_ERROR, NULL }, + + /* The RC4 capabilities */ + { CRYPT_ALGO_RC4, CRYPT_MODE_STREAM, bits( 8 ), "RC4", CRYPT_ERROR, + bits( 40 ), bits( 128 ), bits( 256 ), + bits( 0 ), bits( 0 ), bits( 0 ), + rc4SelfTest, rc4Init, rc4InitEx, rc4End, rc4InitKey, NULL, + rc4Encrypt, rc4Decrypt, CRYPT_ERROR, NULL }, + + /* The SAFER capabilities */ + { CRYPT_ALGO_SAFER, CRYPT_MODE_ECB, bits( 64 ), "SAFER-ECB", CRYPT_ERROR, + bits( 40 ), bits( 64 ), bits( 128 ), + bits( 0 ), bits( 0 ), bits( 0 ), + saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL, + saferEncryptECB, saferDecryptECB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_SAFER, CRYPT_MODE_CBC, bits( 64 ), "SAFER-CBC", CRYPT_ERROR, + bits( 40 ), bits( 64 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL, + saferEncryptCBC, saferDecryptCBC, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_SAFER, CRYPT_MODE_CFB, bits( 8 ), "SAFER-CFB", CRYPT_ERROR, + bits( 40 ), bits( 64 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL, + saferEncryptCFB, saferDecryptCFB, CRYPT_ERROR, NULL }, + { CRYPT_ALGO_SAFER, CRYPT_MODE_OFB, bits( 8 ), "SAFER-OFB", CRYPT_ERROR, + bits( 40 ), bits( 64 ), bits( 128 ), + bits( 16 ), bits( 32 ), bits( 64 ), + saferSelfTest, saferInit, saferInitEx, saferEnd, saferInitKey, NULL, + saferEncryptOFB, saferDecryptOFB, CRYPT_ERROR, NULL }, + + /* The end-of-list marker */ + { CRYPT_ALGO_NONE, CRYPT_MODE_NONE, CRYPT_ERROR, "", 0, + 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, CRYPT_ERROR, NULL } + }; + +/* The list of crypt library capability records. Even if initCapabilities() + is never called we still have a minimum non-encryption method available */ + +static CAPABILITY_INFO *capabilityListHead = intrinsicCapabilities; +static CAPABILITY_INFO *capabilityListTail = intrinsicCapabilities; +static CAPABILITY_INFO *intrinsicCapabilityListEnd = NULL; + +/* Free the capability list */ + +static void freeCapabilityList( void ) + { + CAPABILITY_INFO *capabilityListPtr = intrinsicCapabilityListEnd; + void *capabilityToFree; + + /* Mark the list as being empty */ + intrinsicCapabilityListEnd = NULL; + + /* Free the capability record list list */ + while( capabilityListPtr != NULL ) + { + capabilityToFree = capabilityListPtr; + capabilityListPtr = capabilityListPtr->next; + secureFree( &capabilityToFree, sizeof( CAPABILITY_INFO ) ); + } + } + +/* Initialise the intrinsic encryption library capability list */ + +static int initCapabilities( void ) + { + CAPABILITY_INFO *capabilityInfoPtr; + CRYPT_ALGO cryptAlgo = CRYPT_ERROR; + int i; + + /* Add the built-in encryption capabilities */ + for( i = 0; intrinsicCapabilities[ i + 1 ].blockSize != CRYPT_ERROR; i++ ) + intrinsicCapabilities[ i ].next = &intrinsicCapabilities[ i + 1 ]; + + /* Perform the self-test for each encryption algorithm */ + for( capabilityInfoPtr = capabilityListHead; + capabilityInfoPtr != NULL; + capabilityInfoPtr = capabilityInfoPtr->next ) + { + CAPABILITY_INFO *capabilitySelfTestPtr; + int status; + + /* If we've already encountered this algorithm, don't try the + self-test again */ + if( capabilityInfoPtr->cryptAlgo == cryptAlgo ) + continue; + cryptAlgo = capabilityInfoPtr->cryptAlgo; + + /* Perform the self-test for this algorithm type */ + status = capabilityInfoPtr->selfTestFunction(); + + /* Set the test status for each capability using this algorithm */ + for( capabilitySelfTestPtr = capabilityInfoPtr; + capabilitySelfTestPtr != NULL; + capabilitySelfTestPtr = capabilitySelfTestPtr->next ) + if( capabilitySelfTestPtr->cryptAlgo == capabilityInfoPtr->cryptAlgo ) + capabilitySelfTestPtr->selfTestStatus = status; + } + + return( CRYPT_OK ); + } + +/* Add a capability record to the library */ + +static int addCapability( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, \ + int blockSize, char *name, int speed, \ + int minKeySize, int keySize, int maxKeySize ) + { + CAPABILITY_INFO *newElement; + + /* Check the passed-in parameters */ + if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) + return( CRYPT_BADPARM1 ); + if( cryptMode < CRYPT_MODE_NONE || cryptMode > CRYPT_MODE_LAST ) + return( CRYPT_BADPARM2 ); + if( blockSize < 0 ) + return( CRYPT_BADPARM3 ); + if( name == NULL ) + return( CRYPT_BADPARM4 ); + if( ( speed != CRYPT_ERROR && speed < 0 ) || speed > CRYPT_MAX_SPEED ) + return( CRYPT_BADPARM5 ); + if( minKeySize < 0 ) + return( CRYPT_BADPARM6 ); + if( keySize < minKeySize ) + return( CRYPT_BADPARM7 ); + if( maxKeySize < keySize ) + return( CRYPT_BADPARM8 ); + + /* Allocate memory for the new capability and its associated message */ + if( ( newElement = ( CAPABILITY_INFO * ) malloc( sizeof( CAPABILITY_INFO ) ) ) == NULL ) + return( CRYPT_NOMEM ); + memset( newElement, 0, sizeof( CAPABILITY_INFO ) ); + if( ( newElement->name = ( char * ) malloc( strlen( name ) + 1 ) ) == NULL ) + { + free( newElement ); + return( CRYPT_NOMEM ); + } + + /* Copy the information across */ + newElement->cryptAlgo = cryptAlgo; + newElement->cryptMode = cryptMode; + newElement->blockSize = blockSize; + strcpy( newElement->name, name ); + newElement->minKeySize = minKeySize; + newElement->keySize = keySize; + newElement->maxKeySize = maxKeySize; + newElement->next = NULL; + + /* Link it into the list */ + if( capabilityListHead == NULL ) + capabilityListHead = newElement; + else + capabilityListTail->next = newElement; + capabilityListTail = newElement; + + return( CRYPT_OK ); + } + +/* Find the capability record for a given encryption algorithm */ + +static CAPABILITY_INFO *findCapabilityInfo( CRYPT_ALGO cryptAlgo, \ + CRYPT_MODE cryptMode ) + { + CAPABILITY_INFO *capabilityInfoPtr; + + /* Try and find information on the required algorithm */ + for( capabilityInfoPtr = capabilityListHead; + capabilityInfoPtr != NULL; + capabilityInfoPtr = capabilityInfoPtr->next ) + if( capabilityInfoPtr->cryptAlgo == cryptAlgo && + ( capabilityInfoPtr->cryptMode == cryptMode || + cryptMode == CRYPT_MODE_NONE ) ) + return( capabilityInfoPtr ); + + /* Nothing available */ + return( NULL ); + } + +/**************************************************************************** +* * +* Capability Query Functions * +* * +****************************************************************************/ + +/* Determine whether a given encryption mode is available */ + +CRET queryModeAvailability( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode ) + { + /* Perform basic error checking */ + if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) + return( CRYPT_BADPARM1 ); + if( cryptMode < CRYPT_MODE_NONE || cryptMode > CRYPT_MODE_LAST ) + return( CRYPT_BADPARM2 ); + + /* Make sure the library has been initalised */ + if( capabilityListHead == NULL ) + return( CRYPT_NOTINITED ); + + /* See if we have any information on this encryption algo/mode */ + if( findCapabilityInfo( cryptAlgo, cryptMode ) == NULL ) + return( ( findCapabilityInfo( cryptAlgo, CRYPT_MODE_NONE ) == NULL ) ? \ + CRYPT_NOALGO : CRYPT_NOMODE ); + + return( CRYPT_OK ); + } + +CRET queryAlgoAvailability( CRYPT_ALGO cryptAlgo ) + { + return( queryModeAvailability( cryptAlgo, CRYPT_MODE_NONE ) ); + } + +/* Get information on a given encrytion algorithm */ + +CRET queryAlgoModeInformation( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, \ + CRYPT_QUERY_INFO CPTR cryptQueryInfo ) + { + CAPABILITY_INFO *capabilityInfo; + + /* Perform basic error checking */ + if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) + return( CRYPT_BADPARM1 ); + if( cryptMode < CRYPT_MODE_NONE || cryptMode > CRYPT_MODE_LAST ) + return( CRYPT_BADPARM2 ); + if( cryptQueryInfo == NULL ) + return( CRYPT_BADPARM3 ); + + /* Make sure the library has been initalised */ + if( capabilityListHead == NULL ) + return( CRYPT_NOTINITED ); + + /* Clear the fields in the query structure */ + memset( cryptQueryInfo, 0, sizeof( CRYPT_QUERY_INFO ) ); + + /* Find the information record on this algorithm */ + if( ( capabilityInfo = findCapabilityInfo( cryptAlgo, cryptMode ) ) == NULL ) + { + cryptQueryInfo->algoName = ""; + cryptQueryInfo->blockSize = CRYPT_ERROR; + cryptQueryInfo->minKeySize = CRYPT_ERROR; + cryptQueryInfo->keySize = CRYPT_ERROR; + cryptQueryInfo->maxKeySize = CRYPT_ERROR; + cryptQueryInfo->minIVsize = CRYPT_ERROR; + cryptQueryInfo->ivSize = CRYPT_ERROR; + cryptQueryInfo->maxIVsize = CRYPT_ERROR; + cryptQueryInfo->speed = CRYPT_ERROR; + return( ( findCapabilityInfo( cryptAlgo, CRYPT_MODE_NONE ) == NULL ) ? \ + CRYPT_NOALGO : CRYPT_NOMODE ); + } + + /* Return the appropriate information */ + cryptQueryInfo->cryptAlgo = cryptAlgo; + cryptQueryInfo->cryptMode = cryptMode; + cryptQueryInfo->algoName = capabilityInfo->name; + cryptQueryInfo->blockSize = capabilityInfo->blockSize; + cryptQueryInfo->minKeySize = capabilityInfo->minKeySize; + cryptQueryInfo->keySize = capabilityInfo->keySize; + cryptQueryInfo->maxKeySize = capabilityInfo->maxKeySize; + cryptQueryInfo->minIVsize = capabilityInfo->minIVsize; + cryptQueryInfo->ivSize = capabilityInfo->ivSize; + cryptQueryInfo->maxIVsize = capabilityInfo->maxIVsize; + cryptQueryInfo->speed = capabilityInfo->speed; + return( CRYPT_OK ); + } + +/* Get information on the algorithm used by a given encryption context */ + +CRET queryContextInformation( CRYPT_INFO CPTR cryptInfo, + CRYPT_QUERY_INFO CPTR cryptQueryInfo ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( cryptInfo->capabilityInfo == NULL ) + return( CRYPT_NOTINITED ); + + return( queryAlgoModeInformation( cryptInfo->capabilityInfo->cryptAlgo, + cryptInfo->capabilityInfo->cryptMode, cryptQueryInfo ) ); + } + +/* Initialise and shut down the encryption library */ + +CRET initLibrary( void ) + { + return( initCapabilities() ); + } + +CRET endLibrary( void ) + { + freeCapabilityList(); + return( CRYPT_OK ); + } + +/**************************************************************************** +* * +* Encryption Context Management Functions * +* * +****************************************************************************/ + +/* A magic value to detect whether an encryption context has been + initialised yet */ + +#define CRYPT_MAGIC 0xC0EDBABEL + +/* Initialise and perform an extended initialisation of an encryption + context */ + +CRET initCryptContext( CRYPT_INFO CPTR cryptInfo, CRYPT_ALGO cryptAlgo, \ + CRYPT_MODE cryptMode ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) + return( CRYPT_BADPARM2 ); + if( cryptMode < CRYPT_MODE_NONE || cryptMode > CRYPT_MODE_LAST ) + return( CRYPT_BADPARM3 ); + + /* Set all fields to zero */ + memset( cryptInfo, 0, sizeof( CRYPT_INFO ) ); + + /* Set up the pointer to the capability information */ + if( ( cryptInfo->capabilityInfo = findCapabilityInfo( cryptAlgo, cryptMode ) ) == NULL ) + return( ( queryAlgoAvailability( cryptAlgo ) ) ? \ + CRYPT_NOMODE : CRYPT_NOALGO ); + + /* Make sure the algorithm self-test went OK */ + if( cryptInfo->capabilityInfo->selfTestStatus != CRYPT_OK ) + return( CRYPT_SELFTEST ); + + /* Perform any algorithm-specific initialization */ + if( cryptInfo->capabilityInfo->initFunction != NULL ) + { + int status; + + status = cryptInfo->capabilityInfo->initFunction( cryptInfo ); + if( isStatusError( status ) ) + return( status ); + } + + /* Set up the IV information to the default values. This can be + overridden later if required */ + cryptInfo->ivLength = cryptInfo->capabilityInfo->ivSize; + + /* Set the check value. Note that we set it after the capability info + has been set, so that a check on this value will also tell us whether + the capability info is present */ + cryptInfo->checkValue = CRYPT_MAGIC; + + return( CRYPT_OK ); + } + +CRET initCryptContextEx( CRYPT_INFO CPTR cryptInfo, CRYPT_ALGO cryptAlgo, \ + CRYPT_MODE cryptMode, void *cryptInfoEx ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( cryptAlgo < CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST ) + return( CRYPT_BADPARM2 ); + if( cryptMode < CRYPT_MODE_NONE || cryptMode > CRYPT_MODE_LAST ) + return( CRYPT_BADPARM3 ); + if( cryptInfoEx == NULL ) + return( CRYPT_BADPARM4 ); + + /* Set all fields to zero */ + memset( cryptInfo, 0, sizeof( CRYPT_INFO ) ); + + /* Set up the pointer to the capability information */ + if( ( cryptInfo->capabilityInfo = findCapabilityInfo( cryptAlgo, cryptMode ) ) == NULL ) + return( ( queryAlgoAvailability( cryptAlgo ) ) ? \ + CRYPT_NOMODE : CRYPT_NOALGO ); + + /* Make sure the algorithm self-test went OK */ + if( cryptInfo->capabilityInfo->selfTestStatus != CRYPT_OK ) + return( CRYPT_SELFTEST ); + + /* Perform any algorithm-specific initialization */ + if( cryptInfo->capabilityInfo->initExFunction != NULL ) + { + int status; + + status = cryptInfo->capabilityInfo->initExFunction( cryptInfo, cryptInfoEx ); + if( isStatusError( status ) ) + return( status ); + } + + /* Set up the IV information to the default values. This can be + overridden later if required */ + cryptInfo->ivLength = cryptInfo->capabilityInfo->ivSize; + + /* Set the check value. Note that we set it after the capability info + has been set, so that a check on this value will also tell us whether + the capability info is present */ + cryptInfo->checkValue = CRYPT_MAGIC; + + return( CRYPT_OK ); + } + +/* Destroy an encryption context */ + +CRET destroyCryptContext( CRYPT_INFO CPTR cryptInfo ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( cryptInfo->checkValue != CRYPT_MAGIC || + cryptInfo->capabilityInfo == NULL ) + return( CRYPT_NOTINITED ); + + /* Perform any algorithm-specific shutdown */ + if( cryptInfo->capabilityInfo->endFunction != NULL ) + { + int status; + + status = cryptInfo->capabilityInfo->endFunction( cryptInfo ); + if( isStatusError( status ) ) + return( status ); + } + + /* Clear all data in the encryption context */ + memset( cryptInfo, 0, sizeof( CRYPT_INFO ) ); + return( CRYPT_OK ); + } + +/**************************************************************************** +* * +* Keying Functions * +* * +****************************************************************************/ + +/* Load a user key into an encryption context */ + +CRET loadCryptContext( CRYPT_INFO CPTR cryptInfo, void CPTR userKey, + int userKeyLength ) + { + int status; + + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( userKey == NULL ) + return( CRYPT_BADPARM2 ); + if( cryptInfo->checkValue != CRYPT_MAGIC ) + return( CRYPT_NOTINITED ); + if( userKeyLength < cryptInfo->capabilityInfo->minKeySize || + userKeyLength > cryptInfo->capabilityInfo->maxKeySize ) + return( CRYPT_BADPARM3 ); + if( cryptInfo->capabilityInfo->initKeyFunction == NULL ) + return( CRYPT_NOALGO ); + + /* Load the user encryption key into the crypt context */ + memcpy( cryptInfo->userKey, userKey, userKeyLength ); + cryptInfo->userKeyLength = userKeyLength; + + /* Remember that we need to set an IV before we encrypt anything */ + cryptInfo->ivSet = FALSE; + + /* Call the encryption routine for this algorithm/mode */ + if( ( status = cryptInfo->capabilityInfo->initKeyFunction( cryptInfo ) ) != CRYPT_OK ) + return( status ); + + /* Record the fact that the key has been initialized */ + cryptInfo->keySet = TRUE; + + return( CRYPT_OK ); + } + +/**************************************************************************** +* * +* IV Handling Functions * +* * +****************************************************************************/ + +/* Load an IV key into an encryption context */ + +CRET loadIV( CRYPT_INFO CPTR cryptInfo, void CPTR iv, int ivLength ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( cryptInfo->checkValue != CRYPT_MAGIC ) + return( CRYPT_NOTINITED ); + if( ivLength < cryptInfo->capabilityInfo->minIVsize || + ivLength > cryptInfo->capabilityInfo->maxIVsize ) + return( CRYPT_BADPARM3 ); + + /* Set the IV length and check whether we'll be using a user-supplied + IV */ + cryptInfo->ivLength = ivLength; + cryptInfo->ivCount = 0; + if( iv != NULL ) + { + /* Load the IV of the required length. If the required IV size is + less than the maximum possible IV size, we pad it with zeroes */ + memset( cryptInfo->iv, 0, CRYPT_MAX_IVSIZE ); + memcpy( cryptInfo->iv, iv, cryptInfo->ivLength ); + memcpy( cryptInfo->currentIV, cryptInfo->iv, CRYPT_MAX_IVSIZE ); + cryptInfo->ivSet = TRUE; + } + if( cryptInfo->capabilityInfo->initIVFunction != NULL ) + { + int status; + + status = cryptInfo->capabilityInfo->initIVFunction( cryptInfo ); + if( isStatusError( status ) ) + return( status ); + } + + return( CRYPT_OK ); + } + +/* Retrieve an IV from an encryption context */ + +CRET retrieveIV( CRYPT_INFO CPTR cryptInfo, void CPTR iv ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( iv == NULL ) + return( CRYPT_BADPARM2 ); + if( cryptInfo->checkValue != CRYPT_MAGIC ) + return( CRYPT_NOTINITED ); + + /* Make sure the IV has been set */ + if( cryptInfo->ivSet == FALSE ) + return( CRYPT_NOIV ); + + /* Copy the IV data of the required length to the output buffer */ + memcpy( iv, cryptInfo->iv, cryptInfo->ivLength ); + + return( CRYPT_OK ); + } + +/**************************************************************************** +* * +* Encrypt/Decrypt Routines * +* * +****************************************************************************/ + +/* Encrypt a block of memory */ + +CRET encryptBuffer( CRYPT_INFO CPTR cryptInfo, void CPTR buffer, int length ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( buffer == NULL ) + return( CRYPT_BADPARM2 ); + if( length < 0 ) + return( CRYPT_BADPARM3 ); + if( !cryptInfo->keySet ) + return( CRYPT_NOKEY ); + if( cryptInfo->checkValue != CRYPT_MAGIC ) + return( CRYPT_NOTINITED ); + if( cryptInfo->capabilityInfo->encryptFunction == NULL ) + return( CRYPT_NOALGO ); + + /* If there's no IV set, generate one ourselves */ + if( !cryptInfo->ivSet ) + { + BYTE iv[ CRYPT_MAX_IVSIZE ]; + int status; + + getIV( iv, cryptInfo->ivLength ); + status = loadIV( cryptInfo, iv, cryptInfo->ivLength ); + if( isStatusError( status ) ) + return( CRYPT_ERROR ); + } + + /* Call the encryption routine for this algorithm/mode */ + return( cryptInfo->capabilityInfo->encryptFunction( cryptInfo, buffer, length ) ); + } + +/* Decrypt a block of memory */ + +CRET decryptBuffer( CRYPT_INFO CPTR cryptInfo, void CPTR buffer, int length ) + { + /* Perform basic error checking */ + if( cryptInfo == NULL ) + return( CRYPT_BADPARM1 ); + if( buffer == NULL ) + return( CRYPT_BADPARM2 ); + if( length < 0 ) + return( CRYPT_BADPARM3 ); + if( !cryptInfo->keySet ) + return( CRYPT_NOKEY ); + if( cryptInfo->checkValue != CRYPT_MAGIC ) + return( CRYPT_NOTINITED ); + if( cryptInfo->capabilityInfo->decryptFunction == NULL ) + return( CRYPT_NOALGO ); + + /* Make sure the IV has been set */ + if( cryptInfo->ivSet == FALSE ) + return( CRYPT_NOIV ); + + /* Call the decryption routine for this algorithm/mode */ + return( cryptInfo->capabilityInfo->decryptFunction( cryptInfo, buffer, length ) ); + } + +/**************************************************************************** +* * +* Dynamic Library Update Support * +* * +****************************************************************************/ + +/* Add a new encryption capability to the library. This routine is quite + powerful, but what a kludge! */ + +CRET addCryptCapability( CRYPT_ALGO cryptAlgo, CRYPT_MODE cryptMode, \ + int blockSize, char *name, int speed, \ + int minKeySize, int keySize, int maxKeySize ) + { + int status; + + /* Add the basic capability information */ + status = addCapability( cryptAlgo, cryptMode, blockSize, name, + speed, minKeySize, keySize, maxKeySize ); + if( isStatusError( status ) ) + return( status ); + + /* Add the handlers */ +/* Not implemented yet */ + + return( CRYPT_OK ); + } + +/**************************************************************************** +* * +* OS-Specific Support Routines * +* * +****************************************************************************/ + +#if defined( __WINDOWS__ ) && !( defined( WIN32 ) || defined( _WIN32 ) ) + +/* Whether LibMain() has been called before */ + +static BOOLEAN libMainCalled = FALSE; +static HWND hInst; + +/* The main function for the DLL */ + +int CALLBACK LibMain( HINSTANCE hInstance, WORD wDataSeg, WORD wHeapSize, \ + LPSTR lpszCmdLine ) + { + /* Rot bilong kargo */ + if( wHeapSize > 0 ) + UnlockData( 0 ); /* Allow heap to move */ + + /* If we've been called before, return with an error message */ + if( libMainCalled ) + return( FALSE ); + libMainCalled = TRUE; + + /* Initialise the library */ + if( initLibrary() != CRYPT_OK ) + return( FALSE ); + + /* Remember the proc instance for later */ + hInst = hInstance; + + return( TRUE ); + } + +/* Shut down the DLL */ + +int CALLBACK WEP( int nSystemExit ) + { + switch( nSystemExit ) + { + case WEP_SYSTEM_EXIT: + /* System is shutting down */ + break; + + case WEP_FREE_DLL: + /* DLL reference count = 0, DLL-only shutdown */ + break; + } + + /* Shut down the encryption library if necessary */ + endLibrary(); + + return( TRUE ); + } + +#elif defined( __WINDOWS__ ) && ( defined( WIN32 ) || defined( _WIN32 ) ) + +/* Whether LibMain() has been called before */ + +static BOOLEAN libMainCalled = FALSE; +static HWND hInst; + +int LibMain( HANDLE hInstance, ULONG ulReasonCalled, LPVOID lpReserved ) + { + /* If we've been called before, return with an error message */ + if( libMainCalled ) + return( FALSE ); + libMainCalled = TRUE; + + /* Initialise the library */ + if( initLibrary() != CRYPT_OK ) + return( FALSE ); + + /* Remember the proc instance for later */ + hInst = hInstance; + + return( TRUE ); + } + +int CALLBACK WEP( int nSystemExit ) + { + /* Shut down the encryption library if necessary */ + endLibrary(); + + return( TRUE ); + } +#endif /* __WINDOWS__ */ diff --git a/third_party/cryptlib-0.99/crypt.h b/third_party/cryptlib-0.99/crypt.h new file mode 100644 index 0000000..6650399 --- /dev/null +++ b/third_party/cryptlib-0.99/crypt.h @@ -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 + #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 +#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 + 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 */ diff --git a/third_party/cryptlib-0.99/cryptnt.def b/third_party/cryptlib-0.99/cryptnt.def new file mode 100644 index 0000000..c3dc108 --- /dev/null +++ b/third_party/cryptlib-0.99/cryptnt.def @@ -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 diff --git a/third_party/cryptlib-0.99/cryptnt.mak b/third_party/cryptlib-0.99/cryptnt.mak new file mode 100644 index 0000000..2956545 --- /dev/null +++ b/third_party/cryptlib-0.99/cryptnt.mak @@ -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 +################################################################################ diff --git a/third_party/cryptlib-0.99/cryptnt.rc b/third_party/cryptlib-0.99/cryptnt.rc new file mode 100644 index 0000000..a83584f --- /dev/null +++ b/third_party/cryptlib-0.99/cryptnt.rc @@ -0,0 +1,33 @@ +; Resource file for the Windows 32-bit encryption library + +#include + +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 diff --git a/third_party/cryptlib-0.99/cryptos2.def b/third_party/cryptlib-0.99/cryptos2.def new file mode 100644 index 0000000..6cecd9e --- /dev/null +++ b/third_party/cryptlib-0.99/cryptos2.def @@ -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 diff --git a/third_party/cryptlib-0.99/cryptwin.def b/third_party/cryptlib-0.99/cryptwin.def new file mode 100644 index 0000000..6cecd9e --- /dev/null +++ b/third_party/cryptlib-0.99/cryptwin.def @@ -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 diff --git a/third_party/cryptlib-0.99/cryptwin.mak b/third_party/cryptlib-0.99/cryptwin.mak new file mode 100644 index 0000000..fe61831 --- /dev/null +++ b/third_party/cryptlib-0.99/cryptwin.mak @@ -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) +<< diff --git a/third_party/cryptlib-0.99/cryptwin.rc b/third_party/cryptlib-0.99/cryptwin.rc new file mode 100644 index 0000000..56949fc --- /dev/null +++ b/third_party/cryptlib-0.99/cryptwin.rc @@ -0,0 +1,33 @@ +; Resource file for the encryption library + +#include + +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 diff --git a/third_party/cryptlib-0.99/docs.txt b/third_party/cryptlib-0.99/docs.txt new file mode 100644 index 0000000..7305312 --- /dev/null +++ b/third_party/cryptlib-0.99/docs.txt @@ -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 and one call from . + +- 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_, 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 + 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 of +the Signal and Information Processing Laboratory, Swiss Federal Institute of +Technology. diff --git a/third_party/cryptlib-0.99/idea/idea.c b/third_party/cryptlib-0.99/idea/idea.c new file mode 100644 index 0000000..7efcda0 --- /dev/null +++ b/third_party/cryptlib-0.99/idea/idea.c @@ -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 +#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>16, \ + x = (x-t16)+(x>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 +#include +/* + * 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>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 diff --git a/third_party/cryptlib-0.99/lib_3des.c b/third_party/cryptlib-0.99/lib_3des.c new file mode 100644 index 0000000..683264e --- /dev/null +++ b/third_party/cryptlib-0.99/lib_3des.c @@ -0,0 +1,443 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/lib_des.c b/third_party/cryptlib-0.99/lib_des.c new file mode 100644 index 0000000..368f776 --- /dev/null +++ b/third_party/cryptlib-0.99/lib_des.c @@ -0,0 +1,486 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/lib_idea.c b/third_party/cryptlib-0.99/lib_idea.c new file mode 100644 index 0000000..45dee11 --- /dev/null +++ b/third_party/cryptlib-0.99/lib_idea.c @@ -0,0 +1,442 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/lib_mdc.c b/third_party/cryptlib-0.99/lib_mdc.c new file mode 100644 index 0000000..6c2d68e --- /dev/null +++ b/third_party/cryptlib-0.99/lib_mdc.c @@ -0,0 +1,460 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/lib_null.c b/third_party/cryptlib-0.99/lib_null.c new file mode 100644 index 0000000..307fe6f --- /dev/null +++ b/third_party/cryptlib-0.99/lib_null.c @@ -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 ); + } diff --git a/third_party/cryptlib-0.99/lib_rc4.c b/third_party/cryptlib-0.99/lib_rc4.c new file mode 100644 index 0000000..5362d1d --- /dev/null +++ b/third_party/cryptlib-0.99/lib_rc4.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/lib_safr.c b/third_party/cryptlib-0.99/lib_safr.c new file mode 100644 index 0000000..2f91f55 --- /dev/null +++ b/third_party/cryptlib-0.99/lib_safr.c @@ -0,0 +1,489 @@ +#include +#include +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/libdes/3ecb_enc.c b/third_party/cryptlib-0.99/libdes/3ecb_enc.c new file mode 100644 index 0000000..670e17a --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/3ecb_enc.c @@ -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); + } diff --git a/third_party/cryptlib-0.99/libdes/copyrigh b/third_party/cryptlib-0.99/libdes/copyrigh new file mode 100644 index 0000000..dc789d4 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/copyrigh @@ -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. diff --git a/third_party/cryptlib-0.99/libdes/des.h b/third_party/cryptlib-0.99/libdes/des.h new file mode 100644 index 0000000..56588ac --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/des.h @@ -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 diff --git a/third_party/cryptlib-0.99/libdes/des_locl.h b/third_party/cryptlib-0.99/libdes/des_locl.h new file mode 100644 index 0000000..8113e50 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/des_locl.h @@ -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 +#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 + +#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 + * 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<>(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); + + diff --git a/third_party/cryptlib-0.99/libdes/ecb_enc.c b/third_party/cryptlib-0.99/libdes/ecb_enc.c new file mode 100644 index 0000000..2071f80 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/ecb_enc.c @@ -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); + } diff --git a/third_party/cryptlib-0.99/libdes/pcbc_enc.c b/third_party/cryptlib-0.99/libdes/pcbc_enc.c new file mode 100644 index 0000000..e5ff1c4 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/pcbc_enc.c @@ -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); + } diff --git a/third_party/cryptlib-0.99/libdes/podd.h b/third_party/cryptlib-0.99/libdes/podd.h new file mode 100644 index 0000000..5306a7c --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/podd.h @@ -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}; diff --git a/third_party/cryptlib-0.99/libdes/set_key.c b/third_party/cryptlib-0.99/libdes/set_key.c new file mode 100644 index 0000000..5981cf2 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/set_key.c @@ -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>(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>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)); + } diff --git a/third_party/cryptlib-0.99/libdes/sk.h b/third_party/cryptlib-0.99/libdes/sk.h new file mode 100644 index 0000000..25b10bf --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/sk.h @@ -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 +}; diff --git a/third_party/cryptlib-0.99/libdes/spr.h b/third_party/cryptlib-0.99/libdes/spr.h new file mode 100644 index 0000000..3a1afad --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/spr.h @@ -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}; diff --git a/third_party/cryptlib-0.99/libdes/version.h b/third_party/cryptlib-0.99/libdes/version.h new file mode 100644 index 0000000..b823f85 --- /dev/null +++ b/third_party/cryptlib-0.99/libdes/version.h @@ -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"; diff --git a/third_party/cryptlib-0.99/makefile b/third_party/cryptlib-0.99/makefile new file mode 100644 index 0000000..dcde21b --- /dev/null +++ b/third_party/cryptlib-0.99/makefile @@ -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 " + @$(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) diff --git a/third_party/cryptlib-0.99/mdc/shs.c b/third_party/cryptlib-0.99/mdc/shs.c new file mode 100644 index 0000000..5d346a5 --- /dev/null +++ b/third_party/cryptlib-0.99/mdc/shs.c @@ -0,0 +1,540 @@ +#include +#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 +#include +#include + +/* 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 */ diff --git a/third_party/cryptlib-0.99/mdc/shs.h b/third_party/cryptlib-0.99/mdc/shs.h new file mode 100644 index 0000000..cb7c6db --- /dev/null +++ b/third_party/cryptlib-0.99/mdc/shs.h @@ -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 */ diff --git a/third_party/cryptlib-0.99/rc4/rc4.asm b/third_party/cryptlib-0.99/rc4/rc4.asm new file mode 100644 index 0000000..96ee9a1 --- /dev/null +++ b/third_party/cryptlib-0.99/rc4/rc4.asm @@ -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 diff --git a/third_party/cryptlib-0.99/rc4/rc4.c b/third_party/cryptlib-0.99/rc4/rc4.c new file mode 100644 index 0000000..c38cd81 --- /dev/null +++ b/third_party/cryptlib-0.99/rc4/rc4.c @@ -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; +} diff --git a/third_party/cryptlib-0.99/rc4/rc4.h b/third_party/cryptlib-0.99/rc4/rc4.h new file mode 100644 index 0000000..1e54565 --- /dev/null +++ b/third_party/cryptlib-0.99/rc4/rc4.h @@ -0,0 +1,23 @@ +#include + +/* 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 ); diff --git a/third_party/cryptlib-0.99/safer/safer.c b/third_party/cryptlib-0.99/safer/safer.c new file mode 100644 index 0000000..a275b66 --- /dev/null +++ b/third_party/cryptlib-0.99/safer/safer.c @@ -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 */ + +/******************************************************************************/ diff --git a/third_party/cryptlib-0.99/safer/safer.h b/third_party/cryptlib-0.99/safer/safer.h new file mode 100644 index 0000000..0474a5f --- /dev/null +++ b/third_party/cryptlib-0.99/safer/safer.h @@ -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 */ diff --git a/third_party/cryptlib-0.99/test.c b/third_party/cryptlib-0.99/test.c new file mode 100644 index 0000000..180dca9 --- /dev/null +++ b/third_party/cryptlib-0.99/test.c @@ -0,0 +1,519 @@ +#include +#include +#include +#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 ); + } diff --git a/third_party/cryptlib-0.99/testdes.h b/third_party/cryptlib-0.99/testdes.h new file mode 100644 index 0000000..39386b0 --- /dev/null +++ b/third_party/cryptlib-0.99/testdes.h @@ -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 " 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 } } + }; diff --git a/third_party/cryptlib-0.99/testidea.h b/third_party/cryptlib-0.99/testidea.h new file mode 100644 index 0000000..42d5991 --- /dev/null +++ b/third_party/cryptlib-0.99/testidea.h @@ -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 } } + }; diff --git a/third_party/cryptlib-0.99/testrc4.h b/third_party/cryptlib-0.99/testrc4.h new file mode 100644 index 0000000..4ab5aaf --- /dev/null +++ b/third_party/cryptlib-0.99/testrc4.h @@ -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 }; diff --git a/third_party/cryptlib-0.99/testsafr.h b/third_party/cryptlib-0.99/testsafr.h new file mode 100644 index 0000000..f2449d4 --- /dev/null +++ b/third_party/cryptlib-0.99/testsafr.h @@ -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 } }, + }; diff --git a/undes.c b/undes.c new file mode 100644 index 0000000..33937c5 --- /dev/null +++ b/undes.c @@ -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 +#include +#include +#include +#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 \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, " and 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 ); +} diff --git a/validation.md b/validation.md new file mode 100644 index 0000000..8f096b2 --- /dev/null +++ b/validation.md @@ -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.