Coverage report: /home/ellis/comp/ext/ironclad/src/macs/skein-mac.lisp

KindCoveredAll%
expression0188 0.0
branch04 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; skein-mac.lisp -- implementation of the Skein MAC
2
 (in-package :crypto)
3
 
4
 (defclass skein-mac (mac)
5
   ((value :accessor skein-value :initarg :value)
6
    (tweak :accessor skein-tweak :initarg :tweak)
7
    (cfg :accessor skein-cfg :initarg :cfg)
8
    (buffer :accessor skein-buffer :initarg :buffer)
9
    (buffer-length :accessor skein-buffer-length :initarg :buffer-length)
10
    (cipher :accessor skein-cipher :initarg :cipher)
11
    (block-length :accessor block-length :initarg :block-length)
12
    (digest-length :accessor digest-length :initarg :digest-length)))
13
 
14
 (defun make-skein-mac (key &key (block-length 64) (digest-length 64))
15
   (unless (or (= block-length 32)
16
               (= block-length 64)
17
               (= block-length 128))
18
     (error 'invalid-mac-parameter
19
            :mac-name 'skein-mac
20
            :message "The block length must be 32, 64 or 128 bytes"))
21
 
22
   (make-instance 'skein-mac
23
                  :key key
24
                  :block-length block-length
25
                  :digest-length digest-length))
26
 
27
 (defmethod copy-skein-mac ((mac skein-mac) &optional copy)
28
   (declare (type (or null skein-mac) copy))
29
   (let ((copy (if copy
30
                   copy
31
                   (make-instance 'skein-mac
32
                                  :key (skein-value mac)
33
                                  :block-length (block-length mac)
34
                                  :digest-length (digest-length mac)))))
35
     (declare (type skein-mac copy))
36
     (replace (skein-value copy) (skein-value mac))
37
     (replace (skein-tweak copy) (skein-tweak mac))
38
     (replace (skein-cfg copy) (skein-cfg mac))
39
     (replace (skein-buffer copy) (skein-buffer mac))
40
     (setf (skein-buffer-length copy) (skein-buffer-length mac))
41
     (setf (skein-cipher copy) (skein-copy-cipher (skein-cipher mac)))
42
     copy))
43
 
44
 (defmethod shared-initialize :after ((mac skein-mac) slot-names
45
                                      &rest initargs
46
                                      &key key &allow-other-keys)
47
   (declare (ignore slot-names initargs)
48
            (type (simple-array (unsigned-byte 8) (*)) key))
49
   (let* ((block-length (block-length mac))
50
          (digest-length (digest-length mac))
51
          (value (make-array block-length
52
                             :element-type '(unsigned-byte 8)
53
                             :initial-element 0))
54
          (tweak (skein-make-tweak t nil +skein-key+ 0))
55
          (cfg (skein-make-configuration-string (* 8 digest-length)))
56
          (cipher (ecase block-length
57
                    (32 (make-cipher :threefish256
58
                                     :key value
59
                                     :mode :ecb))
60
                    (64 (make-cipher :threefish512
61
                                     :key value
62
                                     :mode :ecb))
63
                    (128 (make-cipher :threefish1024
64
                                      :key value
65
                                      :mode :ecb)))))
66
     (setf (skein-cipher mac) cipher
67
           (skein-value mac) value
68
           (skein-cfg mac) cfg
69
           (skein-tweak mac) tweak
70
           (skein-buffer mac) (make-array block-length
71
                                          :element-type '(unsigned-byte 8))
72
           (skein-buffer-length mac) 0)
73
 
74
     ;; Process key
75
     (when (plusp (length key))
76
       (skein-ubi mac key 0 (length key))
77
       (let* ((padding-length (- block-length (skein-buffer-length mac)))
78
              (padding (make-array padding-length
79
                                   :element-type '(unsigned-byte 8)
80
                                   :initial-element 0)))
81
         (skein-update-tweak tweak
82
                             :final t
83
                             :position-increment (skein-buffer-length mac))
84
         (skein-ubi mac padding 0 padding-length t)))
85
 
86
     ;; Process configuration string
87
     (let ((padded-cfg (make-array block-length
88
                                   :element-type '(unsigned-byte 8)
89
                                   :initial-element 0)))
90
       (replace padded-cfg cfg :end2 32)
91
       (skein-update-tweak tweak
92
                           :first t
93
                           :final t
94
                           :type +skein-cfg+
95
                           :position 32)
96
       (skein-ubi mac padded-cfg 0 block-length t))
97
 
98
     ;; Prepare message processing
99
     (skein-update-tweak tweak
100
                         :first t
101
                         :final nil
102
                         :type +skein-msg+
103
                         :position 0)))
104
 
105
 (defun update-skein-mac (mac sequence &key (start 0) end)
106
   (skein-ubi mac sequence start (or end (length sequence)))
107
   mac)
108
 
109
 (defun skein-mac-digest (mac)
110
   (let ((digest (make-array (digest-length mac)
111
                             :element-type '(unsigned-byte 8)))
112
         (mac-copy (copy-skein-mac mac)))
113
     (skein-finalize mac-copy digest 0)
114
     digest))
115
 
116
 (defmac skein-mac
117
         make-skein-mac
118
         update-skein-mac
119
         skein-mac-digest)