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