mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-24 04:02:40 -06:00
153 lines
3.4 KiB
C++
153 lines
3.4 KiB
C++
#include <Python.h>
|
|
|
|
#include <openssl/conf.h>
|
|
#include <openssl/evp.h>
|
|
#include <openssl/err.h>
|
|
#include <string.h>
|
|
|
|
static bool _inited = false;
|
|
|
|
static void _init()
|
|
{
|
|
if (!_inited)
|
|
{
|
|
_inited = true;
|
|
ERR_load_crypto_strings();
|
|
OpenSSL_add_all_algorithms();
|
|
OPENSSL_config(NULL);
|
|
}
|
|
}
|
|
|
|
int _handle_error()
|
|
{
|
|
ERR_print_errors_fp(stderr);
|
|
return -1;
|
|
}
|
|
|
|
int AES_encrypt(unsigned char* data, int size, unsigned char* key, unsigned char* iv, unsigned char* ciphertext)
|
|
{
|
|
EVP_CIPHER_CTX *ctx;
|
|
int ciphertext_len, len;
|
|
|
|
if (!(ctx = EVP_CIPHER_CTX_new()))
|
|
return _handle_error();
|
|
|
|
if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
|
|
return _handle_error();
|
|
|
|
if (EVP_EncryptUpdate(ctx, ciphertext, &len, data, size) != 1)
|
|
return _handle_error();
|
|
|
|
ciphertext_len = len;
|
|
|
|
if (EVP_EncryptFinal_ex(ctx, &ciphertext[len], &len) != 1)
|
|
return _handle_error();
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return ciphertext_len + len;
|
|
}
|
|
|
|
int AES_decrypt(unsigned char* data, int size, unsigned char* key, unsigned char* iv, unsigned char* plaintext)
|
|
{
|
|
EVP_CIPHER_CTX *ctx;
|
|
int plaintext_len, len;
|
|
|
|
if (!(ctx = EVP_CIPHER_CTX_new()))
|
|
return _handle_error();
|
|
|
|
if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
|
|
return _handle_error();
|
|
|
|
if (EVP_DecryptUpdate(ctx, plaintext, &len, data, size) != 1)
|
|
return _handle_error();
|
|
|
|
plaintext_len = len;
|
|
|
|
if(EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1)
|
|
return _handle_error();
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
return plaintext_len + len;
|
|
}
|
|
|
|
static PyObject* py_aes_encrypt(PyObject* self, PyObject* args)
|
|
{
|
|
unsigned char* data;
|
|
unsigned char* key;
|
|
unsigned char* iv;
|
|
int size, keysize, ivsize;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#s#s#", &data, &size, &key, &keysize, &iv, &ivsize))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (ivsize != 16 || keysize != 16)
|
|
{
|
|
PyErr_Format(PyExc_ValueError, "iv and key must 16 bytes");
|
|
return NULL;
|
|
}
|
|
|
|
unsigned char* ciphertext = new unsigned char[size + 16];
|
|
|
|
int ciphertext_len = AES_encrypt(data, size, key, iv, ciphertext);
|
|
if (ciphertext_len == -1)
|
|
{
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject* v = Py_BuildValue("s#", ciphertext, ciphertext_len);
|
|
delete[] ciphertext;
|
|
|
|
return v;
|
|
};
|
|
|
|
static PyObject* py_aes_decrypt(PyObject* self, PyObject* args)
|
|
{
|
|
unsigned char* data;
|
|
unsigned char* key;
|
|
unsigned char* iv;
|
|
int size, keysize, ivsize;
|
|
|
|
if (!PyArg_ParseTuple(args, "s#s#s#", &data, &size, &key, &keysize, &iv, &ivsize))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (ivsize != 16 || keysize != 16)
|
|
{
|
|
PyErr_Format(PyExc_ValueError, "iv and key must 16 bytes");
|
|
return NULL;
|
|
}
|
|
|
|
unsigned char* plaintext = new unsigned char[size + 16];
|
|
|
|
int plaintext_len = AES_decrypt(data, size, key, iv, plaintext);
|
|
if (plaintext_len == -1)
|
|
{
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
PyObject* v = Py_BuildValue("s#", plaintext, plaintext_len);
|
|
delete[] plaintext;
|
|
|
|
return v;
|
|
};
|
|
|
|
static PyMethodDef Methods[] = {
|
|
{"encrypt", py_aes_encrypt, METH_VARARGS},
|
|
{"decrypt", py_aes_decrypt, METH_VARARGS},
|
|
{NULL, NULL, 0}
|
|
};
|
|
|
|
#ifdef BUILD_PYD
|
|
extern "C" __declspec(dllexport)
|
|
#endif
|
|
|
|
void initaes(void)
|
|
{
|
|
_init();
|
|
Py_InitModule("aes", Methods);
|
|
}
|