2 #define CONFIG "config.h"
6 #if defined(_CRYPTO_OPENSSL)
9 #include "crypto_openssl.h" // Required for Eclipse only
14 #ifndef _OPENSSL_NO_HMAC
16 int Sha256HmacInit_OpenSSL(HMAC_CTX
*c
, const void *k
, int l
)
19 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
24 HMAC_Init_ex(c
, k
, l
, EVP_sha256(), NULL
);
28 int Sha256HmacFinish_OpenSSL(HMAC_CTX
*c
, unsigned char *h
, unsigned int *l
)
30 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
40 int_fast8_t Sha256Hmac(BYTE
* key
, BYTE
* restrict data
, DWORD len
, BYTE
* restrict hmac
)
44 # if OPENSSL_VERSION_NUMBER >= 0x10000000L
47 Sha256HmacInit_OpenSSL(&Ctx
, key
, 16) &&
48 HMAC_Update(&Ctx
, data
, len
) &&
49 Sha256HmacFinish_OpenSSL(&Ctx
, hmac
, NULL
);
51 # else // OpenSSL 0.9.x
53 Sha256HmacInit_OpenSSL(&Ctx
, key
, 16);
54 HMAC_Update(&Ctx
, data
, len
);
55 Sha256HmacFinish_OpenSSL(&Ctx
, hmac
, NULL
);
61 #else // _OPENSSL_NO_HMAC (some routers have OpenSSL without support for HMAC)
63 int _Sha256HmacInit(Sha256HmacCtx
*Ctx
, BYTE
*key
, size_t klen
)
68 memset(IPad
, 0x36, sizeof(IPad
));
69 memset(Ctx
->OPad
, 0x5C, sizeof(Ctx
->OPad
));
73 BYTE
*temp
= (BYTE
*)alloca(32);
74 SHA256(key
, klen
, temp
);
79 for (i
= 0; i
< klen
; i
++)
81 IPad
[ i
] ^= key
[ i
];
82 Ctx
->OPad
[ i
] ^= key
[ i
];
85 SHA256_Init(&Ctx
->ShaCtx
);
86 return SHA256_Update(&Ctx
->ShaCtx
, IPad
, sizeof(IPad
));
89 int _Sha256HmacUpdate(Sha256HmacCtx
*Ctx
, BYTE
*data
, size_t len
)
91 int rc
= SHA256_Update(&Ctx
->ShaCtx
, data
, len
);
95 int _Sha256HmacFinish(Sha256HmacCtx
*Ctx
, BYTE
*hmac
, void* dummy
)
99 SHA256_Final(temp
, &Ctx
->ShaCtx
);
100 SHA256_Init(&Ctx
->ShaCtx
);
101 SHA256_Update(&Ctx
->ShaCtx
, Ctx
->OPad
, sizeof(Ctx
->OPad
));
102 SHA256_Update(&Ctx
->ShaCtx
, temp
, sizeof(temp
));
103 return SHA256_Final(hmac
, &Ctx
->ShaCtx
);
106 int_fast8_t Sha256Hmac(BYTE
* key
, BYTE
* restrict data
, DWORD len
, BYTE
* restrict hmac
)
109 _Sha256HmacInit(&Ctx
, key
, 16);
110 _Sha256HmacUpdate(&Ctx
, data
, len
);
111 _Sha256HmacFinish(&Ctx
, hmac
, NULL
);
116 #if defined(_USE_AES_FROM_OPENSSL)
117 void TransformOpenSslEncryptKey(AES_KEY
*k
, const AesCtx
*const Ctx
)
119 uint32_t *rk_OpenSSL
= k
->rd_key
, *rk_vlmcsd
= (uint32_t*)Ctx
->Key
;
120 k
->rounds
= Ctx
->rounds
;
122 for (; rk_OpenSSL
< k
->rd_key
+ ((k
->rounds
+ 1) << 2); rk_OpenSSL
++, rk_vlmcsd
++)
124 #ifdef _OPENSSL_SOFTWARE
125 *rk_OpenSSL
= BE32(*rk_vlmcsd
);
127 *rk_OpenSSL
= LE32(*rk_vlmcsd
);
132 void TransformOpenSslDecryptKey(AES_KEY
*k
, const AesCtx
*const Ctx
)
136 #ifdef _DEBUG_OPENSSL
137 AES_set_decrypt_key((BYTE
*)Ctx
->Key
, 128, k
);
138 errorout("Correct V5 round key:");
140 for (i
= 0; i
< (Ctx
->rounds
+ 1) << 4; i
++)
142 if (!(i
% 16)) errorout("\n");
143 if (!(i
% 4)) errorout(" ");
144 errorout("%02X", ((BYTE
*)(k
->rd_key
))[i
]);
150 k
->rounds
= Ctx
->rounds
;
152 /* invert the order of the round keys blockwise (1 Block = AES_BLOCK_SIZE = 16): */
154 for (i
= 0; i
< (Ctx
->rounds
+ 1) << 2; i
++)
156 #ifdef _OPENSSL_SOFTWARE
157 k
->rd_key
[((Ctx
->rounds
-(i
>> 2)) << 2) + (i
& 3)] = BE32(Ctx
->Key
[i
]);
159 k
->rd_key
[((Ctx
->rounds
-(i
>> 2)) << 2) + (i
& 3)] = LE32(Ctx
->Key
[i
]);
163 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
165 uint32_t *rk
= k
->rd_key
+ 4;
167 for (i
= 0; i
< (Ctx
->rounds
- 1); i
++)
169 MixColumnsR((BYTE
*)(rk
+ (i
<< 2)));
172 #ifdef _DEBUG_OPENSSL
173 errorout("Real round key:");
175 for (i
= 0; i
< (Ctx
->rounds
+ 1) << 4; i
++)
177 if (!(i
% 16)) errorout("\n");
178 if (!(i
% 4)) errorout(" ");
179 errorout("%02X", ((BYTE
*)(k
->rd_key
))[i
]);
186 static BYTE NullIV
[AES_BLOCK_SIZE
+ 8]; // OpenSSL may overwrite bytes behind IV
188 void AesEncryptCbc(const AesCtx
*const Ctx
, BYTE
*iv
, BYTE
*data
, size_t *len
)
192 // OpenSSL overwrites IV plus 4 bytes
193 BYTE localIV
[24]; // 4 spare bytes for safety
194 if (iv
) memcpy(localIV
, iv
, AES_BLOCK_SIZE
);
196 // OpenSSL Low-Level APIs do not pad. Could use EVP API instead but needs more code to access the expanded key
197 uint_fast8_t pad
= (~*len
& (AES_BLOCK_SIZE
- 1)) + 1;
199 #if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
201 for (i
= 0; i
< pad
; i
++) data
[*len
+ i
] = pad
;
203 memset(data
+ *len
, pad
, pad
);
207 memset(NullIV
, 0, sizeof(NullIV
));
209 TransformOpenSslEncryptKey(&k
, Ctx
);
211 AES_cbc_encrypt(data
, data
, *len
, &k
, iv
? localIV
: NullIV
, AES_ENCRYPT
);
214 void AesDecryptBlock(const AesCtx
*const Ctx
, BYTE
*block
)
218 TransformOpenSslDecryptKey(&k
, Ctx
);
219 AES_decrypt(block
, block
, &k
);
222 #if defined(_CRYPTO_OPENSSL) && defined(_USE_AES_FROM_OPENSSL) && !defined(_OPENSSL_SOFTWARE)
223 void AesEncryptBlock(const AesCtx
*const Ctx
, BYTE
*block
)
227 TransformOpenSslEncryptKey(&k
, Ctx
);
228 AES_encrypt(block
, block
, &k
);
232 void AesDecryptCbc(const AesCtx
*const Ctx
, BYTE
*iv
, BYTE
*data
, size_t len
)
236 memset(NullIV
, 0, sizeof(NullIV
));
238 TransformOpenSslDecryptKey(&k
, Ctx
);
239 AES_cbc_encrypt(data
, data
, len
, &k
, iv
? iv
: NullIV
, AES_DECRYPT
);
242 #ifndef _OPENSSL_SOFTWARE
243 void AesCmacV4(BYTE
*Message
, size_t MessageSize
, BYTE
*HashOut
)
246 BYTE hash
[AES_BLOCK_BYTES
];
250 AesInitKey(&Ctx
, AesKeyV4
, FALSE
, V4_KEY_BYTES
);
251 TransformOpenSslEncryptKey(&k
, &Ctx
);
253 memset(hash
, 0, sizeof(hash
));
254 memset(Message
+ MessageSize
, 0, AES_BLOCK_BYTES
);
255 Message
[MessageSize
] = 0x80;
257 for (i
= 0; i
<= MessageSize
; i
+= AES_BLOCK_BYTES
)
259 XorBlock(Message
+ i
, hash
);
260 AES_encrypt(hash
, hash
, &k
);
263 memcpy(HashOut
, hash
, AES_BLOCK_BYTES
);
265 #endif // !_OPENSSL_SOFTWARE
267 #endif // defined(_USE_AES_FROM_OPENSSL)
269 #endif // _CRYPTO_OPENSSL