Coverage report: /home/ellis/comp/ext/ironclad/src/ciphers/keystream.lisp

KindCoveredAll%
expression0175 0.0
branch020 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; keystream.lisp
2
 (in-package :crypto)
3
 
4
 (defun keystream-position (cipher &optional position)
5
   "Return or change the current POSITION within the key stream of a CIPHER."
6
   (let ((mode (mode cipher)))
7
     (cond
8
       ((typep mode 'ctr-mode)
9
        (let ((block-length (block-length cipher))
10
              (iv-position (iv-position mode))
11
              (keystream-blocks (keystream-blocks mode)))
12
          (if (null position)
13
              (if (zerop iv-position)
14
                  (* block-length keystream-blocks)
15
                  (+ (* block-length (1- keystream-blocks)) iv-position))
16
              (let ((iv (iv mode))
17
                    (buffer (make-array block-length :element-type '(unsigned-byte 8))))
18
                (multiple-value-bind (q r)
19
                    (truncate position block-length)
20
                  (if (< q keystream-blocks)
21
                      (decrement-counter-block iv (- keystream-blocks q))
22
                      (increment-counter-block iv (- q keystream-blocks)))
23
                  (setf (keystream-blocks mode) q)
24
                  (setf (iv-position mode) 0)
25
                  (encrypt-in-place cipher buffer :end r)
26
                  t)))))
27
 
28
       ((typep cipher 'chacha)
29
        (let ((state (chacha-state cipher)))
30
          (if (null position)
31
              (let ((counter (if (= (chacha-counter-size cipher) 1)
32
                                 (aref state 12)
33
                                 (+ (aref state 12) (ash (aref state 13) 32)))))
34
                (- (* 64 counter) (chacha-keystream-buffer-remaining cipher)))
35
              (let ((buffer (make-array 64 :element-type '(unsigned-byte 8))))
36
                (declare (dynamic-extent buffer))
37
                (multiple-value-bind (q r)
38
                    (truncate position 64)
39
                  (setf (aref state 12) (logand q #xffffffff))
40
                  (unless (= (chacha-counter-size cipher) 1)
41
                    (setf (aref state 13) (logand (ash q -32) #xffffffff)))
42
                  (setf (chacha-keystream-buffer-remaining cipher) 0)
43
                  (encrypt-in-place cipher buffer :end r)
44
                  t)))))
45
 
46
       ((typep cipher 'salsa20)
47
        (let ((state (salsa20-state cipher)))
48
          (if (null position)
49
              (let ((counter (+ (aref state 8) (ash (aref state 9) 32))))
50
                (- (* 64 counter) (salsa20-keystream-buffer-remaining cipher)))
51
              (let ((buffer (make-array 64 :element-type '(unsigned-byte 8))))
52
                (declare (dynamic-extent buffer))
53
                (multiple-value-bind (q r)
54
                    (truncate position 64)
55
                  (setf (aref state 8) (logand q #xffffffff))
56
                  (setf (aref state 9) (logand (ash q -32) #xffffffff))
57
                  (setf (salsa20-keystream-buffer-remaining cipher) 0)
58
                  (encrypt-in-place cipher buffer :end r)
59
                  t)))))
60
 
61
       (t
62
        nil))))