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