libidav/crypto.c

changeset 349
0b4ecadaf3f9
parent 267
171498cb2137
child 354
067ea2315a8a
equal deleted inserted replaced
348:b79fb94f9e0a 349:0b4ecadaf3f9
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2016 Olaf Wintermann. All rights reserved. 4 * Copyright 2017 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
27 */ 27 */
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <unistd.h>
33 #include <fcntl.h>
32 #include <libidav/utils.h> 34 #include <libidav/utils.h>
33 #include <openssl/rand.h>
34 35
35 #include "crypto.h" 36 #include "crypto.h"
37
38 /* -------------------- OpenSSL Crypto Functions -------------------- */
39 #ifdef DAV_USE_OPENSSL
36 40
37 #if OPENSSL_VERSION_NUMBER < 10000000 41 #if OPENSSL_VERSION_NUMBER < 10000000
38 42
39 static EVP_CIPHER_CTX* create_evp_cipher_ctx() { 43 static EVP_CIPHER_CTX* create_evp_cipher_ctx() {
40 EVP_CIPHER_CTX *ctx = malloc(sizeof(EVP_CIPHER_CTX)); 44 EVP_CIPHER_CTX *ctx = malloc(sizeof(EVP_CIPHER_CTX));
322 *length = outlen + f; 326 *length = outlen + f;
323 return (char*)out; 327 return (char*)out;
324 } 328 }
325 329
326 330
327 void dav_get_hash(SHA256_CTX *sha256, unsigned char *buf) { 331 void dav_get_hash(SHA_CTX *sha256, unsigned char *buf) {
328 SHA256_Final((unsigned char*)buf, sha256); 332 SHA256_Final((unsigned char*)buf, sha256);
329 } 333 }
334
335 #endif
336
337
338 /* -------------------- Apple Crypto Functions -------------------- */
339 #ifdef __APPLE__
340
341 #define RANDOM_BUFFER_LENGTH 256
342 static char randbuf[RANDOM_BUFFER_LENGTH];
343 static int rbufpos = RANDOM_BUFFER_LENGTH;
344
345 int dav_rand_bytes(unsigned char *buf, size_t len) {
346 if(len + rbufpos > RANDOM_BUFFER_LENGTH) {
347 int devr = open("/dev/urandom", O_RDONLY);
348 if(devr == -1) {
349 return 1;
350 }
351
352 if(read(devr, randbuf, RANDOM_BUFFER_LENGTH) < RANDOM_BUFFER_LENGTH) {
353 close(devr);
354 return 1;
355 }
356
357 rbufpos = 0;
358 if(len > RANDOM_BUFFER_LENGTH) {
359 int err = 0;
360 if(read(devr, buf, len) < len) {
361 err = 1;
362 }
363 close(devr);
364 return err;
365 }
366
367 close(devr);
368 }
369
370 char *r = randbuf;
371 memcpy(buf, r + rbufpos, len);
372 rbufpos += len;
373
374 return 0;
375 }
376
377 AESDecrypter* aes_decrypter_new(DavKey *key, void *stream, dav_write_func write_func) {
378 AESDecrypter *dec = calloc(1, sizeof(AESDecrypter));
379 CC_SHA256_Init(&dec->sha256);
380 dec->stream = stream;
381 dec->write = write_func;
382 dec->key = key;
383 dec->init = 0;
384 dec->ivpos = 0;
385
386 return dec;
387 }
388
389
390 void aes_decrypter_init(AESDecrypter *dec) {
391 //EVP_CIPHER_CTX_init(&dec->ctx);
392 dec->init = 1;
393
394 CCCryptorRef cryptor;
395 CCCryptorStatus status;
396 if(dec->key->type == DAV_KEY_AES128) {
397 status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, dec->key->data, dec->key->length, dec->ivtmp, &cryptor);
398 } else if(dec->key->type == DAV_KEY_AES256) {
399 status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, dec->key->data, dec->key->length, dec->ivtmp, &cryptor);
400 } else {
401 fprintf(stderr, "unknown key type\n");
402 exit(-1);
403 }
404 dec->ctx = cryptor;
405 }
406
407 size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) {
408 int len = s*n;
409 if(!dec->init) {
410 size_t n = 16 - dec->ivpos;
411 size_t cp = n > len ? len : n;
412 memcpy(dec->ivtmp + dec->ivpos, buf, cp);
413 dec->ivpos += cp;
414 if(dec->ivpos >= 16) {
415 aes_decrypter_init(dec);
416 }
417 if(len == cp) {
418 return len;
419 } else {
420 buf = (char*)buf + cp;
421 len -= cp;
422 }
423 }
424
425 int outlen = len + 16;
426 unsigned char *out = malloc(outlen);
427
428 CCCryptorStatus status;
429 size_t avail = outlen;
430 size_t moved = 0;
431 status = CCCryptorUpdate(dec->ctx, buf, len, out, avail, &moved);
432
433 ssize_t wlen = dec->write(out, 1, moved, dec->stream);
434 CC_SHA256_Update(&dec->sha256, out, wlen);
435 free(out);
436 return (s*n) / s;
437 }
438
439 void aes_decrypter_shutdown(AESDecrypter *dec) {
440 if(dec->init) {
441 void *out = malloc(128);
442 size_t len = 0;
443 //EVP_DecryptFinal_ex(dec->ctx, out, &len);
444 CCCryptorFinal(dec->ctx, out, 128, &len);
445
446
447 dec->write(out, 1, len, dec->stream);
448 CC_SHA256_Update(&dec->sha256, out, len);
449 free(out);
450 //EVP_CIPHER_CTX_cleanup(&dec->ctx);
451 //EVP_CIPHER_CTX_free(dec->ctx);
452 }
453 }
454
455 void aes_decrypter_close(AESDecrypter *dec) {
456
457 }
458
459 AESEncrypter* aes_encrypter_new(DavKey *key, void *stream, dav_read_func read_func) {
460 unsigned char *iv = malloc(16);
461 if(dav_rand_bytes(iv, 16)) {
462 return NULL;
463 }
464
465 CCCryptorRef cryptor;
466 CCCryptorStatus status;
467 if(key->type == DAV_KEY_AES128) {
468 status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key->data, key->length, iv, &cryptor);
469 } else if(key->type == DAV_KEY_AES256) {
470 status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key->data, key->length, iv, &cryptor);
471 } else {
472 free(iv);
473 return NULL;
474 }
475
476 AESEncrypter *enc = malloc(sizeof(AESEncrypter));
477 enc->ctx = cryptor;
478 CC_SHA256_Init(&enc->sha256);
479 enc->stream = stream;
480 enc->read = read_func;
481 enc->tmp = NULL;
482 enc->tmplen = 0;
483 enc->tmpoff = 0;
484 enc->end = 0;
485 enc->iv = iv;
486 enc->ivlen = 16;
487
488 return enc;
489 }
490
491 size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) {
492 size_t len = s*n;
493 if(enc->tmp) {
494 size_t tmp_diff = enc->tmplen - enc->tmpoff;
495 size_t cp_len = tmp_diff > len ? len : tmp_diff;
496 memcpy(buf, enc->tmp + enc->tmpoff, cp_len);
497 enc->tmpoff += cp_len;
498 if(enc->tmpoff >= enc->tmplen) {
499 free(enc->tmp);
500 enc->tmp = NULL;
501 enc->tmplen = 0;
502 enc->tmpoff = 0;
503 }
504 return cp_len / s;
505 }
506
507 if(enc->end) {
508 return 0;
509 }
510
511 void *in = malloc(len);
512 size_t in_len = enc->read(in, 1, len, enc->stream);
513
514 CC_SHA256_Update(&enc->sha256, in, in_len);
515
516 unsigned char *out = NULL;
517 size_t outlen = 0;
518 size_t ivl = enc->ivlen;
519 if(in_len != 0) {
520 outlen = len + 16;
521 out = malloc(outlen + ivl);
522 if(enc->iv) {
523 memcpy(out, enc->iv, ivl);
524 }
525
526 CCCryptorStatus status;
527 size_t avail = outlen;
528 status = CCCryptorUpdate(enc->ctx, in, in_len, out + ivl, avail, &outlen);
529
530 free(in);
531 } else {
532 out = malloc(32);
533 CCCryptorStatus status;
534 size_t avail = outlen;
535 status = CCCryptorFinal(enc->ctx, out, 32, &outlen);
536 enc->end = 1;
537 free(in);
538 }
539 enc->tmp = (char*)out;
540 enc->tmplen = outlen + ivl;
541 enc->tmpoff = 0;
542
543 if(enc->iv) {
544 free(enc->iv);
545 enc->iv = NULL;
546 enc->ivlen = 0;
547 }
548
549 return aes_read(buf, s, n, enc);
550 }
551
552 void aes_encrypter_close(AESEncrypter *enc) {
553 if(enc->tmp) {
554 free(enc->tmp);
555 }
556 if(enc->iv) {
557 free(enc->iv);
558 }
559 // TODO: cleanup cryptor
560 free(enc);
561 }
562
563 char* aes_encrypt(char *in, size_t len, DavKey *key) {
564 unsigned char iv[16];
565 if(dav_rand_bytes(iv, 16)) {
566 return NULL;
567 }
568
569 CCCryptorRef cryptor;
570 CCCryptorStatus status;
571 if(key->type == DAV_KEY_AES128) {
572 status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key->data, key->length, iv, &cryptor);
573 } else if(key->type == DAV_KEY_AES256) {
574 status = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key->data, key->length, iv, &cryptor);
575 } else {
576 return NULL;
577 }
578
579 if(status != kCCSuccess) {
580 return NULL;
581 }
582
583 int buflen = len + 64;
584 char *buf = calloc(1, buflen);
585 memcpy(buf, iv, 16);
586
587 int pos = 16;
588 size_t avail = buflen - 16;
589 size_t moved;
590 char *out = buf + 16;
591
592 status = CCCryptorUpdate(cryptor, in,
593 len, out, avail,
594 &moved);
595 if(status != kCCSuccess) {
596 free(buf);
597 return NULL;
598 }
599
600 pos += moved;
601 avail -= moved;
602 out += moved;
603
604 status = CCCryptorFinal(cryptor, out, avail, &moved);
605 if(status != kCCSuccess) {
606 free(buf);
607 return NULL;
608 }
609
610 pos += moved;
611
612 char *b64enc = util_base64encode(buf, pos);
613 free(buf);
614
615 return b64enc;
616 }
617
618 char* aes_decrypt(char *in, size_t *len, DavKey *key) {
619 int inlen;
620 unsigned char *buf = (unsigned char*)util_base64decode_len(in, &inlen);
621
622 CCCryptorRef cryptor;
623 CCCryptorStatus status;
624 if(key->type == DAV_KEY_AES128) {
625 status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key->data, key->length, buf, &cryptor);
626 } else if(key->type == DAV_KEY_AES256) {
627 status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key->data, key->length, buf, &cryptor);
628 } else {
629 free(buf);
630 return NULL;
631 }
632
633 if(status != kCCSuccess) {
634 free(buf);
635 return NULL;
636 }
637
638 char *out = malloc(inlen + 1);
639 size_t outavail = inlen;
640 size_t outlen = 0;
641
642 unsigned char *inbuf = buf + 16;
643 inlen -= 16;
644
645 size_t moved = 0;
646 status = CCCryptorUpdate(cryptor, inbuf, inlen, out, outavail, &moved);
647 if(status != kCCSuccess) {
648 free(buf);
649 free(out);
650 // TODO cryptor
651 return NULL;
652 }
653
654 outlen += moved;
655 outavail -= moved;
656
657 status = CCCryptorFinal(cryptor, out + outlen, outavail, &moved);
658 if(status != kCCSuccess) {
659 free(buf);
660 free(out);
661 // TODO cryptor
662 return NULL;
663 }
664
665 outlen += moved;
666 out[outlen] = 0;
667
668 *len = outlen;
669 return out;
670 }
671
672 void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf) {
673 CC_SHA256_Final(buf, sha256);
674 }
675
676 #endif

mercurial