Coverage report: /home/ellis/comp/ext/ironclad/src/aead/eax.lisp

KindCoveredAll%
expression0325 0.0
branch022 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; eax.lisp -- Encrypt then authenticate then translate
2
 (in-package :crypto)
3
 
4
 (defclass eax (aead-mode)
5
   ((cipher :accessor eax-cipher
6
            :initform nil)
7
    (mac-n :accessor eax-mac-n
8
           :initform nil)
9
    (mac-h :accessor eax-mac-h
10
           :initform nil)
11
    (mac-c :accessor eax-mac-c
12
           :initform nil)))
13
 
14
 (defmethod shared-initialize :after ((mode eax) slot-names &rest initargs &key key cipher-name initialization-vector &allow-other-keys)
15
   (declare (ignore slot-names initargs))
16
   (let* ((mac-n (if (or (null (eax-mac-n mode)) cipher-name)
17
                     (make-mac :cmac key cipher-name)
18
                     (reinitialize-instance (eax-mac-n mode) :key key)))
19
          (mac-h (if (or (null (eax-mac-h mode)) cipher-name)
20
                     (make-mac :cmac key cipher-name)
21
                     (reinitialize-instance (eax-mac-h mode) :key key)))
22
          (mac-c (if (or (null (eax-mac-c mode)) cipher-name)
23
                     (make-mac :cmac key cipher-name)
24
                     (reinitialize-instance (eax-mac-c mode) :key key)))
25
          (block-length (block-length (or cipher-name (eax-cipher mode))))
26
          (buffer (make-array block-length
27
                              :element-type '(unsigned-byte 8)
28
                              :initial-element 0)))
29
     (update-mac mac-n buffer)
30
     (update-mac mac-n initialization-vector)
31
     (setf (aref buffer (1- (length buffer))) 1)
32
     (update-mac mac-h buffer)
33
     (setf (aref buffer (1- (length buffer))) 2)
34
     (update-mac mac-c buffer)
35
     (let* ((n (produce-mac mac-n))
36
            (cipher (if (or (null (eax-cipher mode)) cipher-name)
37
                        (make-cipher cipher-name
38
                                     :key key
39
                                     :mode :ctr
40
                                     :initialization-vector n)
41
                        (reinitialize-instance (eax-cipher mode)
42
                                               :key key
43
                                               :mode :ctr
44
                                               :initialization-vector n))))
45
       (setf (eax-mac-n mode) mac-n
46
             (eax-mac-h mode) mac-h
47
             (eax-mac-c mode) mac-c
48
             (eax-cipher mode) cipher)))
49
   mode)
50
 
51
 (defmethod process-associated-data ((mode eax) data &key (start 0) end)
52
   (let* ((end (or end (length data))))
53
     (update-mac (eax-mac-h mode) data :start start :end end)))
54
 
55
 (defmethod produce-tag ((mode eax) &key tag (tag-start 0))
56
   (let* ((n (produce-mac (eax-mac-n mode)))
57
          (h (produce-mac (eax-mac-h mode)))
58
          (c (produce-mac (eax-mac-c mode)))
59
          (block-length (length c)))
60
     (etypecase tag
61
       (simple-octet-vector
62
        (when (> block-length (- (length tag) tag-start))
63
          (error 'insufficient-buffer-space
64
                 :buffer tag
65
                 :start tag-start
66
                 :length block-length))
67
        (xor-block block-length n 0 c 0 c 0)
68
        (xor-block block-length h 0 c 0 tag tag-start)
69
        tag)
70
       (null
71
        (xor-block block-length n 0 c 0 c 0)
72
        (xor-block block-length h 0 c 0 c 0)
73
        c))))
74
 
75
 (defmethod encrypt ((mode eax) plaintext ciphertext &key (plaintext-start 0) plaintext-end (ciphertext-start 0) handle-final-block)
76
   (declare (ignore handle-final-block))
77
   (let ((cipher (eax-cipher mode))
78
         (mac-c (eax-mac-c mode))
79
         (plaintext-end (or plaintext-end (length plaintext))))
80
     (multiple-value-bind (consumed-bytes produced-bytes)
81
         (encrypt cipher plaintext ciphertext
82
                  :plaintext-start plaintext-start :plaintext-end plaintext-end
83
                  :ciphertext-start ciphertext-start)
84
       (update-mac mac-c ciphertext
85
                   :start ciphertext-start :end (+ ciphertext-start produced-bytes))
86
       (values consumed-bytes produced-bytes))))
87
 
88
 (defmethod decrypt ((mode eax) ciphertext plaintext &key (ciphertext-start 0) ciphertext-end (plaintext-start 0) handle-final-block)
89
   (let ((cipher (eax-cipher mode))
90
         (mac-c (eax-mac-c mode))
91
         (ciphertext-end (or ciphertext-end (length ciphertext))))
92
     (update-mac mac-c ciphertext
93
                 :start ciphertext-start :end ciphertext-end)
94
     (multiple-value-bind (consumed-bytes produced-bytes)
95
         (decrypt cipher ciphertext plaintext
96
                  :ciphertext-start ciphertext-start :ciphertext-end ciphertext-end
97
                  :plaintext-start plaintext-start)
98
       (when (and handle-final-block (tag mode))
99
         (let ((correct-tag (tag mode))
100
               (tag (produce-tag mode)))
101
           (unless (constant-time-equal tag correct-tag)
102
             (error 'bad-authentication-tag))))
103
       (values consumed-bytes produced-bytes))))
104
 
105
 (defmethod encrypt-message ((mode eax) message &key (start 0) end associated-data (associated-data-start 0) associated-data-end &allow-other-keys)
106
   (let* ((length (- (or end (length message)) start))
107
          (encrypted-message (make-array length :element-type '(unsigned-byte 8))))
108
     (when associated-data
109
       (process-associated-data mode associated-data
110
                                :start associated-data-start :end associated-data-end))
111
     (encrypt mode message encrypted-message
112
              :plaintext-start start :plaintext-end end)
113
     encrypted-message))
114
 
115
 (defmethod decrypt-message ((mode eax) message &key (start 0) end associated-data (associated-data-start 0) associated-data-end &allow-other-keys)
116
   (let* ((length (- (or end (length message)) start))
117
          (decrypted-message (make-array length :element-type '(unsigned-byte 8))))
118
     (when associated-data
119
       (process-associated-data mode associated-data
120
                                :start associated-data-start :end associated-data-end))
121
     (decrypt mode message decrypted-message
122
              :plaintext-start start :plaintext-end end
123
              :handle-final-block t)
124
     decrypted-message))
125
 
126
 (defaead eax)