modified: pixi.toml
[GalaxyCodeBases.git] / etc / Windows / vlmcsd_old_vancepym / crypto_openssl.c
blobf8550c7b153ca483d07c6344986711dfb86bffc2
1 #ifndef CONFIG
2 #define CONFIG "config.h"
3 #endif // CONFIG
4 #include CONFIG
6 #if defined(_CRYPTO_OPENSSL)
8 #include "crypto.h"
9 #include "crypto_openssl.h" // Required for Eclipse only
10 #include <stdint.h>
11 #include "endian.h"
14 #ifndef _OPENSSL_NO_HMAC
16 int Sha256HmacInit_OpenSSL(HMAC_CTX *c, const void *k, int l)
18 HMAC_CTX_init(c);
19 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
20 int result =
21 #else
22 int result = TRUE;
23 #endif
24 HMAC_Init_ex(c, k, l, EVP_sha256(), NULL);
25 return result;
28 int Sha256HmacFinish_OpenSSL(HMAC_CTX *c, unsigned char *h, unsigned int *l)
30 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
31 int result =
32 #else
33 int result = !0;
34 #endif
35 HMAC_Final(c, h, l);
36 HMAC_CTX_cleanup(c);
37 return result;
40 int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
42 HMAC_CTX Ctx;
44 # if OPENSSL_VERSION_NUMBER >= 0x10000000L
46 return
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);
56 return TRUE;
58 # endif
61 #else // _OPENSSL_NO_HMAC (some routers have OpenSSL without support for HMAC)
63 int _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
65 BYTE IPad[64];
66 unsigned int i;
68 memset(IPad, 0x36, sizeof(IPad));
69 memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
71 if ( klen > 64 )
73 BYTE *temp = (BYTE*)alloca(32);
74 SHA256(key, klen, temp);
75 klen = 32;
76 key = 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);
92 return rc;
95 int _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac, void* dummy)
97 BYTE temp[32];
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)
108 Sha256HmacCtx Ctx;
109 _Sha256HmacInit(&Ctx, key, 16);
110 _Sha256HmacUpdate(&Ctx, data, len);
111 _Sha256HmacFinish(&Ctx, hmac, NULL);
112 return TRUE;
114 #endif
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);
126 #else
127 *rk_OpenSSL = LE32(*rk_vlmcsd);
128 #endif
132 void TransformOpenSslDecryptKey(AES_KEY *k, const AesCtx *const Ctx)
134 uint_fast8_t i;
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]);
147 errorout("\n");
148 #endif
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]);
158 #else
159 k->rd_key[((Ctx->rounds-(i >> 2)) << 2) + (i & 3)] = LE32(Ctx->Key[i]);
160 #endif
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]);
182 errorout("\n");
183 #endif
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)
190 AES_KEY k;
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
200 size_t i;
201 for (i = 0; i < pad; i++) data[*len + i] = pad;
202 #else
203 memset(data + *len, pad, pad);
204 #endif
205 *len += 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)
216 AES_KEY k;
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)
225 AES_KEY k;
227 TransformOpenSslEncryptKey(&k, Ctx);
228 AES_encrypt(block, block, &k);
230 #endif
232 void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
234 AES_KEY k;
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)
245 size_t i;
246 BYTE hash[AES_BLOCK_BYTES];
247 AesCtx Ctx;
248 AES_KEY k;
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