Coverage report: /home/ellis/comp/ext/ironclad/src/macs/cmac.lisp
Kind | Covered | All | % |
expression | 0 | 246 | 0.0 |
branch | 0 | 14 | 0.0 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; cmac.lisp -- The CMAC algorithm from NIST 800-38B.
5
((cipher :reader cmac-cipher :initarg :cipher)
6
(subkey1 :reader cmac-subkey1 :initarg :subkey1
7
:type (simple-array (unsigned-byte 8) (*)))
8
(subkey2 :reader cmac-subkey2 :initarg :subkey2
9
:type (simple-array (unsigned-byte 8) (*)))
10
(buffer :reader cmac-buffer :initarg :buffer
11
:type (simple-array (unsigned-byte 8) (*)))
12
(buffer-index :accessor cmac-buffer-index :initform 0 :type index)))
14
(defun make-cmac (key cipher-name)
15
(declare (type (simple-array (unsigned-byte 8) (*)) key))
16
(let* ((cipher (make-cipher cipher-name :key key :mode :ecb))
17
(block-length (block-length cipher-name))
18
(L (make-array block-length :element-type '(unsigned-byte 8)
20
(encrypt-in-place cipher L)
21
(flet ((gen-subkey (b)
22
(let* ((n-bits (* block-length 8))
24
(ldb (byte n-bits 0) (ash (octets-to-integer b) 1))
26
(when (logbitp 7 (aref b 0))
28
(8 (setf (aref k 7) (logxor (aref k 7) #x1b)))
29
(16 (setf (aref k 15) (logxor (aref k 15) #x87)))
30
(32 (setf (aref k 30) (logxor (aref k 30) #x4)
31
(aref k 31) (logxor (aref k 31) #x25)))
32
(64 (setf (aref k 62) (logxor (aref k 62) #x1)
33
(aref k 63) (logxor (aref k 63) #x25)))
34
(128 (setf (aref k 125) (logxor (aref k 125) #x8)
35
(aref k 126) (logxor (aref k 126) #x0)
36
(aref k 127) (logxor (aref k 127) #x43)))))
38
(let ((L.u (gen-subkey L)))
42
:subkey2 (gen-subkey L.u)
43
:buffer (make-array block-length
44
:element-type '(unsigned-byte 8)
45
:initial-element 0))))))
47
(defmethod reinitialize-instance ((mac cmac) &rest initargs
48
&key key &allow-other-keys)
49
(declare (ignore initargs)
50
(type (simple-array (unsigned-byte 8) (*)) key))
51
(fill (cmac-buffer mac) 0)
52
(setf (cmac-buffer-index mac) 0)
53
(reinitialize-instance (cmac-cipher mac) :key key :mode :ecb)
56
(defun update-cmac (cmac sequence &key (start 0) (end (length sequence)))
57
(declare (type (simple-array (unsigned-byte 8) (*)) sequence)
58
(type index start end)
59
(optimize (speed 3) (space 0) (safety 0) (debug 0)))
60
(let* ((cipher (cmac-cipher cmac))
61
(encryption-function (encrypt-function cipher))
62
(buffer (cmac-buffer cmac))
63
(buffer-index (cmac-buffer-index cmac))
64
(block-length (length buffer))
65
(remaining (- end start)))
66
(declare (type (simple-array (unsigned-byte 8) (*)) buffer))
68
(when (< 0 buffer-index block-length)
69
(dotimes (i (min remaining (- block-length buffer-index)))
70
(setf (aref buffer buffer-index) (logxor (aref buffer buffer-index)
71
(aref sequence start)))
76
(when (and (= buffer-index block-length)
78
(funcall encryption-function cipher buffer 0 buffer 0)
79
(setf buffer-index 0))
81
(loop while (> remaining block-length) do
82
(xor-block block-length buffer 0 sequence start buffer 0)
83
(funcall encryption-function cipher buffer 0 buffer 0)
84
(incf start block-length)
85
(decf remaining block-length))
87
(loop while (plusp remaining) do
88
(setf (aref buffer buffer-index) (logxor (aref buffer buffer-index)
89
(aref sequence start)))
94
(setf (cmac-buffer-index cmac) buffer-index)
97
(defun cmac-digest (cmac)
98
(let* ((block-length (length (cmac-buffer cmac)))
99
(x (copy-seq (cmac-buffer cmac)))
101
((= block-length (cmac-buffer-index cmac))
104
(setf (aref x (cmac-buffer-index cmac))
105
(logxor (aref x (cmac-buffer-index cmac)) #x80))
106
(cmac-subkey2 cmac)))))
107
(xor-block block-length L 0 x 0 x 0)
108
(encrypt-in-place (cmac-cipher cmac) x)