EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
aes.c File Reference
#include <crypto/skcipher.h>
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include "config.h"
#include "crypto.h"
#include "io.h"
Include dependency graph for aes.c:

Go to the source code of this file.

Macros

#define _(a, b)   ((a) ^ (b))
 

Functions

static char * get_key (void)
 
static char * get_iv (void)
 
static int _load_eas_constants (void)
 Load AES key and IV constants.
 
static int add_pkcs7_padding (const char *in, size_t in_len, char **out, size_t *out_len)
 Add PKCS#7 padding to a buffer.
 
static int remove_pkcs7_padding (const char *in, size_t in_len, char **out, size_t *out_len)
 Remove PKCS#7 padding from a buffer.
 
static int _crypt_buffer (bool encrypt, const char *in, size_t in_len, char **out, size_t *out_len)
 Encrypts or decrypts a buffer using AES-128 in CBC mode.
 
int encrypt_buffer (const char *in, size_t in_len, char **out, size_t *out_len)
 Encrypts a buffer using AES-128 in CBC mode.
 
int decrypt_buffer (const char *in, size_t in_len, char **out, size_t *out_len)
 Decrypts a buffer using AES-128 in CBC mode.
 

Variables

static char * AES_KEY = NULL
 
static char * AES_IV = NULL
 

Macro Definition Documentation

◆ _

#define _ (   a,
 
)    ((a) ^ (b))

Definition at line 14 of file aes.c.

Function Documentation

◆ _crypt_buffer()

static int _crypt_buffer ( bool  encrypt,
const char *  in,
size_t  in_len,
char **  out,
size_t *  out_len 
)
static

Encrypts or decrypts a buffer using AES-128 in CBC mode.

Parameters
encryptTrue for encryption, false for decryption.
inInput buffer to encrypt/decrypt.
in_lenLength of the input buffer.
outPointer to the output buffer (allocated within the function).
out_lenPointer to the length of the output buffer.
Returns
0 on success, negative error code on failure.

Definition at line 186 of file aes.c.

