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 |