-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path_libeay.c
131 lines (114 loc) · 3.57 KB
/
_libeay.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
/*
* Copyright (C) 2015-2023 maxpat78 <https://github.com/maxpat78>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/aes.h>
#define PY_SSIZE_T_CLEAN size_t
#include <Python.h>
#ifdef BYTE_ORDER_1234
void betole64(uint64_t *x) {
*x = (*x & 0x00000000FFFFFFFF) << 32 | (*x & 0xFFFFFFFF00000000) >> 32;
*x = (*x & 0x0000FFFF0000FFFF) << 16 | (*x & 0xFFFF0000FFFF0000) >> 16;
*x = (*x & 0x00FF00FF00FF00FF) << 8 | (*x & 0xFF00FF00FF00FF00) >> 8;
}
#endif
static PyObject *
p_AES_ctr128_le_crypt(self, args)
PyObject *self, *args;
{
char ctr_counter_le[16];
char ctr_encrypted_counter[16];
#ifdef BYTE_ORDER_1234
char ctr_counter_be[16];
#endif
const char* p = ctr_encrypted_counter;
const char* q = p+8;
char *key, *buf, *pbuf, *ppbuf;
uint32_t key_len, buf_len, i;
AES_KEY aes_key;
if ( !PyArg_ParseTuple(args, "s#s#", &key, &key_len, &buf, &buf_len) ||
AES_set_encrypt_key(key, key_len*8, &aes_key) < 0 )
return Py_BuildValue("s", NULL);
#ifdef BYTE_ORDER_1234
memset(ctr_counter_be, 0, 16);
#else
memset(ctr_counter_le, 0, 16);
#endif
/* Lavora su una copia del buffer originale */
ppbuf = pbuf = PyMem_Malloc(buf_len);
for (i=0; i < buf_len/16; i++) {
#ifndef BYTE_ORDER_1234
(*((uint64_t*) ctr_counter_le))++;
#else
(*((uint64_t*) ctr_counter_be))++;
*((uint64_t*) ctr_counter_le) = *((uint64_t*) ctr_counter_be);
betole64((uint64_t*)ctr_counter_le);
#endif
AES_ecb_encrypt(ctr_counter_le, ctr_encrypted_counter, &aes_key, 1);
*((uint64_t*) pbuf) = *((uint64_t*) buf) ^ *((uint64_t*) p);
pbuf+=sizeof(uint64_t);
buf+=sizeof(uint64_t);
*((uint64_t*) pbuf) = *((uint64_t*) buf) ^ *((uint64_t*) q);
pbuf+=sizeof(uint64_t);
buf+=sizeof(uint64_t);
}
if ((i = buf_len%16)) {
#ifndef BYTE_ORDER_1234
(*((uint64_t*) ctr_counter_le))++;
#else
(*((uint64_t*) ctr_counter_be))++;
*((uint64_t*) ctr_counter_le) = *((uint64_t*) ctr_counter_be);
betole64((uint64_t*)ctr_counter_le);
#endif
AES_ecb_encrypt(ctr_counter_le, ctr_encrypted_counter, &aes_key, 1);
while (i--)
*pbuf++ = *buf++ ^ *p++;
}
#if PY_MAJOR_VERSION > 2
return Py_BuildValue("y#", ppbuf, buf_len);
#else
return Py_BuildValue("s#", ppbuf, buf_len);
#endif
}
static PyMethodDef _libeay_methods[] =
{
{"AES_ctr128_le_crypt", p_AES_ctr128_le_crypt, METH_VARARGS, "Encrypts with AES CTR-LE (openssl/libressl)"},
{NULL, NULL, 0, NULL}
};
#if PY_MAJOR_VERSION > 2
static struct PyModuleDef _libeay_module = {
PyModuleDef_HEAD_INIT,
"_libeay", /* name of module */
NULL, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
_libeay_methods
};
PyMODINIT_FUNC PyInit__libeay()
{
return PyModule_Create(&_libeay_module);
}
#else
__declspec(dllexport)
void
init_libeay()
{
Py_InitModule("_libeay", _libeay_methods);
}
#endif