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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
;;; guile-gcrypt --- crypto tooling for guile
;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
;;; Copyright © 2019 Mathieu Othacehe <m.othacehe@gmail.com>
;;;
;;; This file is part of guile-gcrypt.
;;;
;;; guile-gcrypt 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.
;;;
;;; guile-gcrypt 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 guile-gcrypt. If not, see <http://www.gnu.org/licenses/>.
(define-module (gcrypt random)
#:use-module (gcrypt internal)
#:use-module (gcrypt base64)
#:use-module (rnrs bytevectors)
#:use-module (system foreign)
#:use-module (ice-9 match)
#:export (%gcry-weak-random
%gcry-strong-random
%gcry-very-strong-random
gen-random-bv
random-token))
(define %gcry-weak-random 0) ; not used
(define %gcry-strong-random 1)
(define %gcry-very-strong-random 2)
(define %gcry-randomize
(libgcrypt->procedure void
"gcry_randomize"
`(* ,size_t ,int))) ; buffer, length, level
(define* (gen-random-bv #:optional (bv-length 50)
(level %gcry-strong-random))
(let* ((bv (make-bytevector bv-length))
(bv-ptr (bytevector->pointer bv)))
(%gcry-randomize bv-ptr bv-length %gcry-strong-random)
bv))
(define %gcry-create-nonce
(libgcrypt->procedure void "gcry_create_nonce"
`(* ,size_t))) ; buffer, length
(define* (gen-random-nonce #:optional (bv-length 50))
(let* ((bv (make-bytevector bv-length))
(bv-ptr (bytevector->pointer bv)))
(%gcry-create-nonce bv-ptr bv-length)
bv))
(define* (random-token #:optional (bv-length 30)
(type 'strong))
"Generate a random token.
Generates a token of bytevector BV-LENGTH, default 30.
The default TYPE is 'strong. Possible values are:
- strong: Uses libgcrypt's gcry_randomize procedure with level
GCRY_STRONG_RANDOM (\"use this level for session keys and similar
purposes\").
- very-strong: Also uses libgcrypt's gcry_randomize procedure with level
GCRY_VERY_STRONG_RANDOM (\"Use this level for long term key material\")
- nonce: Uses libgcrypt's gcry_xcreate_nonce, whose documentation I'll
just quote inline:
Fill BUFFER with LENGTH unpredictable bytes. This is commonly
called a nonce and may also be used for initialization vectors and
padding. This is an extra function nearly independent of the other
random function for 3 reasons: It better protects the regular
random generator's internal state, provides better performance and
does not drain the precious entropy pool."
(let ((bv (match type
('strong
(gen-random-bv bv-length %gcry-strong-random))
('very-strong
(gen-random-bv bv-length %gcry-very-strong-random))
('nonce
(gen-random-nonce bv-length)))))
(base64-encode bv 0 bv-length #f #t base64url-alphabet)))
|