Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // DesX.c DESX implementation |
3 | | // |
4 | | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. |
5 | | // |
6 | | |
7 | | |
8 | | #include "precomp.h" |
9 | | |
10 | | |
11 | | const SYMCRYPT_BLOCKCIPHER SymCryptDesxBlockCipher_default = { |
12 | | SymCryptDesxExpandKey, // PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY expandKeyFunc; |
13 | | SymCryptDesxEncrypt, // PSYMCRYPT_BLOCKCIPHER_CRYPT encryptFunc; |
14 | | SymCryptDesxDecrypt, // PSYMCRYPT_BLOCKCIPHER_CRYPT decryptFunc; |
15 | | NULL, // PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB ecbEncryptFunc; |
16 | | NULL, // PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB ecbDecryptFunc; |
17 | | NULL, // PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE cbcEncryptFunc; |
18 | | NULL, // PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE cbcDecryptFunc; |
19 | | NULL, // PSYMCRYPT_BLOCKCIPHER_MAC_MODE cbcMacFunc; |
20 | | NULL, // PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE ctrMsbFunc; |
21 | | NULL, // PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmEncryptPartFunc; |
22 | | NULL, // PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmDecryptPartFunc; |
23 | | 8, // SIZE_T blockSize; |
24 | | sizeof( SYMCRYPT_DESX_EXPANDED_KEY ), // SIZE_T expandedKeySize; // = sizeof( SYMCRYPT_XXX_EXPANDED_KEY ) |
25 | | }; |
26 | | |
27 | | const PCSYMCRYPT_BLOCKCIPHER SymCryptDesxBlockCipher = &SymCryptDesxBlockCipher_default; |
28 | | |
29 | | SYMCRYPT_ERROR |
30 | | SYMCRYPT_CALL |
31 | | SymCryptDesxExpandKey( _Out_ PSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey, |
32 | | _In_reads_(cbKey) PCBYTE pbKey, |
33 | | SIZE_T cbKey ) |
34 | 0 | { |
35 | 0 | if( cbKey != 24 ) |
36 | 0 | { |
37 | 0 | return SYMCRYPT_WRONG_KEY_SIZE; |
38 | 0 | } |
39 | | |
40 | 0 | SymCryptDesExpandKey( &pExpandedKey->desKey, pbKey, 8 ); |
41 | 0 | memcpy( pExpandedKey->inputWhitening, pbKey+8, 8 ); |
42 | 0 | memcpy( pExpandedKey->outputWhitening, pbKey+16, 8 ); |
43 | |
|
44 | 0 | return SYMCRYPT_NO_ERROR; |
45 | 0 | } |
46 | | |
47 | | VOID |
48 | | SYMCRYPT_CALL |
49 | | SymCryptDesxEncrypt( |
50 | | _In_ PCSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey, |
51 | | _In_reads_( SYMCRYPT_DESX_BLOCK_SIZE ) PCBYTE pbSrc, |
52 | | _Out_writes_( SYMCRYPT_DESX_BLOCK_SIZE ) PBYTE pbDst ) |
53 | 0 | { |
54 | 0 | SYMCRYPT_ALIGN BYTE buf[8]; |
55 | | |
56 | | // |
57 | | // We buffer the result locally to obey the read once/write once rule. |
58 | | // |
59 | 0 | SymCryptXorBytes( pbSrc, pExpandedKey->inputWhitening, buf, 8 ); |
60 | 0 | SymCryptDesEncrypt( &pExpandedKey->desKey, buf, buf ); |
61 | 0 | SymCryptXorBytes( buf, pExpandedKey->outputWhitening, pbDst, 8 ); |
62 | |
|
63 | 0 | SymCryptWipeKnownSize( buf, sizeof( buf ) ); |
64 | 0 | } |
65 | | |
66 | | VOID |
67 | | SYMCRYPT_CALL |
68 | | SymCryptDesxDecrypt( |
69 | | _In_ PCSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey, |
70 | | _In_reads_( SYMCRYPT_DESX_BLOCK_SIZE ) PCBYTE pbSrc, |
71 | | _Out_writes_( SYMCRYPT_DESX_BLOCK_SIZE ) PBYTE pbDst ) |
72 | 0 | { |
73 | 0 | SYMCRYPT_ALIGN BYTE buf[8]; |
74 | | |
75 | | // |
76 | | // We buffer the result locally to obey the read once/write once rule. |
77 | | // |
78 | 0 | SymCryptXorBytes( pbSrc, pExpandedKey->outputWhitening, buf, 8 ); |
79 | 0 | SymCryptDesDecrypt( &pExpandedKey->desKey, buf, buf ); |
80 | 0 | SymCryptXorBytes( buf, pExpandedKey->inputWhitening, pbDst, 8 ); |
81 | |
|
82 | 0 | SymCryptWipeKnownSize( buf, sizeof( buf ) ); |
83 | 0 | } |
84 | | |
85 | | |
86 | | static const BYTE desxKnownKey[24] = { |
87 | | 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
88 | | 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, |
89 | | 0x01, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 |
90 | | }; |
91 | | |
92 | | static const BYTE desxKnownPlaintext[] = { |
93 | | 0xd9, 0xb6, 0xa1, 0x4e, 0xe6, 0x71, 0x4e, 0x17 |
94 | | }; |
95 | | |
96 | | static const BYTE desxKnownCiphertext[] = { |
97 | | 0x66, 0x77, 0x1f, 0x2a, 0x0c, 0x05, 0x01, 0xca |
98 | | }; |
99 | | |
100 | | |
101 | | VOID |
102 | | SYMCRYPT_CALL |
103 | | SymCryptDesxSelftest(void) |
104 | 0 | { |
105 | 0 | SYMCRYPT_DESX_EXPANDED_KEY key; |
106 | 0 | BYTE buf[SYMCRYPT_DESX_BLOCK_SIZE]; |
107 | |
|
108 | 0 | if( SymCryptDesxExpandKey( &key, desxKnownKey, sizeof( desxKnownKey )) != SYMCRYPT_NO_ERROR ) |
109 | 0 | { |
110 | 0 | SymCryptFatal( 'desx' ); |
111 | 0 | } |
112 | |
|
113 | 0 | SymCryptDesxEncrypt( &key, desxKnownPlaintext, buf ); |
114 | |
|
115 | 0 | SymCryptInjectError( buf, SYMCRYPT_DESX_BLOCK_SIZE ); |
116 | |
|
117 | 0 | if( memcmp( buf, desxKnownCiphertext, SYMCRYPT_DESX_BLOCK_SIZE ) != 0 ) |
118 | 0 | { |
119 | 0 | SymCryptFatal( 'desy' ); |
120 | 0 | } |
121 | |
|
122 | 0 | SymCryptDesxDecrypt( &key, desxKnownCiphertext, buf ); |
123 | |
|
124 | 0 | SymCryptInjectError( buf, SYMCRYPT_DESX_BLOCK_SIZE ); |
125 | |
|
126 | 0 | if( memcmp( buf, desxKnownPlaintext, SYMCRYPT_DESX_BLOCK_SIZE ) != 0 ) |
127 | 0 | { |
128 | 0 | SymCryptFatal( 'desz' ); |
129 | 0 | } |
130 | |
|
131 | 0 | } |
132 | | |