Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
#define LOG_MODULE "crypto"
|
||||
|
||||
#include "util/crypto.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char vista_prov[]
|
||||
= "Microsoft Enhanced RSA and AES Cryptographic Provider";
|
||||
static const char winxp_prov[]
|
||||
= "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)";
|
||||
|
||||
static int init_count;
|
||||
static HCRYPTPROV prov;
|
||||
|
||||
void crypto_init(void)
|
||||
{
|
||||
const char *prov_name;
|
||||
OSVERSIONINFOEX osix;
|
||||
|
||||
if (init_count++ != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_misc("Initializing win32 crypto wrappers");
|
||||
|
||||
memset(&osix, 0, sizeof(osix));
|
||||
osix.dwOSVersionInfoSize = sizeof(osix);
|
||||
GetVersionEx((void *) &osix);
|
||||
|
||||
if (osix.dwMajorVersion < 6) {
|
||||
prov_name = winxp_prov;
|
||||
} else {
|
||||
prov_name = vista_prov;
|
||||
}
|
||||
|
||||
if (!CryptAcquireContext(&prov, NULL, prov_name, PROV_RSA_AES,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
log_fatal("CryptAcquireContext failed: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_gen_random(void *bytes, size_t nbytes)
|
||||
{
|
||||
CryptGenRandom(prov, nbytes, bytes);
|
||||
}
|
||||
|
||||
void crypto_fini(void)
|
||||
{
|
||||
if (--init_count != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_misc("Shutting down win32 crypto wrappers");
|
||||
|
||||
if (!CryptReleaseContext(prov, 0)) {
|
||||
log_fatal("CryptReleaseContext failed: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void md5_compute(const void *in_bytes, size_t in_nbytes, uint8_t *out_bytes,
|
||||
size_t out_nbytes)
|
||||
{
|
||||
struct md5 md5;
|
||||
|
||||
md5_init(&md5);
|
||||
md5_append(&md5, in_bytes, in_nbytes);
|
||||
md5_fini(&md5, out_bytes, out_nbytes);
|
||||
}
|
||||
|
||||
void md5_init(struct md5 *md5)
|
||||
{
|
||||
if (!CryptCreateHash(prov, CALG_MD5, 0, 0, &md5->hash)) {
|
||||
log_fatal("CryptCreateHash(CALG_MD5) failed: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void md5_append(struct md5 *md5, const void *bytes, size_t nbytes)
|
||||
{
|
||||
if (!CryptHashData(md5->hash, bytes, nbytes, 0)) {
|
||||
log_fatal("CryptHashData failed: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void md5_fini(struct md5 *md5, uint8_t *output, size_t nbytes)
|
||||
{
|
||||
DWORD tmp;
|
||||
|
||||
log_assert(output != NULL && nbytes == 16);
|
||||
|
||||
tmp = nbytes;
|
||||
|
||||
if (output != NULL) {
|
||||
if (!CryptGetHashParam(md5->hash, HP_HASHVAL, output, &tmp, 0)) {
|
||||
log_fatal("Error getting MD5 result: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!CryptDestroyHash(md5->hash)) {
|
||||
log_fatal("CryptDestroyHash failed: %08x",
|
||||
(unsigned int) GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
#define SWAP(x, y, tmp) tmp = x; x = y; y = tmp
|
||||
|
||||
void arc4_init(struct arc4 *arc4, const uint8_t *key, size_t key_nbytes)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t j;
|
||||
uint8_t tmp;
|
||||
|
||||
arc4->i = 0;
|
||||
arc4->j = 0;
|
||||
|
||||
for (i = 0 ; i < 256 ; i++) {
|
||||
arc4->S[i] = (uint8_t) i;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
for (i = 0 ; i < 256 ; i++) {
|
||||
j = j + arc4->S[i] + key[i % key_nbytes];
|
||||
SWAP(arc4->S[i], arc4->S[j], tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void arc4_apply(struct arc4 *arc4, uint8_t *bytes, size_t nbytes)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t tmp;
|
||||
|
||||
for (i = 0 ; i < nbytes ; i++) {
|
||||
arc4->i += 1;
|
||||
arc4->j += arc4->S[arc4->i];
|
||||
|
||||
SWAP(arc4->S[arc4->i], arc4->S[arc4->j], tmp);
|
||||
|
||||
bytes[i] ^= arc4->S[(uint8_t) (arc4->S[arc4->i] + arc4->S[arc4->j])];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint32_t blowfish_F(struct blowfish* blowfish, uint32_t x)
|
||||
{
|
||||
unsigned short a, b, c, d;
|
||||
uint32_t y;
|
||||
|
||||
d = x & 0x00FF;
|
||||
x >>= 8;
|
||||
c = x & 0x00FF;
|
||||
x >>= 8;
|
||||
b = x & 0x00FF;
|
||||
x >>= 8;
|
||||
a = x & 0x00FF;
|
||||
|
||||
y = blowfish->S[0][a] + blowfish->S[1][b];
|
||||
y = y ^ blowfish->S[2][c];
|
||||
y = y + blowfish->S[3][d];
|
||||
return y;
|
||||
}
|
||||
|
||||
void blowfish_init(struct blowfish* blowfish, const uint8_t* key,
|
||||
size_t key_length)
|
||||
{
|
||||
int i, j, k;
|
||||
uint32_t data, datal, datar;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < 16 + 2; ++i) {
|
||||
data = 0x00000000;
|
||||
|
||||
for (k = 0; k < 4; ++k) {
|
||||
data = (data << 8) | key[j];
|
||||
j = j + 1;
|
||||
if (j >= key_length)
|
||||
j = 0;
|
||||
}
|
||||
|
||||
blowfish->P[i] = blowfish->P[i] ^ data;
|
||||
}
|
||||
|
||||
datal = 0x00000000;
|
||||
datar = 0x00000000;
|
||||
|
||||
for (i = 0; i < 16 + 2; i += 2) {
|
||||
blowfish_encrypt(blowfish, &datal, &datar);
|
||||
blowfish->P[i] = datal;
|
||||
blowfish->P[i + 1] = datar;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
for (j = 0; j < 256; j += 2) {
|
||||
blowfish_encrypt(blowfish, &datal, &datar);
|
||||
blowfish->S[i][j] = datal;
|
||||
blowfish->S[i][j + 1] = datar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blowfish_encrypt(struct blowfish* blowfish, uint32_t* xl, uint32_t* xr)
|
||||
{
|
||||
uint32_t Xl;
|
||||
uint32_t Xr;
|
||||
uint32_t temp;
|
||||
short i;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
Xl = Xl ^ blowfish->P[i];
|
||||
Xr = blowfish_F(blowfish, Xl) ^ Xr;
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
}
|
||||
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
Xr = Xr ^ blowfish->P[16];
|
||||
Xl = Xl ^ blowfish->P[16 + 1];
|
||||
*xl = Xl;
|
||||
*xr = Xr;
|
||||
}
|
||||
|
||||
void blowfish_decrypt(struct blowfish* blowfish, uint32_t* xl, uint32_t* xr)
|
||||
{
|
||||
uint32_t Xl;
|
||||
uint32_t Xr;
|
||||
uint32_t temp;
|
||||
short i;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
for (i = 16 + 1; i > 1; --i) {
|
||||
Xl = Xl ^ blowfish->P[i];
|
||||
Xr = blowfish_F(blowfish, Xl) ^ Xr;
|
||||
/* Exchange Xl and Xr */
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
}
|
||||
|
||||
/* Exchange Xl and Xr */
|
||||
temp = Xl;
|
||||
Xl = Xr;
|
||||
Xr = temp;
|
||||
Xr = Xr ^ blowfish->P[1];
|
||||
Xl = Xl ^ blowfish->P[0];
|
||||
*xl = Xl;
|
||||
*xr = Xr;
|
||||
}
|
||||
Reference in New Issue
Block a user