1 /*  libGringotts - generic data encoding (crypto+compression) library
2  *  (c) 2002, Germano Rizzo <mano@pluto.linux.it>
3  *
4  *  libgrg_crypt.c - routines for data encryption and writing
5  *  Author: Germano Rizzo
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include <string.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <stddef.h>
26 #include <fcntl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/mman.h>
30 
31 #include "libgrg_crypt.h"
32 #include "libgrg_utils.h"
33 #include "libgrg_structs.h"
34 #include "libgringotts.h"
35 
36 #include <mhash.h>
37 #include <zlib.h>
38 #include <bzlib.h>
39 
40 unsigned int
grg_get_key_size_static(const grg_crypt_algo crypt_algo)41 grg_get_key_size_static (const grg_crypt_algo crypt_algo)
42 {
43 	if (crypt_algo == GRG_3DES)
44 		return 24;
45 	else
46 		return 32;
47 }
48 
49 unsigned int
grg_get_key_size(const GRG_CTX gctx)50 grg_get_key_size (const GRG_CTX gctx)
51 {
52 	return grg_get_key_size_static (gctx->crypt_algo);
53 }
54 
55 unsigned int
grg_get_block_size_static(const grg_crypt_algo crypt_algo)56 grg_get_block_size_static (const grg_crypt_algo crypt_algo)
57 {
58 	switch (crypt_algo)
59 	{
60 	case GRG_3DES:
61 		return 8;
62 	case GRG_RIJNDAEL_256:
63 		return 32;
64 	default:
65 		return 16;
66 	}
67 }
68 
69 unsigned int
grg_get_block_size(const GRG_CTX gctx)70 grg_get_block_size (const GRG_CTX gctx)
71 {
72 	return grg_get_block_size_static (gctx->crypt_algo);
73 }
74 
75 /**
76  * get_CRC32:
77  * @string: a byte sequence
78  * @strlen: the length of the string
79  *
80  * Computes the CRC32 checksum of a byte sequence.
81  *
82  * Returns: the checksum
83  */
84 static unsigned char *
get_CRC32(const unsigned char * string,const long strlen)85 get_CRC32 (const unsigned char *string, const long strlen)
86 {
87 	MHASH td;
88 	unsigned char *ret;
89 
90 	td = mhash_init (MHASH_CRC32);
91 
92 	if (td == MHASH_FAILED)
93 		exit (1);
94 
95 	mhash (td, string, strlen);
96 
97 	ret = mhash_end (td);
98 
99 	return ret;
100 }
101 
102 /**
103  * compare_CRC32:
104  * @CRC: the CRC to compare to
105  * @toCheck: the byte sequence to compare the CRC to
106  * @len: the byte sequence length
107  *
108  * Tells if a byte sequence has the provided CRC32, in other words if
109  * it's equal to the previously CRC'ed one.
110  *
111  * Returns: TRUE or FALSE
112  */
113 static int
compare_CRC32(const unsigned char * CRC,const unsigned char * toCheck,const long len)114 compare_CRC32 (const unsigned char *CRC, const unsigned char *toCheck,
115 	       const long len)
116 {
117 	unsigned char *CRC2;
118 	int ret;
119 
120 	if (!CRC || !toCheck)
121 		return 0;
122 
123 	if (!len)
124 		return 1;
125 
126 	CRC2 = get_CRC32 (toCheck, len);
127 
128 	ret = !memcmp (CRC, CRC2, LIBGRG_CRC_LEN);
129 
130 	free (CRC2);
131 
132 	return ret;
133 }
134 
135 unsigned char *
grg2mcrypt(const grg_crypt_algo algo)136 grg2mcrypt (const grg_crypt_algo algo)
137 {
138 	switch (algo)
139 	{
140 	case GRG_RIJNDAEL_128:
141 		return MCRYPT_RIJNDAEL_128;
142 
143 	case GRG_SERPENT:
144 		return MCRYPT_SERPENT;
145 
146 	case GRG_TWOFISH:
147 		return MCRYPT_TWOFISH;
148 
149 	case GRG_CAST_256:
150 		return MCRYPT_CAST_256;
151 
152 	case GRG_SAFERPLUS:
153 		return MCRYPT_SAFERPLUS;
154 
155 	case GRG_LOKI97:
156 		return MCRYPT_LOKI97;
157 
158 	case GRG_3DES:
159 		return MCRYPT_3DES;
160 
161 	case GRG_RIJNDAEL_256:
162 		return MCRYPT_RIJNDAEL_256;
163 
164 	default:
165 		return MCRYPT_SERPENT;
166 	}
167 }
168 
169 static int
validate_mem(const GRG_CTX gctx,const void * mem,const long memDim)170 validate_mem (const GRG_CTX gctx, const void *mem, const long memDim)
171 {
172 	unsigned char vers;
173 	char *tmp;
174 	long rem;
175 
176 	if (!gctx || !mem)
177 		return GRG_ARGUMENT_ERR;
178 
179 	tmp = (char *) mem;
180 	rem = (memDim >= 0) ? memDim : strlen (mem);
181 
182 	//checks the ID header
183 	if (memcmp (gctx->header, mem, HEADER_LEN))
184 		return GRG_READ_MAGIC_ERR;
185 
186 	tmp += HEADER_LEN;
187 	rem -= HEADER_LEN;
188 
189 	//checks the GRG_VERSION
190 	vers = tmp[0] - '0';	//makes the version as an ordinal, not a char anymore
191 	tmp++;
192 	rem--;
193 
194 	if (vers != 3)		//add here all the supported versions
195 		return GRG_READ_UNSUPPORTED_VERSION;
196 
197 	//checks the 1st CRC
198 	if (!compare_CRC32 (tmp, tmp + LIBGRG_CRC_LEN, rem - LIBGRG_CRC_LEN))
199 		return GRG_READ_CRC_ERR;
200 
201 	return vers;
202 }
203 
204 static void
update_gctx_from_mem(GRG_CTX gctx,const char algo)205 update_gctx_from_mem (GRG_CTX gctx, const char algo)
206 {
207 	gctx->crypt_algo = (unsigned char) (algo & GRG_ENCRYPT_MASK);
208 	gctx->hash_algo = (unsigned char) (algo & GRG_HASH_MASK);
209 	gctx->comp_algo = (unsigned char) (algo & GRG_COMP_TYPE_MASK);
210 	gctx->comp_lvl = (unsigned char) (algo & GRG_COMP_LVL_MASK);
211 }
212 
213 static unsigned char *
select_key(const GRG_CTX gctx,const GRG_KEY keystruct,int * dim)214 select_key (const GRG_CTX gctx, const GRG_KEY keystruct, int *dim)
215 {
216 	unsigned char *key;
217 
218 	if (gctx->crypt_algo == GRG_3DES)
219 		*dim = 24;
220 	else
221 		*dim = 32;
222 
223 	if (gctx->hash_algo == GRG_SHA1)
224 		key = grg_memdup (((*dim ==
225 				     24) ? keystruct->
226 				    key_192_sha : keystruct->key_256_sha),
227 				   *dim);
228 	else
229 		key = grg_memdup (((*dim ==
230 				     24) ? keystruct->
231 				    key_192_ripe : keystruct->key_256_ripe),
232 				   *dim);
233 
234 	return key;
235 }
236 
237 static int
decrypt_mem(const GRG_CTX gctx,const GRG_KEY keystruct,const void * mem,long memDim,unsigned char ** origData,long * origDim)238 decrypt_mem (const GRG_CTX gctx, const GRG_KEY keystruct, const void *mem,
239 	     long memDim, unsigned char **origData, long *origDim)
240 {
241 	unsigned char *IV, *ecdata, *curdata, *dimdata, *key, *CRC32b;
242 	int dIV, len, curlen, keylen, err;
243 	char *tmp;
244 	long oDim;
245 	MCRYPT mod;
246 
247 	len = memDim - LIBGRG_DATA_POS;
248 	tmp = ((char *) mem) + LIBGRG_DATA_POS;
249 
250 	dIV = grg_get_block_size_static (gctx->crypt_algo);
251 	IV = grg_memdup (tmp, dIV);
252 	if (!IV){
253 		return GRG_MEM_ALLOCATION_ERR;
254 	}
255 
256 	tmp += dIV;
257 	len -= dIV;
258 
259 	ecdata = grg_memdup (tmp, len);
260 	if (!ecdata)
261 	{
262 		grg_unsafe_free (IV);
263 		return GRG_MEM_ALLOCATION_ERR;
264 	}
265 
266 	curdata = ecdata;
267 	curlen = len;
268 
269 	//decrypts the encrypted data
270 	mod = mcrypt_module_open (grg2mcrypt (gctx->crypt_algo), NULL,
271 				  MCRYPT_CFB, NULL);
272 
273 	if (mod == MCRYPT_FAILED)
274 	{
275 		grg_unsafe_free (ecdata);
276 		grg_unsafe_free (IV);
277 		return GRG_READ_ENC_INIT_ERR;
278 	}
279 
280 	key = select_key (gctx, keystruct, &keylen);
281 	if (!key)
282 	{
283 		grg_unsafe_free (ecdata);
284 		grg_unsafe_free (IV);
285 		return GRG_MEM_ALLOCATION_ERR;
286 	}
287 
288 	grg_XOR_mem (key, keylen, IV, dIV);
289 
290 	mcrypt_generic_init (mod, key, keylen, IV);
291 	grg_free (gctx, key, keylen);
292 	key = NULL;
293 	grg_unsafe_free (IV);
294 
295 	mdecrypt_generic (mod, ecdata, len);
296 
297 	mcrypt_generic_deinit (mod);
298 	mcrypt_module_close (mod);
299 
300 	//checks the 2nd CRC32
301 
302 	CRC32b = grg_memdup (ecdata, LIBGRG_CRC_LEN);
303 	if (!CRC32b)
304 	{
305 		grg_unsafe_free (ecdata);
306 		return GRG_MEM_ALLOCATION_ERR;
307 	}
308 
309 	curdata += LIBGRG_CRC_LEN;
310 	curlen -= LIBGRG_CRC_LEN;
311 
312 	if (!compare_CRC32 (CRC32b, curdata, curlen))
313 	{
314 		grg_unsafe_free (ecdata);
315 		grg_unsafe_free (CRC32b);
316 		return GRG_READ_PWD_ERR;
317 	}
318 
319 	grg_unsafe_free (CRC32b);
320 
321 	//reads the uncompressed data length
322 
323 	dimdata = grg_memdup (curdata, LIBGRG_DATA_DIM_LEN);
324 	if (!dimdata)
325 	{
326 		grg_unsafe_free (ecdata);
327 		return GRG_MEM_ALLOCATION_ERR;
328 	}
329 
330 	curdata += LIBGRG_DATA_DIM_LEN;
331 	curlen -= LIBGRG_DATA_DIM_LEN;
332 
333 	oDim = grg_char2long (dimdata);
334 
335 	grg_free (gctx, dimdata, LIBGRG_DATA_DIM_LEN);
336 	dimdata = NULL;
337 
338 	//uncompress the final data
339 	if (gctx->comp_lvl)
340 	{
341 		unsigned char *tmpData = (unsigned char *) malloc (oDim);
342 
343 		if (!tmpData)
344 		{
345 			grg_unsafe_free (ecdata);
346 			return GRG_MEM_ALLOCATION_ERR;
347 		}
348 
349 		if (gctx->comp_algo)	//bz2
350 			err = BZ2_bzBuffToBuffDecompress ((unsigned char *)
351 							  tmpData, (unsigned int *) &oDim,
352 							  (unsigned char *) curdata, curlen,
353 							  USE_BZ2_SMALL_MEM, 0);
354 		else		//zlib
355 			err = uncompress (tmpData, &oDim, curdata, curlen);
356 
357 		if (err < 0)
358 		{
359 			grg_free (gctx, tmpData, oDim);
360 			tmpData = NULL;
361 			grg_unsafe_free (ecdata);
362 			return GRG_READ_COMP_ERR;
363 		}
364 
365 		*origData = grg_memconcat (2, tmpData, oDim, "", 1);
366 
367 		grg_free (gctx, tmpData, oDim);
368 		tmpData = NULL;
369 	}
370 	else
371 		*origData = grg_memconcat (2, curdata, oDim, "", 1);
372 
373 	grg_unsafe_free (ecdata);
374 
375 	if (!*origData){
376 		return GRG_MEM_ALLOCATION_ERR;
377 	}
378 
379 	if (origDim != NULL)
380 		*origDim = oDim;
381 
382 	return GRG_OK;
383 }
384 
385 int
grg_encrypt_mem(const GRG_CTX gctx,const GRG_KEY keystruct,void ** mem,long * memDim,const unsigned char * origData,const long origDim)386 grg_encrypt_mem (const GRG_CTX gctx, const GRG_KEY keystruct, void **mem,
387 		 long *memDim, const unsigned char *origData,
388 		 const long origDim)
389 {
390 	unsigned char *compData, *chunk, *toCRC1, *CRC1, *toEnc, *key, *IV,
391 		*toCRC2, *CRC2, algo;
392 	unsigned int dIV, dKey, err;
393 	long compDim, uncDim;
394 	MCRYPT mod;
395 
396 	if (!gctx || !keystruct || !origData)
397 			return GRG_ARGUMENT_ERR;
398 
399 	uncDim = (origDim < 0) ? strlen (origData) : origDim;
400 
401 	if (gctx->comp_lvl)
402 	{
403 		if (gctx->comp_algo)	//bz2
404 			compDim = (long) ((((float) uncDim) * 1.01) + 600);
405 		else		//libz
406 			compDim = (long) ((((float) uncDim) + 12) * 1.01);
407 
408 		compData = (char *) malloc (compDim);
409 		if (!compData)
410 			return GRG_MEM_ALLOCATION_ERR;
411 
412 		//compress the data
413 		if (gctx->comp_algo)	//bz2
414 			err = BZ2_bzBuffToBuffCompress (compData,
415 							(unsigned int *)
416 							&compDim,
417 							(unsigned char *)
418 							origData, uncDim,
419 							gctx->comp_lvl * 3, 0,
420 							0);
421 		else
422 			err = compress2 (compData, &compDim, origData, uncDim,
423 					 gctx->comp_lvl * 3);
424 
425 		if (err < 0)
426 		{
427 			grg_free (gctx, compData, compDim);
428 			compData = NULL;
429 			compDim = 0;
430 			return GRG_WRITE_COMP_ERR;
431 		}
432 	}
433 	else
434 	{
435 		compDim = uncDim;
436 		compData = grg_memdup (origData, uncDim);
437 		if (!compData)
438 			return GRG_MEM_ALLOCATION_ERR;
439 	}
440 
441 	chunk = grg_long2char (uncDim);
442 
443 	//adds the CRC32 and DATA_LEN field
444 	toCRC1 = grg_memconcat (2, chunk, LIBGRG_DATA_DIM_LEN, compData,
445 				compDim);
446 
447 	grg_free (gctx, chunk, LIBGRG_DATA_DIM_LEN);
448 	chunk = NULL;
449 	grg_free (gctx, compData, compDim);
450 	compData = NULL;
451 
452 	if (!toCRC1)
453 		return GRG_MEM_ALLOCATION_ERR;
454 
455 	compDim += LIBGRG_DATA_DIM_LEN;
456 
457 	CRC1 = get_CRC32 (toCRC1, compDim);
458 
459 	toEnc = grg_memconcat (2, CRC1, LIBGRG_CRC_LEN, toCRC1, compDim);
460 
461 	grg_free (gctx, CRC1, LIBGRG_CRC_LEN);
462 	CRC1 = NULL;
463 	grg_free (gctx, toCRC1, compDim);
464 	toCRC1 = NULL;
465 
466 	if (!toEnc)
467 		return GRG_MEM_ALLOCATION_ERR;
468 
469 	compDim += LIBGRG_CRC_LEN;
470 
471 	//encrypts the data
472 	mod = mcrypt_module_open (grg2mcrypt (gctx->crypt_algo), NULL,
473 				  MCRYPT_CFB, NULL);
474 
475 	if (mod == MCRYPT_FAILED)
476 	{
477 		grg_free (gctx, toEnc, compDim);
478 		toEnc = NULL;
479 		return GRG_WRITE_ENC_INIT_ERR;
480 	}
481 
482 	dIV = mcrypt_enc_get_iv_size (mod);
483 	IV = grg_rnd_seq (gctx, dIV);
484 	if (!IV)
485 	{
486 		grg_free (gctx, toEnc, compDim);
487 		toEnc = NULL;
488 		return GRG_MEM_ALLOCATION_ERR;
489 	}
490 
491 	key = select_key (gctx, keystruct, &dKey);
492 	if (!key)
493 	{
494 		grg_unsafe_free (IV);
495 		grg_free (gctx, toEnc, compDim);
496 		toEnc = NULL;
497 		return GRG_MEM_ALLOCATION_ERR;
498 	}
499 
500 	grg_XOR_mem (key, dKey, IV, dIV);
501 
502 	err = mcrypt_generic_init (mod, key, dKey, IV);
503 
504 	grg_free (gctx, key, dKey);
505 	key = NULL;
506 
507 	if (err < 0)
508 	{
509 		grg_unsafe_free (IV);
510 		grg_free (gctx, toEnc, compDim);
511 		toEnc = NULL;
512 		return GRG_WRITE_ENC_INIT_ERR;
513 	}
514 
515 	mcrypt_generic (mod, toEnc, compDim);
516 
517 	mcrypt_generic_deinit (mod);
518 	mcrypt_module_close (mod);
519 
520 	//adds algorithm and salt
521 
522 	algo = (unsigned char) (gctx->crypt_algo | gctx->hash_algo | gctx->
523 				comp_algo | gctx->comp_lvl);
524 
525 	toCRC2 = grg_memconcat (3, &algo, LIBGRG_ALGO_LEN, IV, dIV, toEnc,
526 				compDim);
527 
528 	grg_unsafe_free (IV);
529 	grg_free (gctx, toEnc, compDim);
530 	toEnc = NULL;
531 
532 	if (!toCRC2)
533 		return GRG_MEM_ALLOCATION_ERR;
534 
535 	compDim += LIBGRG_ALGO_LEN + dIV;
536 
537 	//calculates the CRC32
538 
539 	CRC2 = get_CRC32 (toCRC2, compDim);
540 
541 	//writes it all
542 
543 	*memDim = LIBGRG_ALGO_POS + compDim;
544 	*mem = malloc (*memDim);
545 	if (!*mem){
546 		grg_free (gctx, CRC2, LIBGRG_CRC_LEN);
547 		CRC2 = NULL;
548 		grg_free (gctx, toCRC2, compDim);
549 		toCRC2 = NULL;
550 		return GRG_MEM_ALLOCATION_ERR;
551 	}
552 
553 	memcpy (((char *) *mem), gctx->header, HEADER_LEN);
554 	((char *) *mem)[HEADER_LEN] = LIBGRG_FILE_VERSION + '0';
555 	memcpy (((char *) *mem) + HEADER_LEN + LIBGRG_FILE_VERSION_LEN, CRC2,
556 		LIBGRG_CRC_LEN);
557 	grg_free (gctx, CRC2, LIBGRG_CRC_LEN);
558 	CRC2 = NULL;
559 	memcpy (((char *) *mem) + LIBGRG_ALGO_POS, toCRC2, compDim);
560 	grg_free (gctx, toCRC2, compDim);
561 	toCRC2 = NULL;
562 
563 	return GRG_OK;
564 }
565 
566 int
grg_validate_file_direct(const GRG_CTX gctx,const int fd)567 grg_validate_file_direct (const GRG_CTX gctx, const int fd)
568 {
569 	int ret, len;
570 	void *mem;
571 
572 	if (fd < 0)
573 		return GRG_READ_FILE_ERR;
574 
575 	if (!gctx)
576 		return GRG_ARGUMENT_ERR;
577 
578 	len = lseek (fd, 0, SEEK_END);
579 	mem = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
580 
581 	if (mem == MAP_FAILED)
582 		return GRG_READ_MMAP_ERR;
583 
584 	ret = validate_mem (gctx, mem, len);
585 
586 	munmap (mem, len);
587 
588 	if (ret > 0)
589 		return GRG_OK;
590 	return ret;
591 }
592 
593 int
grg_validate_file(const GRG_CTX gctx,const unsigned char * path)594 grg_validate_file (const GRG_CTX gctx, const unsigned char *path)
595 {
596 	int fd, res;
597 
598 	if (!gctx || !path)
599 		return GRG_ARGUMENT_ERR;
600 
601 	fd = open (path, O_RDONLY);
602 	res = grg_validate_file_direct (gctx, fd);
603 	close (fd);
604 
605 	return res;
606 }
607 
608 int
grg_update_gctx_from_file_direct(GRG_CTX gctx,const int fd)609 grg_update_gctx_from_file_direct (GRG_CTX gctx, const int fd)
610 {
611 	int ret, len;
612 	void *mem;
613 
614 	if (fd < 0)
615 		return GRG_READ_FILE_ERR;
616 
617 	if (!gctx)
618 		return GRG_ARGUMENT_ERR;
619 
620 	len = lseek (fd, 0, SEEK_END);
621 	mem = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
622 
623 	if (mem == MAP_FAILED)
624 		return GRG_READ_MMAP_ERR;
625 
626 	ret = validate_mem (gctx, mem, len);
627 
628 	if (ret < 0)
629 	{
630 		munmap (mem, len);
631 		return ret;
632 	}
633 
634 	update_gctx_from_mem (gctx, ((char *) mem)[LIBGRG_ALGO_POS]);
635 
636 	munmap (mem, len);
637 
638 	return GRG_OK;
639 }
640 
641 int
grg_update_gctx_from_file(GRG_CTX gctx,const unsigned char * path)642 grg_update_gctx_from_file (GRG_CTX gctx, const unsigned char *path)
643 {
644 	int fd, res;
645 
646 	if (!gctx || !path)
647 		return GRG_ARGUMENT_ERR;
648 
649 	fd = open (path, O_RDONLY);
650 	res = grg_update_gctx_from_file_direct (gctx, fd);
651 	close (fd);
652 
653 	return res;
654 }
655 
656 int
grg_decrypt_file_direct(const GRG_CTX gctx,const GRG_KEY keystruct,const int fd,unsigned char ** origData,long * origDim)657 grg_decrypt_file_direct (const GRG_CTX gctx, const GRG_KEY keystruct,
658 			 const int fd, unsigned char **origData, long *origDim)
659 {
660 	int ret, len;
661 	void *mem;
662 
663 	if (fd < 0)
664 		return GRG_READ_FILE_ERR;
665 
666 	if (!gctx || !keystruct)
667 		return GRG_ARGUMENT_ERR;
668 
669 	len = lseek (fd, 0, SEEK_END);
670 	mem = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
671 
672 	if (mem == MAP_FAILED)
673 		return GRG_READ_MMAP_ERR;
674 
675 	ret = validate_mem (gctx, mem, len);
676 
677 	if (ret < 0)
678 	{
679 		munmap (mem, len);
680 		return ret;
681 	}
682 
683 	update_gctx_from_mem (gctx, ((char *) mem)[LIBGRG_ALGO_POS]);
684 
685 	ret = decrypt_mem (gctx, keystruct, mem, len, origData, origDim);
686 
687 	munmap (mem, len);
688 
689 	return ret;
690 }
691 
692 int
grg_decrypt_file(const GRG_CTX gctx,const GRG_KEY keystruct,const unsigned char * path,unsigned char ** origData,long * origDim)693 grg_decrypt_file (const GRG_CTX gctx, const GRG_KEY keystruct,
694 		  const unsigned char *path, unsigned char **origData,
695 		  long *origDim)
696 {
697 	int fd, res;
698 
699 	if (!gctx || !keystruct || !path)
700 		return GRG_ARGUMENT_ERR;
701 
702 	fd = open (path, O_RDONLY);
703 	res = grg_decrypt_file_direct (gctx, keystruct, fd, origData,
704 				       origDim);
705 	close (fd);
706 
707 	return res;
708 }
709 
710 int
grg_encrypt_file_direct(const GRG_CTX gctx,const GRG_KEY keystruct,const int fd,const unsigned char * origData,const long origDim)711 grg_encrypt_file_direct (const GRG_CTX gctx, const GRG_KEY keystruct,
712 			 const int fd, const unsigned char *origData,
713 			 const long origDim)
714 {
715 	int ret;
716 	void *mem;
717 	long memDim;
718 
719 	if (!gctx || !keystruct || !origData)
720 		return GRG_ARGUMENT_ERR;
721 
722 	ret = grg_encrypt_mem (gctx, keystruct, &mem, &memDim, origData,
723 			       origDim);
724 
725 	if (ret < 0)
726 		return ret;
727 
728 	if (fd < 3)
729 	{
730 		grg_unsafe_free (mem);
731 		return GRG_WRITE_FILE_ERR;
732 	}
733 
734 	write (fd, mem, memDim);
735 
736 	fsync (fd);
737 
738 	//closing
739 	grg_unsafe_free (mem);
740 
741 	return GRG_OK;
742 }
743 
744 int
grg_encrypt_file(const GRG_CTX gctx,const GRG_KEY keystruct,const unsigned char * path,const unsigned char * origData,const long origDim)745 grg_encrypt_file (const GRG_CTX gctx, const GRG_KEY keystruct,
746 		  const unsigned char *path, const unsigned char *origData,
747 		  const long origDim)
748 {
749 	int fd, res;
750 
751 	if (!gctx || !keystruct || !path || !origData)
752 		return GRG_ARGUMENT_ERR;
753 
754 	fd = open (path, O_WRONLY | O_CREAT | O_TRUNC,
755 		   S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
756 
757 	res = grg_encrypt_file_direct (gctx, keystruct, fd, origData,
758 				       origDim);
759 	close (fd);
760 
761 	if (res < 0)
762 		unlink (path);
763 
764 	return res;
765 }
766 
767 
768 int
grg_validate_mem(const GRG_CTX gctx,const void * mem,const long memDim)769 grg_validate_mem (const GRG_CTX gctx, const void *mem, const long memDim)
770 {
771 	int ret;
772 
773 	if (!mem || !gctx)
774 			return GRG_ARGUMENT_ERR;
775 
776 	ret = validate_mem (gctx, mem, memDim);
777 
778 	if (ret > 0)
779 		return GRG_OK;
780 
781 	return ret;
782 }
783 
784 int
grg_update_gctx_from_mem(GRG_CTX gctx,const void * mem,const long memDim)785 grg_update_gctx_from_mem (GRG_CTX gctx, const void *mem, const long memDim)
786 {
787 	int ret = validate_mem (gctx, mem, memDim);
788 	if (ret < 0)
789 		return ret;
790 
791 	update_gctx_from_mem (gctx, ((char *) mem)[LIBGRG_ALGO_POS]);
792 
793 	return GRG_OK;
794 }
795 
796 int
grg_decrypt_mem(const GRG_CTX gctx,const GRG_KEY keystruct,const void * mem,const long memDim,unsigned char ** origData,long * origDim)797 grg_decrypt_mem (const GRG_CTX gctx, const GRG_KEY keystruct, const void *mem,
798 		 const long memDim, unsigned char **origData, long *origDim)
799 {
800 	int ret;
801 
802 	if (!mem || !gctx || !keystruct)
803 			return GRG_ARGUMENT_ERR;
804 
805 	ret = validate_mem (gctx, mem, memDim);
806 
807 	if (ret < 0)
808 		return ret;
809 
810 	update_gctx_from_mem (gctx, ((char *) mem)[LIBGRG_ALGO_POS]);
811 
812 	ret = decrypt_mem (gctx, keystruct, mem, memDim, origData, origDim);
813 
814 	return ret;
815 }
816