187 {
188 struct crypto_skcipher *tfm; // Cipher transformation handle
189 struct skcipher_request *req; // Cipher request handle
190 struct scatterlist sg; // Scatterlist for input/output data
191 char *buf = NULL; // Buffer to hold input data (padded if necessary)
192 char *padded_in = NULL; // Buffer for padded input (for encryption)
193 size_t padded_len = 0; // Length of padded input
194 int ret = 0; // Return value
195 char iv[AES_BLOCK_SIZE]; // Initialization vector
196
197 // Load AES key and IV if not already loaded
198 if (!AES_KEY || !AES_IV) {
199 ret = _load_eas_constants();
200 if (ret != 0) {
201 ERR_MSG("Failed to load AES constants: %d\n", ret);
202 return ret;
203 }
204 }
205
206 if (!in || !out || !out_len)
207 return -EINVAL;
208
209 // Initialize output parameters
210 *out = NULL;
211 *out_len = 0;
212
213 memcpy(iv, AES_IV, AES_BLOCK_SIZE); // Copy IV
214
215 if (encrypt) {
216 // Add PKCS#7 padding for encryption
217 ret = add_pkcs7_padding(in, in_len, &padded_in, &padded_len);
218 if (ret != 0)
219 return ret;
220 }
221 else {
222 // For decryption, input must be a multiple of block size
223 if (in_len % AES_BLOCK_SIZE != 0) {
224 ERR_MSG("Decrypt input length must be a multiple of %d\n",
226 return -EINVAL;
227 }
228 padded_in = vmalloc(in_len);
229 if (!padded_in)
230 return -ENOMEM;
231 memcpy(padded_in, in, in_len);
232 padded_len = in_len;
233 }
234
235 // Allocate buffer for results
236 buf = vmalloc(padded_len);
237 if (!buf) {
238 vfree(padded_in);
239 return -ENOMEM;
240 }
241
242 // Allocate cipher transformation for AES in CBC mode
243 tfm = crypto_alloc_skcipher("cbc(aes)", 0, 0);
244 if (IS_ERR(tfm)) {
245 ret = PTR_ERR(tfm);
246 goto out_free_buffers;
247 }
248
249 // Allocate cipher request
250 req = skcipher_request_alloc(tfm, GFP_KERNEL);
251 if (!req) {
252 ret = -ENOMEM;
253 goto out_free_tfm;
254 }
255
256 // Set the encryption key
257 ret = crypto_skcipher_setkey(tfm, AES_KEY, 16);
258 if (ret != 0) {
259 pr_err("setkey failed: %d\n", ret);
260 goto out_free_req;
261 }
262
263 // Initialize scatterlist with input and output buffers
264 sg_init_one(&sg, padded_in, padded_len);
265 skcipher_request_set_crypt(req, &sg, &sg, padded_len, iv);
266
267 // Perform encryption or decryption
268 if (encrypt)
269 ret = crypto_skcipher_encrypt(req);
270 else
271 ret = crypto_skcipher_decrypt(req);
272
273 if (ret) {
274 ERR_MSG("%s failed: %d\n", encrypt ? "encrypt" : "decrypt", ret);
275 goto out_free_req;
276 }
277
278 // Copy result
279 memcpy(buf, sg_virt(&sg), padded_len);
280
281 if (!encrypt) {
282 // Remove padding after decryption
283 char *unpadded_buf;
284 size_t unpadded_len;
285
286 ret = remove_pkcs7_padding(buf, padded_len, &unpadded_buf, &unpadded_len);
287 if (ret != 0) {
288 ERR_MSG("Failed to remove padding: %d\n", ret);
289 goto out_free_req;
290 }
291
292 // Free the original buffer and replace with unpadded one
293 vfree(buf);
294 buf = unpadded_buf;
295 padded_len = unpadded_len;
296 }
297
298 *out = buf;
299 *out_len = padded_len;
300 buf = NULL; // Prevent free on success path
301
302out_free_req:
303 skcipher_request_free(req);
304out_free_tfm:
305 crypto_free_skcipher(tfm);
306out_free_buffers:
307 vfree(padded_in);
308 vfree(buf);
309
310 return ret;
311}
static char * AES_IV
Definition aes.c:12
static int _load_eas_constants(void)
Load AES key and IV constants.
Definition aes.c:69
static int add_pkcs7_padding(const char *in, size_t in_len, char **out, size_t *out_len)
Add PKCS#7 padding to a buffer.
Definition aes.c:96
static char * AES_KEY
Definition aes.c:11
static int remove_pkcs7_padding(const char *in, size_t in_len, char **out, size_t *out_len)
Remove PKCS#7 padding from a buffer.
Definition aes.c:135
#define ERR_MSG(fmt, args...)
Definition config.h:16
#define AES_BLOCK_SIZE
Definition crypto.h:7

◆ _load_eas_constants()

static int _load_eas_constants ( void  )
static

Load AES key and IV constants.

This function initializes the AES key and IV buffers. It retrieves the key and IV from the configuration or hardcoded values. Returns 0 on success, negative error code on failure.

Definition at line 69 of file aes.c.

69 {
70 // Load AES key
71 AES_KEY = get_key();
72 if (!AES_KEY) {
73 ERR_MSG("Failed to load AES key\n");
74 return -ENOMEM;
75 }
76
77 // Load AES IV
78 AES_IV = get_iv();
79 if (!AES_IV) {
80 ERR_MSG("Failed to load AES IV\n");
81 return -ENOMEM;
82 }
83
84 return 0;
85}
static char * get_iv(void)
Definition aes.c:39
static char * get_key(void)
Definition aes.c:16

◆ add_pkcs7_padding()

static int add_pkcs7_padding ( const char *  in,
size_t  in_len,
char **  out,
size_t *  out_len 
)
static

Add PKCS#7 padding to a buffer.

Parameters
inInput buffer
in_lenLength of input buffer
outOutput buffer (allocated within the function)
out_lenLength of output buffer
Returns
0 on success, negative error code on failure

Definition at line 96 of file aes.c.

97 {
98 size_t padding_len;
99 size_t padded_len;
100 char *padded_buf;
101 int i;
102
103 // Calculate padding length (1-16 bytes)
104 padding_len = AES_BLOCK_SIZE - (in_len % AES_BLOCK_SIZE);
105 padded_len = in_len + padding_len;
106
107 // Allocate padded buffer
108 padded_buf = vmalloc(padded_len);
109 if (!padded_buf)
110 return -ENOMEM;
111
112 // Copy original data
113 memcpy(padded_buf, in, in_len);
114
115 // Add padding bytes
116 for (i = 0; i < padding_len; i++) {
117 padded_buf[in_len + i] = (char)padding_len;
118 }
119
120 *out = padded_buf;
121 *out_len = padded_len;
122
123 return 0;
124}

◆ decrypt_buffer()

int decrypt_buffer ( const char *  in,
size_t  in_len,
char **  out,
size_t *  out_len 
)

Decrypts a buffer using AES-128 in CBC mode.

Parameters
inInput buffer to decrypt.
in_lenLength of the input buffer.
outPointer to the output buffer (allocated within the function).
out_lenPointer to the length of the output buffer.
Returns
0 on success, negative error code on failure.

Definition at line 335 of file aes.c.

335 {
336 return _crypt_buffer(false, in, in_len, out, out_len);
337}
static int _crypt_buffer(bool encrypt, const char *in, size_t in_len, char **out, size_t *out_len)
Encrypts or decrypts a buffer using AES-128 in CBC mode.
Definition aes.c:186

◆ encrypt_buffer()

int encrypt_buffer ( const char *  in,
size_t  in_len,
char **  out,
size_t *  out_len 
)

Encrypts a buffer using AES-128 in CBC mode.

Parameters
inInput buffer to encrypt.
in_lenLength of the input buffer.
outPointer to the output buffer (allocated within the function).
out_lenPointer to the length of the output buffer.
Returns
0 on success, negative error code on failure.

Definition at line 322 of file aes.c.

322 {
323 return _crypt_buffer(true, in, in_len, out, out_len);
324}

◆ get_iv()

static char * get_iv ( void  )
static

Definition at line 39 of file aes.c.

39 {
40 static char iv[] = {
41 _(0x03, 0x62), // 'a' = 0x61
42 _(0x00, 0x62), // 'b' = 0x62
43 _(0x02, 0x61), // 'c' = 0x63
44 _(0x00, 0x64), // 'd' = 0x64
45 _(0x00, 0x65), // 'e' = 0x65
46 _(0x00, 0x66), // 'f' = 0x66
47 _(0x10, 0x21), // '1' = 0x31
48 _(0x13, 0x21), // '2' = 0x33
49 _(0x13, 0x20), // '3' = 0x33
50 _(0x14, 0x20), // '4' = 0x34
51 _(0x15, 0x20), // '5' = 0x35
52 _(0x16, 0x20), // '6' = 0x36
53 _(0x17, 0x20), // '7' = 0x37
54 _(0x18, 0x20), // '8' = 0x38
55 _(0x19, 0x20), // '9' = 0x39
56 0x30, // '0'
57 0
58 };
59 return iv;
60}
#define _(a, b)
Definition aes.c:14

◆ get_key()

static char * get_key ( void  )
static

Definition at line 16 of file aes.c.

16 {
17 static char key[] = {
18 _(0x10, 0x21), // '1' = 0x31
19 _(0x13, 0x21), // '2' = 0x33
20 _(0x13, 0x20), // '3' = 0x33
21 _(0x14, 0x20), // '4' = 0x34
22 _(0x15, 0x20), // '5' = 0x35
23 _(0x16, 0x20), // '6' = 0x36
24 _(0x17, 0x20), // '7' = 0x37
25 _(0x18, 0x20), // '8' = 0x38
26 _(0x19, 0x20), // '9' = 0x39
27 0x30, // '0'
28 _(0x03, 0x62), // 'a' = 0x61
29 _(0x00, 0x62), // 'b' = 0x62
30 _(0x02, 0x61), // 'c' = 0x63
31 _(0x00, 0x64), // 'd' = 0x64
32 _(0x00, 0x65), // 'e' = 0x65
33 _(0x00, 0x66), // 'f' = 0x66
34 0
35 };
36 return key;
37}

◆ remove_pkcs7_padding()

static int remove_pkcs7_padding ( const char *  in,
size_t  in_len,
char **  out,
size_t *  out_len 
)
static

Remove PKCS#7 padding from a buffer.

Parameters
inInput buffer with padding
in_lenLength of input buffer
outOutput buffer (allocated within the function)
out_lenLength of output buffer
Returns
0 on success, negative error code on failure

Definition at line 135 of file aes.c.

136 {
137 unsigned char padding_len;
138 size_t data_len;
139 char *unpadded_buf;
140 int i;
141
142 // Validate input length
143 if (in_len == 0 || in_len % AES_BLOCK_SIZE != 0)
144 return -EINVAL;
145
146 // Get padding length from the last byte
147 padding_len = (unsigned char)in[in_len - 1];
148
149 // Validate padding length
150 if (padding_len == 0 || padding_len > AES_BLOCK_SIZE || padding_len > in_len)
151 return -EINVAL;
152
153 // Verify all padding bytes are correct
154 for (i = 0; i < padding_len; i++) {
155 if ((unsigned char)in[in_len - 1 - i] != padding_len)
156 return -EINVAL;
157 }
158
159 // Calculate data length
160 data_len = in_len - padding_len;
161
162 // Allocate unpadded buffer
163 unpadded_buf = vmalloc(data_len);
164 if (!unpadded_buf)
165 return -ENOMEM;
166
167 // Copy data without padding
168 memcpy(unpadded_buf, in, data_len);
169
170 *out = unpadded_buf;
171 *out_len = data_len;
172
173 return 0;
174}

Variable Documentation

◆ AES_IV

char* AES_IV = NULL
static

Definition at line 12 of file aes.c.

◆ AES_KEY

char* AES_KEY = NULL
static

Definition at line 11 of file aes.c.