summaryrefslogtreecommitdiff
path: root/haunt/jakob/dynamic/aes.scm
blob: 11d481919d35971af219b8168a333a2b67080e3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;;; Copyright © 2019 - 2022 Jakob L. Kreuze <zerodaysfordays@sdf.org>
;;;
;;; This program is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program. If not, see
;;; <http://www.gnu.org/licenses/>.

(define-module (jakob dynamic aes)
  #:use-module (gcrypt random)
  #:use-module (system foreign)
  #:use-module (rnrs bytevectors)
  #:export (new-captcha))

(define %libnettle (dynamic-link "libnettle"))
(define %aes256-rounds 14)

(define %aes-key-size (/ 256 8))
(define %aes-block-size (/ 128 8))
(define %tex-aes-key (gen-random-bv %aes-key-size))

;; Assume `data' is a bytevector of length `%aes-block-size'.
(define (aes-256-encrypt key data)
  (let ((dest (make-bytevector %aes-block-size))
        (%ctx (make-c-struct (map (lambda (_) uint32) (iota (* 4 (+ 1 %aes256-rounds))))
                             (map (lambda (_) 0) (iota (* 4 (+ 1 %aes256-rounds))))))
        (%aes-256-encrypt
         (pointer->procedure void
                             (dynamic-func "nettle_aes256_encrypt" %libnettle)
                             (list '* size_t '* '*)))
        (%aes-256-set-encrypt-key
         (pointer->procedure void
                             (dynamic-func "nettle_aes256_set_encrypt_key" %libnettle)
                             (list '* '*))))
    (%aes-256-set-encrypt-key %ctx (bytevector->pointer %tex-aes-key))
    (%aes-256-encrypt %ctx %aes-block-size (bytevector->pointer dest) (bytevector->pointer data))
    dest))

(define (aes-256-decrypt key data)
  (let ((dest (make-bytevector %aes-block-size))
        (%ctx (make-c-struct (map (lambda (_) uint32) (iota (* 4 (+ 1 %aes256-rounds))))
                             (map (lambda (_) 0) (iota (* 4 (+ 1 %aes256-rounds))))))
        (%aes-256-decrypt
         (pointer->procedure void
                             (dynamic-func "nettle_aes256_decrypt" %libnettle)
                             (list '* size_t '* '*)))
        (%aes-256-set-decrypt-key
         (pointer->procedure void
                             (dynamic-func "nettle_aes256_set_decrypt_key" %libnettle)
                             (list '* '*))))
    (%aes-256-set-decrypt-key %ctx (bytevector->pointer %tex-aes-key))
    (%aes-256-decrypt %ctx %aes-block-size (bytevector->pointer dest) (bytevector->pointer data))
    dest))

;; (utf8->string (aes-256-decrypt %tex-aes-key (aes-256-encrypt %tex-aes-key (string->utf8 "AAAABBBBC hello!"))))
;; => "AAAABBBBC hello!"