Update of /project/crypticl/cvsroot/crypticl/src In directory clnet:/tmp/cvs-serv1593
Modified Files: utilities.lisp random.lisp aes.lisp Log Message: Backup of initial version of secure random generator with aes in counter mode.
--- /project/crypticl/cvsroot/crypticl/src/utilities.lisp 2007/01/22 22:45:32 1.9 +++ /project/crypticl/cvsroot/crypticl/src/utilities.lisp 2007/01/23 23:55:39 1.10 @@ -73,14 +73,9 @@
(defun int-as-octet-vector-add (ov n) - "Add n to octet vector ov." + "Add n to octet vector ov and keep size of octet vector." (integer-to-octet-vector (+ (octet-vector-to-integer ov) n) :vector ov))
-(defun foo (data ctr) - (aes-crypt-octet-vector data #16(0) 'ctr nil ctr) - (int-as-octet-vector-add ctr 1) - (hex data)) - (defun hex (ov) (octet-vector-to-hex-string ov))
@@ -171,8 +166,7 @@ (unless out (setf out (make-array size :element-type '(unsigned-byte 8)))) (dotimes (i size out) - (setf (aref out (+ out-start i)) (aref in (+ start i)))))) - + (setf (aref out (+ out-start i)) (aref in (+ start i))))))
(defun concat (&rest args) "Concatenates strings and vectors. --- /project/crypticl/cvsroot/crypticl/src/random.lisp 2007/01/23 21:20:36 1.6 +++ /project/crypticl/cvsroot/crypticl/src/random.lisp 2007/01/23 23:55:39 1.7 @@ -161,3 +161,96 @@ (if (= 0 (mod bitsize 8)) n (dpb 0 (byte (- 8 (mod bitsize 8)) bitsize) n)))) + + + +;;;; +;;;; AES version +;;;; +;;;; Based on Fortuna from Practical Cryptography. +;;;; +(defparameter *random-secure-obj-aes* nil + "State for the random number generator") + +(defun random-secure-octets-aes (size) + "Returns size pseudorandom octets from a cryptographically secure PRNG." + (unless *random-secure-obj-aes* + (setf *random-secure-obj-aes* (make-SecurePRNG-AES))) + + (SecurePRNG-octets-aes *random-secure-obj-aes* size)) + +(defclass SecurePRNG-AES () + ((key + :accessor key + :initform #16(0)) + (ctr + :accessor ctr + :initform #16(0))) + (:documentation "Cryptographically secure pseudo random number generator.")) + +(defun make-SecurePRNG-AES () + "Constructor for the Secure-PRNG class. Assumes that X bits secret/seed is enough." + (let ((obj (make-instance 'SecurePRNG-AES))) + (format t "ctr after init = ~A~%" (hex (ctr obj))) + (reseed obj (high-entropy-octets 16)))) + +(defmethod reseed ((obj SecurePRNG-AES) new-seed) + "Reseed with byte array of high entropy bits." + (let ((hasher (make-SHA-256)) + (keysize (length (key obj)))) + ;; Concatenate old key with new seed and hash + (update hasher (key obj)) + (setf (key obj) (subseq (hash hasher new-seed) 0 keysize)) + ;; We run in counter mode so update counter + (inc-counter obj) + (format t "ctr in reseed = ~A~%" (hex (ctr obj))) + obj)) + +(defmethod inc-counter ((obj SecurePRNG-AES)) + (int-as-octet-vector-add (ctr obj) 1)) + +(defun set-seed-aes (new-seed) + "Reseed the global secure PRNG. + +The input should be high entropy bits, ideally 256 bits of entropy or more, +given as a bignum or a byte array." + (unless *random-secure-obj-aes* + (setf *random-secure-obj-aes* (make-SecurePRNG))) + (typecase new-seed + (integer (reseed *random-secure-obj-aes* + (integer-to-octet-vector new-seed))) + (vector (reseed *random-secure-obj-aes* new-seed)))) + +(defmethod SecurePRNG-octets-aes ((obj SecurePRNG-AES) size) + "Returns size pseudorandom octets from a cryptographically secure PRNG." + (let ((res (make-array size + :element-type '(unsigned-byte 8) + :initial-element 0)) + (tmp (make-array (length (ctr obj)) + :element-type '(unsigned-byte 8) + :initial-element 0)) + (ctr-size (length (ctr obj)))) + + (do* ((offset 0 (+ offset next)) + (leftover size (- leftover next)) + (next (min ctr-size leftover) (min ctr-size leftover))) + ((<= leftover 0)) + ;; the cipher overwrites the input buffer so we cannot use + ;; (ctr obj) directly. + (octet-vector-copy (ctr obj) 0 ctr-size tmp 0) + (aes-crypt-octet-vector tmp (key obj) 'ctr-onetime nil) + (octet-vector-copy tmp 0 next res offset) + (inc-counter obj)) + + res)) + + +(defun foo () + (setf *random-secure-obj-aes* (make-SecurePRNG-AES)) + (format t "ctr before = ~A~%" (hex (ctr *random-secure-obj-aes*))) + (format t "bytes = ~A~%"(hex (random-secure-octets-aes 16))) + (format t "ctr = ~A~%" (hex (ctr *random-secure-obj-aes*)))) + +(defun bar (&optional (size 16)) + (format t "bytes = ~A~%"(hex (random-secure-octets-aes size))) + (format t "ctr = ~A~%" (hex (ctr *random-secure-obj-aes*)))) --- /project/crypticl/cvsroot/crypticl/src/aes.lisp 2007/01/21 01:15:22 1.8 +++ /project/crypticl/cvsroot/crypticl/src/aes.lisp 2007/01/23 23:55:39 1.9 @@ -375,8 +375,17 @@ (aes-ecb-mode data round-key num-rounds doEncrypt)) ((eq mode 'cbc) (aes-cbc-mode data round-key num-rounds doEncrypt iv)) + ((eq mode 'ctr-onetime) + (aes-generate-one-time-pad-ctr data round-key num-rounds)) (t (error "No such mode ~A" mode)))))
+(defun aes-generate-one-time-pad-ctr (data round-key num-rounds) + "data is the counter" + (let ((encrypted-block (make-array '(4 4))) + (offset 0)) + (get-block encrypted-block data offset) + (aes-encrypt-block encrypted-block round-key num-rounds) + (copy-back-block encrypted-block data offset)))
(defun aes-cbc-mode (data round-key num-rounds doEncrypt iv)