@@ -35,6 +35,7 @@ import (
35
35
"crypto/internal/fips140/sha256"
36
36
"crypto/internal/fips140/sha3"
37
37
"crypto/internal/fips140/sha512"
38
+ "crypto/internal/fips140/subtle"
38
39
"crypto/rand"
39
40
_ "embed"
40
41
"encoding/binary"
@@ -189,6 +190,9 @@ var (
189
190
"AES-GCM/open" : cmdAesGcmOpen (false ),
190
191
"AES-GCM-randnonce/seal" : cmdAesGcmSeal (true ),
191
192
"AES-GCM-randnonce/open" : cmdAesGcmOpen (true ),
193
+
194
+ "CMAC-AES" : cmdCmacAesAft (),
195
+ "CMAC-AES/verify" : cmdCmacAesVerifyAft (),
192
196
}
193
197
)
194
198
@@ -1154,6 +1158,57 @@ func cmdAesGcmOpen(randNonce bool) command {
1154
1158
}
1155
1159
}
1156
1160
1161
+ func cmdCmacAesAft () command {
1162
+ return command {
1163
+ requiredArgs : 3 , // Number of output bytes, key, message
1164
+ handler : func (args [][]byte ) ([][]byte , error ) {
1165
+ // safe to truncate to int based on our capabilities describing a max MAC output len of 128 bits.
1166
+ outputLen := int (binary .LittleEndian .Uint32 (args [0 ]))
1167
+ key := args [1 ]
1168
+ message := args [2 ]
1169
+
1170
+ blockCipher , err := aes .New (key )
1171
+ if err != nil {
1172
+ return nil , fmt .Errorf ("creating AES block cipher with key len %d: %w" , len (key ), err )
1173
+ }
1174
+
1175
+ cmac := gcm .NewCMAC (blockCipher )
1176
+ tag := cmac .MAC (message )
1177
+
1178
+ if outputLen > len (tag ) {
1179
+ return nil , fmt .Errorf ("invalid output length: expected %d, got %d" , outputLen , len (tag ))
1180
+ }
1181
+
1182
+ return [][]byte {tag [:outputLen ]}, nil
1183
+ },
1184
+ }
1185
+ }
1186
+
1187
+ func cmdCmacAesVerifyAft () command {
1188
+ return command {
1189
+ requiredArgs : 3 , // Key, message, claimed MAC
1190
+ handler : func (args [][]byte ) ([][]byte , error ) {
1191
+ key := args [0 ]
1192
+ message := args [1 ]
1193
+ claimedMAC := args [2 ]
1194
+
1195
+ blockCipher , err := aes .New (key )
1196
+ if err != nil {
1197
+ return nil , fmt .Errorf ("creating AES block cipher with key len %d: %w" , len (key ), err )
1198
+ }
1199
+
1200
+ cmac := gcm .NewCMAC (blockCipher )
1201
+ tag := cmac .MAC (message )
1202
+
1203
+ if subtle .ConstantTimeCompare (tag [:len (claimedMAC )], claimedMAC ) != 1 {
1204
+ return [][]byte {{0 }}, nil
1205
+ }
1206
+
1207
+ return [][]byte {{1 }}, nil
1208
+ },
1209
+ }
1210
+ }
1211
+
1157
1212
func TestACVP (t * testing.T ) {
1158
1213
testenv .SkipIfShortAndSlow (t )
1159
1214
0 commit comments