aboutsummaryrefslogtreecommitdiffstats
path: root/virtio-crypto.tex
blob: 4a15e143b7d1c7cf8e04a63d9fdbf337fb5eb1d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
\section{Crypto Device}\label{sec:Device Types / Crypto Device}

The virtio crypto device is a virtual cryptography device as well as a
virtual cryptographic accelerator. The virtio crypto device provides the
following crypto services: CIPHER, MAC, HASH, and AEAD. Virtio crypto
devices have a single control queue and at least one data queue. Crypto
operation requests are placed into a data queue, and serviced by the
device. Some crypto operation requests are only valid in the context of a
session. The role of the control queue is facilitating control operation
requests. Sessions management is realized with control operation
requests.

\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}

20

\subsection{Virtqueues}\label{sec:Device Types / Crypto Device / Virtqueues}

\begin{description}
\item[0] dataq1
\item[\ldots]
\item[N-1] dataqN
\item[N] controlq
\end{description}

N is set by \field{max_dataqueues}.

\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature bits}

\begin{description}
\item VIRTIO_CRYPTO_F_REVISION_1 (0) revision 1. Revision 1 has a specific
    request format and other enhancements (which result in some additional
    requirements).
\item VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE (1) stateless mode requests are
    supported by the CIPHER service.
\item VIRTIO_CRYPTO_F_HASH_STATELESS_MODE (2) stateless mode requests are
    supported by the HASH service.
\item VIRTIO_CRYPTO_F_MAC_STATELESS_MODE (3) stateless mode requests are
    supported by the MAC service.
\item VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE (4) stateless mode requests are
    supported by the AEAD service.
\end{description}


\subsubsection{Feature bit requirements}\label{sec:Device Types / Crypto Device / Feature bit requirements}

Some crypto feature bits require other crypto feature bits
(see \ref{drivernormative:Basic Facilities of a Virtio Device / Feature Bits}):

\begin{description}
\item[VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_REVISION_1.
\item[VIRTIO_CRYPTO_F_HASH_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_REVISION_1.
\item[VIRTIO_CRYPTO_F_MAC_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_REVISION_1.
\item[VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_REVISION_1.
\end{description}

\subsection{Supported crypto services}\label{sec:Device Types / Crypto Device / Supported crypto services}

The following crypto services are defined:

\begin{lstlisting}
/* CIPHER service */
#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
/* HASH service */
#define VIRTIO_CRYPTO_SERVICE_HASH   1
/* MAC (Message Authentication Codes) service */
#define VIRTIO_CRYPTO_SERVICE_MAC    2
/* AEAD (Authenticated Encryption with Associated Data) service */
#define VIRTIO_CRYPTO_SERVICE_AEAD   3
\end{lstlisting}

The above constants designate bits used to indicate the which of crypto services are
offered by the device as described in, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.

\subsubsection{CIPHER services}\label{sec:Device Types / Crypto Device / Supported crypto services / CIPHER services}

The following CIPHER algorithms are defined:

\begin{lstlisting}
#define VIRTIO_CRYPTO_NO_CIPHER                 0
#define VIRTIO_CRYPTO_CIPHER_ARC4               1
#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
\end{lstlisting}

The above constants have two usages:
\begin{enumerate}
\item As bit numbers, used to tell the driver which CIPHER algorithms
are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
\item As values, used to designate the algorithm in (CIPHER type) crypto
operation requests, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
\end{enumerate}

\subsubsection{HASH services}\label{sec:Device Types / Crypto Device / Supported crypto services / HASH services}

The following HASH algorithms are defined:

\begin{lstlisting}
#define VIRTIO_CRYPTO_NO_HASH            0
#define VIRTIO_CRYPTO_HASH_MD5           1
#define VIRTIO_CRYPTO_HASH_SHA1          2
#define VIRTIO_CRYPTO_HASH_SHA_224       3
#define VIRTIO_CRYPTO_HASH_SHA_256       4
#define VIRTIO_CRYPTO_HASH_SHA_384       5
#define VIRTIO_CRYPTO_HASH_SHA_512       6
#define VIRTIO_CRYPTO_HASH_SHA3_224      7
#define VIRTIO_CRYPTO_HASH_SHA3_256      8
#define VIRTIO_CRYPTO_HASH_SHA3_384      9
#define VIRTIO_CRYPTO_HASH_SHA3_512      10
#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
\end{lstlisting}

The above constants have two usages:
\begin{enumerate}
\item As bit numbers, used to tell the driver which HASH algorithms
are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
\item As values, used to designate the algorithm in (HASH type) crypto
operation requires, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
\end{enumerate}

\subsubsection{MAC services}\label{sec:Device Types / Crypto Device / Supported crypto services / MAC services}

The following MAC algorithms are defined:

\begin{lstlisting}
#define VIRTIO_CRYPTO_NO_MAC                       0
#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
#define VIRTIO_CRYPTO_MAC_ZUC_EIA3                 54
\end{lstlisting}

The above constants have two usages:
\begin{enumerate}
\item As bit numbers, used to tell the driver which MAC algorithms
are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
\item As values, used to designate the algorithm in (MAC type) crypto
operation requests, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
\end{enumerate}

\subsubsection{AEAD services}\label{sec:Device Types / Crypto Device / Supported crypto services / AEAD services}

The following AEAD algorithms are defined:

\begin{lstlisting}
#define VIRTIO_CRYPTO_NO_AEAD     0
#define VIRTIO_CRYPTO_AEAD_GCM    1
#define VIRTIO_CRYPTO_AEAD_CCM    2
#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
\end{lstlisting}

The above constants have two usages:
\begin{enumerate}
\item As bit numbers, used to tell the driver which AEAD algorithms
are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
\item As values, used to designate the algorithm in (DEAD type) crypto
operation requests, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
\end{enumerate}

\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}

Crypto device configuration uses the following layout structure:

\begin{lstlisting}
struct virtio_crypto_config {
    le32 status;
    le32 max_dataqueues;
    le32 crypto_services;
    /* Detailed algorithms mask */
    le32 cipher_algo_l;
    le32 cipher_algo_h;
    le32 hash_algo;
    le32 mac_algo_l;
    le32 mac_algo_h;
    le32 aead_algo;
    /* Maximum length of cipher key in bytes */
    le32 max_cipher_key_len;
    /* Maximum length of authenticated key in bytes */
    le32 max_auth_key_len;
    le32 reserved;
    /* Maximum size of each crypto request's content in bytes */
    le64 max_size;
};
\end{lstlisting}

\begin{description}
\item Currently, only one \field{status} bit is defined: VIRTIO_CRYPTO_S_HW_READY
    set indicates that the device is ready to process requests, this bit is read-only
    for the driver
\begin{lstlisting}
#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
\end{lstlisting}

\item [\field{max_dataqueues}] is the maximum number of data virtqueues that can
    be configured by the device. The driver MAY use only one data queue, or it
    can use more to achieve better performance.

\item [\field{crypto_services}] crypto service offered, see \ref{sec:Device Types / Crypto Device / Supported crypto services}.

\item [\field{cipher_algo_l}] CIPHER algorithms bits 0-31, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.

\item [\field{cipher_algo_h}] CIPHER algorithms bits 32-63, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.

\item [\field{hash_algo}] HASH algorithms bits, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / HASH services}.

\item [\field{mac_algo_l}] MAC algorithms bits 0-31, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.

\item [\field{mac_algo_h}] MAC algorithms bits 32-63, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.

\item [\field{aead_algo}] AEAD algorithms bits, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / AEAD services}.

\item [\field{max_cipher_key_len}] is the maximum length of cipher key supported by the device.

\item [\field{max_auth_key_len}] is the maximum length of authenticated key supported by the device.

\item [\field{reserved}] is reserved for future use.

\item [\field{max_size}] is the maximum size of the variable-length parameters of
    data operation of each crypto request's content supported by the device.
\end{description}

\begin{note}
Unless explicitly stated otherwise all lengths and sizes are in bytes.
\end{note}

\devicenormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}

\begin{itemize*}
\item The device MUST set \field{max_dataqueues} to between 1 and 65535 inclusive.
\item The device MUST set the \field{status} with valid flags, undefined flags MUST NOT be set.
\item The device MUST accept and handle requests after \field{status} is set to VIRTIO_CRYPTO_S_HW_READY.
\item The device MUST set \field{crypto_services} based on the crypto services the device offers.
\item The device MUST set detailed algorithms masks for each service advertised by \field{crypto_services}.
    The device MUST NOT set the not defined algorithms bits.
\item The device MUST set \field{max_size} to show the maximum size of crypto request the device supports.
\item The device MUST set \field{max_cipher_key_len} to show the maximum length of cipher key if the
    device supports CIPHER service.
\item The device MUST set \field{max_auth_key_len} to show the maximum length of authenticated key if
    the device supports MAC service.
\end{itemize*}

\drivernormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}

\begin{itemize*}
\item The driver MUST read the \field{status} from the bottom bit of status to check whether the
    VIRTIO_CRYPTO_S_HW_READY is set, and the driver MUST reread it after device reset.
\item The driver MUST NOT transmit any requests to the device if the VIRTIO_CRYPTO_S_HW_READY is not set.
\item The driver MUST read \field{max_dataqueues} field to discover the number of data queues the device supports.
\item The driver MUST read \field{crypto_services} field to discover which services the device is able to offer.
\item The driver SHOULD ignore the not defined algorithms bits.
\item The driver MUST read the detailed algorithms fields based on \field{crypto_services} field.
\item The driver SHOULD read \field{max_size} to discover the maximum size of the variable-length
    parameters of data operation of the crypto request's content the device supports and MUST
    guarantee the size of each crypto request's content within the \field{max_size}, otherwise
    the request will fail and the driver MUST reset the device.
\item The driver SHOULD read \field{max_cipher_key_len} to discover the maximum length of cipher key
    the device supports and MUST guarantee the \field{key_len} (CIPHER service or AEAD service) within
    the \field{max_cipher_key_len} of the device configuration, otherwise the request will fail.
\item The driver SHOULD read \field{max_auth_key_len} to discover the maximum length of authenticated
    key the device supports and MUST guarantee the \field{auth_key_len} (MAC service) within the
    \field{max_auth_key_len} of the device configuration, otherwise the request will fail.
\end{itemize*}

\subsection{Device Initialization}\label{sec:Device Types / Crypto Device / Device Initialization}

\drivernormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}

\begin{itemize*}
\item The driver MUST configure and initialize all virtqueues.
\item The driver MUST read the supported crypto services from bits of \field{crypto_services}.
\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
\end{itemize*}

\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}

The operation of a virtio crypto device is driven by requests placed on the virtqueues.
Requests consist of a queue-type specific header (specifying among others the operation)
and an operation specific payload.

If VIRTIO_CRYPTO_F_REVISION_1 is negotiated the device may support both session mode
(See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation})
and stateless mode operation requests.
In stateless mode all operation parameters are supplied as a part of each request,
while in session mode, some or all operation parameters are managed within the
session. Stateless mode is guarded by feature bits 0-4 on a service level. If
stateless mode is negotiated for a service, the service accepts both session
mode and stateless requests; otherwise stateless mode requests are rejected
(via operation status).

\subsubsection{Operation Status}\label{sec:Device Types / Crypto Device / Device Operation / Operation status}
The device MUST return a status code as part of the operation (both session
operation and service operation) result. The valid operation status as follows:

\begin{lstlisting}
enum VIRTIO_CRYPTO_STATUS {
    VIRTIO_CRYPTO_OK = 0,
    VIRTIO_CRYPTO_ERR = 1,
    VIRTIO_CRYPTO_BADMSG = 2,
    VIRTIO_CRYPTO_NOTSUPP = 3,
    VIRTIO_CRYPTO_INVSESS = 4,
    VIRTIO_CRYPTO_NOSPC = 5,
    VIRTIO_CRYPTO_MAX
};
\end{lstlisting}

\begin{itemize*}
\item VIRTIO_CRYPTO_OK: success.
\item VIRTIO_CRYPTO_BADMSG: authentication failed (only when AEAD decryption).
\item VIRTIO_CRYPTO_NOTSUPP: operation or algorithm is unsupported.
\item VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto operations.
\item VIRTIO_CRYPTO_NOSPC: no free session ID (only when the VIRTIO_CRYPTO_F_REVISION_1
    feature bit is negotiated).
\item VIRTIO_CRYPTO_ERR: any failure not mentioned above occurs.
\end{itemize*}

\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}

The driver uses the control virtqueue to send control commands to the
device, such as session operations (See \ref{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation}).

The header for controlq is of the following form:
\begin{lstlisting}
#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))

struct virtio_crypto_ctrl_header {
#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
    le32 opcode;
    /* algo should be service-specific algorithms */
    le32 algo;
    le32 flag;
    le32 reserved;
};
\end{lstlisting}

The controlq request is composed of four parts:
\begin{lstlisting}
struct virtio_crypto_op_ctrl_req {
    /* Device read only portion */

    struct virtio_crypto_ctrl_header header;

#define VIRTIO_CRYPTO_CTRLQ_OP_SPEC_HDR_LEGACY 56
    /* fixed length fields, opcode specific */
    u8 op_flf[flf_len];

    /* variable length fields, opcode specific */
    u8 op_vlf[vlf_len];

    /* Device write only portion */

    /* op result or completion status */
    u8 op_outcome[outcome_len];
};
\end{lstlisting}

\field{header} is a general header (see above).

\field{op_flf} is the opcode (in \field{header}) specific fixed-length paramenters.

\field{flf_len} depends on the VIRTIO_CRYPTO_F_REVISION_1 feature bit (see below).

\field{op_vlf} is the opcode (in \field{header}) specific variable-length paramenters.

\field{vlf_len} is the size of the specific structure used.
\begin{note}
The \field{vlf_len} of session-destroy operation and the hash-session-create
operation is ZERO.
\end{note}

\begin{itemize*}
\item If the opcode (in \field{header}) is VIRTIO_CRYPTO_CIPHER_CREATE_SESSION
    then \field{op_flf} is struct virtio_crypto_sym_create_session_flf if
    VIRTIO_CRYPTO_F_REVISION_1 is negotiated and struct virtio_crypto_sym_create_session_flf is
    padded to 56 bytes if NOT negotiated, and \field{op_vlf} is struct
    virtio_crypto_sym_create_session_vlf.
\item If the opcode (in \field{header}) is VIRTIO_CRYPTO_HASH_CREATE_SESSION
    then \field{op_flf} is struct virtio_crypto_hash_create_session_flf if
    VIRTIO_CRYPTO_F_REVISION_1 is negotiated and struct virtio_crypto_hash_create_session_flf is
    padded to 56 bytes if NOT negotiated.
\item If the opcode (in \field{header}) is VIRTIO_CRYPTO_MAC_CREATE_SESSION
    then \field{op_flf} is struct virtio_crypto_mac_create_session_flf if
    VIRTIO_CRYPTO_F_REVISION_1 is negotiated and struct virtio_crypto_mac_create_session_flf is
    padded to 56 bytes if NOT negotiated, and \field{op_vlf} is struct
    virtio_crypto_mac_create_session_vlf.
\item If the opcode (in \field{header}) is VIRTIO_CRYPTO_AEAD_CREATE_SESSION
    then \field{op_flf} is struct virtio_crypto_aead_create_session_flf if
    VIRTIO_CRYPTO_F_REVISION_1 is negotiated and struct virtio_crypto_aead_create_session_flf is
    padded to 56 bytes if NOT negotiated, and \field{op_vlf} is struct
    virtio_crypto_aead_create_session_vlf.
\item If the opcode (in \field{header}) is VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION
    or VIRTIO_CRYPTO_HASH_DESTROY_SESSION or VIRTIO_CRYPTO_MAC_DESTROY_SESSION or
    VIRTIO_CRYPTO_AEAD_DESTROY_SESSION then \field{op_flf} is struct
    virtio_crypto_destroy_session_flf if VIRTIO_CRYPTO_F_REVISION_1 is negotiated and
    struct virtio_crypto_destroy_session_flf is padded to 56 bytes if NOT negotiated.
\end{itemize*}

\field{op_outcome} stores the result of operation and must be struct
virtio_crypto_destroy_session_input for destroy session or
struct virtio_crypto_create_session_input for create session.

\field{outcome_len} is the size of the structure used.


\paragraph{Session operation}\label{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation}

The session is a handle which describes the cryptographic parameters to be
applied to a number of buffers.

The following structure stores the result of session creation set by the device:

\begin{lstlisting}
struct virtio_crypto_create_session_input {
    le64 session_id;
    le32 status;
    le32 padding;
};
\end{lstlisting}

A request to destroy a session includes the following information:

\begin{lstlisting}
struct virtio_crypto_destroy_session_flf {
    /* Device read only portion */
    le64  session_id;
};

struct virtio_crypto_destroy_session_input {
    /* Device write only portion */
    u8  status;
};
\end{lstlisting}


\subparagraph{Session operation: HASH session}\label{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: HASH session}

The fixed-length paramenters of HASH session requests is as follows:

\begin{lstlisting}
struct virtio_crypto_hash_create_session_flf {
    /* Device read only portion */

    /* See VIRTIO_CRYPTO_HASH_* above */
    le32 algo;
    /* hash result length */
    le32 hash_result_len;
};
\end{lstlisting}


\subparagraph{Session operation: MAC session}\label{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: MAC session}

The fixed-length and the variable-length parameters of MAC session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_mac_create_session_flf {
    /* Device read only portion */

    /* See VIRTIO_CRYPTO_MAC_* above */
    le32 algo;
    /* hash result length */
    le32 hash_result_len;
    /* length of authenticated key */
    le32 auth_key_len;
    le32 padding;
};

struct virtio_crypto_mac_create_session_vlf {
    /* Device read only portion */

    /* The authenticated key */
    u8 auth_key[auth_key_len];
};
\end{lstlisting}

The length of \field{auth_key} is specified in \field{auth_key_len} in the struct
virtio_crypto_mac_create_session_flf.


\subparagraph{Session operation: Symmetric algorithms session}\label{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: Symmetric algorithms session}

The request of symmetric session could be the CIPHER algorithms request
or the chain algorithms (chaining CIPHER and HASH/MAC) request.

The fixed-length and the variable-length parameters of CIPHER session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_cipher_session_flf {
    /* Device read only portion */

    /* See VIRTIO_CRYPTO_CIPHER* above */
    le32 algo;
    /* length of key */
    le32 key_len;
#define VIRTIO_CRYPTO_OP_ENCRYPT  1
#define VIRTIO_CRYPTO_OP_DECRYPT  2
    /* encryption or decryption */
    le32 op;
    le32 padding;
};

struct virtio_crypto_cipher_session_vlf {
    /* Device read only portion */

    /* The cipher key */
    u8 cipher_key[key_len];
};
\end{lstlisting}

The length of \field{cipher_key} is specified in \field{key_len} in the struct
virtio_crypto_cipher_session_flf.

The fixed-length and the variable-length parameters of Chain session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_alg_chain_session_flf {
    /* Device read only portion */

#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER  1
#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH  2
    le32 alg_chain_order;
/* Plain hash */
#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN    1
/* Authenticated hash (mac) */
#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH     2
/* Nested hash */
#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED   3
    le32 hash_mode;
    struct virtio_crypto_cipher_session_flf cipher_hdr;

#define VIRTIO_CRYPTO_ALG_CHAIN_SESS_OP_SPEC_HDR_SIZE  16
    /* fixed length fields, algo specific */
    u8 algo_flf[VIRTIO_CRYPTO_ALG_CHAIN_SESS_OP_SPEC_HDR_SIZE];

    /* length of the additional authenticated data (AAD) in bytes */
    le32 aad_len;
    le32 padding;
};

struct virtio_crypto_alg_chain_session_vlf {
    /* Device read only portion */

    /* The cipher key */
    u8 cipher_key[key_len];
    /* The authenticated key */
    u8 auth_key[auth_key_len];
};
\end{lstlisting}

\field{hash_mode} decides the type used by \field{algo_flf}.

\field{algo_flf} is fixed to 16 bytes and MUST contains or be one of
the following types:
\begin{itemize*}
\item struct virtio_crypto_hash_create_session_flf
\item struct virtio_crypto_mac_create_session_flf
\end{itemize*}
The data of unused part (if has) in \field{algo_flf} will be ignored.

The length of \field{cipher_key} is specified in \field{key_len} in \field{cipher_hdr}.

The length of \field{auth_key} is specified in \field{auth_key_len} in struct
virtio_crypto_mac_create_session_flf.

The fixed-length parameters of Symmetric session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_sym_create_session_flf {
    /* Device read only portion */

#define VIRTIO_CRYPTO_SYM_SESS_OP_SPEC_HDR_SIZE  48
    /* fixed length fields, opcode specific */
    u8 op_flf[VIRTIO_CRYPTO_SYM_SESS_OP_SPEC_HDR_SIZE];

/* No operation */
#define VIRTIO_CRYPTO_SYM_OP_NONE  0
/* Cipher only operation on the data */
#define VIRTIO_CRYPTO_SYM_OP_CIPHER  1
/* Chain any cipher with any hash or mac operation. The order
   depends on the value of alg_chain_order param */
#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING  2
    le32 op_type;
    le32 padding;
};
\end{lstlisting}

\field{op_flf} is fixed to 48 bytes, MUST contains or be one of
the following types:
\begin{itemize*}
\item struct virtio_crypto_cipher_session_flf
\item struct virtio_crypto_alg_chain_session_flf
\end{itemize*}
The data of unused part (if has) in \field{op_flf} will be ignored.

\field{op_type} decides the type used by \field{op_flf}.

The variable-length parameters of Symmetric session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_sym_create_session_vlf {
    /* Device read only portion */
    /* variable length fields, opcode specific */
    u8 op_vlf[vlf_len];
};
\end{lstlisting}

\field{op_vlf} MUST contains or be one of the following types:
\begin{itemize*}
\item struct virtio_crypto_cipher_session_vlf
\item struct virtio_crypto_alg_chain_session_vlf
\end{itemize*}

\field{op_type} in struct virtio_crypto_sym_create_session_flf decides the
type used by \field{op_vlf}.

\field{vlf_len} is the size of the specific structure used.


\subparagraph{Session operation: AEAD session}\label{sec:Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: AEAD session}

The fixed-length and the variable-length parameters of AEAD session requests are as follows:

\begin{lstlisting}
struct virtio_crypto_aead_create_session_flf {
    /* Device read only portion */

    /* See VIRTIO_CRYPTO_AEAD_* above */
    le32 algo;
    /* length of key */
    le32 key_len;
    /* Authentication tag length */
    le32 tag_len;
    /* The length of the additional authenticated data (AAD) in bytes */
    le32 aad_len;
    /* encryption or decryption, See above VIRTIO_CRYPTO_OP_* */
    le32 op;
    le32 padding;
};

struct virtio_crypto_aead_create_session_vlf {
    /* Device read only portion */
    u8 key[key_len];
};
\end{lstlisting}

The length of \field{key} is specified in \field{key_len} in struct
virtio_crypto_aead_create_session_flf.


\drivernormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: create session}

\begin{itemize*}
\item The driver MUST set the \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
\item The driver MUST set the control general header, the opcode specific header,
    the opcode specific extra parameters and the opcode specific outcome buffer in turn.
    See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}.
\item The driver MUST set the \field{reversed} field to zero.
\end{itemize*}

\devicenormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: create session}

\begin{itemize*}
\item The device MUST use the corresponding opcode specific structure according to the
    \field{opcode} in the control general header.
\item The device MUST extract extra parameters according to the structures used.
\item The device MUST set the \field{status} field to one of the following values of enum
    VIRTIO_CRYPTO_STATUS after finish a session creation:
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if a session is created successfully.
\item VIRTIO_CRYPTO_NOTSUPP if the requested algorithm or operation is unsupported.
\item VIRTIO_CRYPTO_NOSPC if no free session ID (only when the VIRTIO_CRYPTO_F_REVISION_1
    feature bit is negotiated).
\item VIRTIO_CRYPTO_ERR if failure not mentioned above occurs.
\end{itemize*}
\item The device MUST set the \field{session_id} field to a unique session identifier only
    if the status is set to VIRTIO_CRYPTO_OK.
\end{itemize*}

\drivernormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: destroy session}

\begin{itemize*}
\item The driver MUST set the \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
\item The driver MUST set the \field{session_id} to a valid value assigned by the device
    when the session was created.
\end{itemize*}

\devicenormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
Operation / Control Virtqueue / Session operation / Session operation: destroy session}

\begin{itemize*}
\item The device MUST set the \field{status} field to one of the following values of enum VIRTIO_CRYPTO_STATUS.
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if a session is created successfully.
\item VIRTIO_CRYPTO_ERR if any failure occurs.
\end{itemize*}
\end{itemize*}


\subsubsection{Data Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue}

The driver uses the data virtqueues to transmit crypto operation requests to the device,
and completes the crypto operations.

The header for dataq is as follows:

\begin{lstlisting}
struct virtio_crypto_op_header {
#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
#define VIRTIO_CRYPTO_HASH \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
#define VIRTIO_CRYPTO_MAC \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
#define VIRTIO_CRYPTO_AEAD_DECRYPT \
    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
    le32 opcode;
    /* algo should be service-specific algorithms */
    le32 algo;
    le64 session_id;
#define VIRTIO_CRYPTO_FLAG_SESSION_MODE 1
    /* control flag to control the request */
    le32 flag;
    le32 padding;
};
\end{lstlisting}

\begin{note}
If VIRTIO_CRYPTO_F_REVISION_1 is not negotiated the \field{flag} is ignored.

If VIRTIO_CRYPTO_F_REVISION_1 is negotiated but VIRTIO_CRYPTO_F_<SERVICE>_STATELESS_MODE
is not negotiated, then the device SHOULD reject <SERVICE> requests if
VIRTIO_CRYPTO_FLAG_SESSION_MODE is not set (in \field{flag}).
\end{note}

The dataq request is composed of four parts:
\begin{lstlisting}
struct virtio_crypto_op_data_req {
    /* Device read only portion */

    struct virtio_crypto_op_header header;

#define VIRTIO_CRYPTO_DATAQ_OP_SPEC_HDR_LEGACY 48
    /* fixed length fields, opcode specific */
    u8 op_flf[flf_len];

    /* Device read && write portion */
    /* variable length fields, opcode specific */
    u8 op_vlf[vlf_len];

    /* Device write only portion */
    struct virtio_crypto_inhdr inhdr;
};
\end{lstlisting}

\field{header} is a general header (see above).

\field{op_flf} is the opcode (in \field{header}) specific header.

\field{flf_len} depends on the VIRTIO_CRYPTO_F_REVISION_1 feature bit
(see below).

\field{op_vlf} is the opcode (in \field{header}) specific parameters.

\field{vlf_len} is the size of the specific structure used.

\begin{itemize*}
\item If the the opcode (in \field{header}) is VIRTIO_CRYPTO_CIPHER_ENCRYPT
    or VIRTIO_CRYPTO_CIPHER_DECRYPT then:
    \begin{itemize*}
    \item If VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is negotiated, \field{op_flf} is
        struct virtio_crypto_sym_data_flf_stateless, and \field{op_vlf} is struct
        virtio_crypto_sym_data_vlf_stateless.
    \item If VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is NOT negotiated, \field{op_flf}
        is struct virtio_crypto_sym_data_flf if VIRTIO_CRYPTO_F_REVISION_1 is negotiated
        and struct virtio_crypto_sym_data_flf is padded to 48 bytes if NOT negotiated,
        and \field{op_vlf} is struct virtio_crypto_sym_data_vlf.
    \end{itemize*}
\item If the the opcode (in \field{header}) is VIRTIO_CRYPTO_HASH:
    \begin{itemize*}
    \item If VIRTIO_CRYPTO_F_HASH_STATELESS_MODE is negotiated, \field{op_flf} is
        struct virtio_crypto_hash_data_flf_stateless, and \field{op_vlf} is struct
        virtio_crypto_hash_data_vlf_stateless.
    \item If VIRTIO_CRYPTO_F_HASH_STATELESS_MODE is NOT negotiated, \field{op_flf}
        is struct virtio_crypto_hash_data_flf if VIRTIO_CRYPTO_F_REVISION_1 is negotiated
        and struct virtio_crypto_hash_data_flf is padded to 48 bytes if NOT negotiated,
        and \field{op_vlf} is struct virtio_crypto_hash_data_vlf.
    \end{itemize*}
\item If the the opcode (in \field{header}) is VIRTIO_CRYPTO_MAC:
    \begin{itemize*}
    \item If VIRTIO_CRYPTO_F_MAC_STATELESS_MODE is negotiated, \field{op_flf} is
        struct virtio_crypto_mac_data_flf_stateless, and \field{op_vlf} is struct
        virtio_crypto_mac_data_vlf_stateless.
    \item If VIRTIO_CRYPTO_F_MAC_STATELESS_MODE is NOT negotiated, \field{op_flf}
        is struct virtio_crypto_mac_data_flf if VIRTIO_CRYPTO_F_REVISION_1 is negotiated
        and struct virtio_crypto_mac_data_flf is padded to 48 bytes if NOT negotiated,
        and \field{op_vlf} is struct virtio_crypto_mac_data_vlf.
    \end{itemize*}
\item If the the opcode (in \field{header}) is VIRTIO_CRYPTO_AEAD_ENCRYPT
    or VIRTIO_CRYPTO_AEAD_DECRYPT then:
    \begin{itemize*}
    \item If VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE is negotiated, \field{op_flf} is
        struct virtio_crypto_aead_data_flf_stateless, and \field{op_vlf} is struct
        virtio_crypto_aead_data_vlf_stateless.
    \item If VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE is NOT negotiated, \field{op_flf}
        is struct virtio_crypto_aead_data_flf if VIRTIO_CRYPTO_F_REVISION_1 is negotiated
        and struct virtio_crypto_aead_data_flf is padded to 48 bytes if NOT negotiated,
        and \field{op_vlf} is struct virtio_crypto_aead_data_vlf.
    \end{itemize*}
\end{itemize*}

\field{inhdr} is a unified input header that used to return the status of
the operations, is defined as follows:

\begin{lstlisting}
struct virtio_crypto_inhdr {
    u8 status;
};
\end{lstlisting}

\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / HASH Service Operation}

Session mode HASH service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_hash_data_flf {
    /* length of source data */
    le32 src_data_len;
    /* hash result length */
    le32 hash_result_len;
};

struct virtio_crypto_hash_data_vlf {
    /* Device read only portion */
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

Each data request uses the virtio_crypto_hash_data_flf structure and the
virtio_crypto_hash_data_vlf structure to store information used to run the
HASH operations.

\field{src_data} is the source data that will be processed.
\field{src_data_len} is the length of source data.
\field{hash_result} is the result data and \field{hash_result_len} is the length
of it.

Stateless mode HASH service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_hash_data_flf_stateless {
    struct {
        /* See VIRTIO_CRYPTO_HASH_* above */
        le32 algo;
    } sess_para;

    /* length of source data */
    le32 src_data_len;
    /* hash result length */
    le32 hash_result_len;
    le32 reserved;
};
struct virtio_crypto_hash_data_vlf_stateless {
    /* Device read only portion */
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

\drivernormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}

\begin{itemize*}
\item If the driver uses the session mode, then the driver MUST set \field{session_id}
    in struct virtio_crypto_op_header to a valid value assigned by the device when the
    session was created.
\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, 1) if the
    driver uses the stateless mode, then the driver MUST set the \field{flag} field in
    struct virtio_crypto_op_header to ZERO and MUST set the fields in struct
    virtio_crypto_hash_data_flf_stateless.sess_para, 2) if the driver uses the session
    mode, then the driver MUST set the \field{flag} field in struct virtio_crypto_op_header
    to VIRTIO_CRYPTO_FLAG_SESSION_MODE.
\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
\end{itemize*}

\devicenormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}

\begin{itemize*}
\item The device MUST use the corresponding structure according to the \field{opcode}
    in the data general header.
\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, the device
    MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide
    which mode the driver uses.
\item The device MUST copy the results of HASH operations in the hash_result[] if HASH
    operations success.
\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the
    following values of enum VIRTIO_CRYPTO_STATUS:
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if the operation success.
\item VIRTIO_CRYPTO_NOTSUPP if the requested algorithm or operation is unsupported.
\item VIRTIO_CRYPTO_INVSESS if the session ID invalid when in session mode.
\item VIRTIO_CRYPTO_ERR if any failure not mentioned above occurs.
\end{itemize*}
\end{itemize*}


\subsubsection{MAC Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / MAC Service Operation}

Session mode MAC service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_mac_data_flf {
    struct virtio_crypto_hash_data_flf hdr;
};

struct virtio_crypto_mac_data_vlf {
    /* Device read only portion */
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

Each request uses the virtio_crypto_mac_data_flf structure and the
virtio_crypto_mac_data_vlf structure to store information used to run the
MAC operations.

\field{src_data} is the source data that will be processed.
\field{src_data_len} is the length of source data.
\field{hash_result} is the result data and \field{hash_result_len} is the length
of it.

Stateless mode MAC service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_mac_data_flf_stateless {
    struct {
        /* See VIRTIO_CRYPTO_MAC_* above */
        le32 algo;
        /* length of authenticated key */
        le32 auth_key_len;
    } sess_para;

    /* length of source data */
    le32 src_data_len;
    /* hash result length */
    le32 hash_result_len;
};

struct virtio_crypto_mac_data_vlf_stateless {
    /* Device read only portion */
    /* The authenticated key */
    u8 auth_key[auth_key_len];
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

\field{auth_key} is the authenticated key that will be used during the process.
\field{auth_key_len} is the length of the key.

\drivernormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}

\begin{itemize*}
\item If the driver uses the session mode, then the driver MUST set \field{session_id}
    in struct virtio_crypto_op_header to a valid value assigned by the device when the
    session was created.
\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, 1) if the
    driver uses the stateless mode, then the driver MUST set the \field{flag} field
    in struct virtio_crypto_op_header to ZERO and MUST set the fields in struct
    virtio_crypto_mac_data_flf_stateless.sess_para, 2) if the driver uses the session
    mode, then the driver MUST set the \field{flag} field in struct virtio_crypto_op_header
    to VIRTIO_CRYPTO_FLAG_SESSION_MODE.
\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_MAC.
\end{itemize*}

\devicenormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}

\begin{itemize*}
\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, the device
    MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide
	which mode the driver uses.
\item The device MUST copy the results of MAC operations in the hash_result[] if HASH
    operations success.
\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the
    following values of enum VIRTIO_CRYPTO_STATUS:
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if the operation success.
\item VIRTIO_CRYPTO_NOTSUPP if the requested algorithm or operation is unsupported.
\item VIRTIO_CRYPTO_INVSESS if the session ID invalid when in session mode.
\item VIRTIO_CRYPTO_ERR if any failure not mentioned above occurs.
\end{itemize*}
\end{itemize*}

\subsubsection{Symmetric algorithms Operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}

Session mode CIPHER service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_cipher_data_flf {
    /*
     * Byte Length of valid IV/Counter data pointed to by the below iv data.
     *
     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
     *   SNOW3G in UEA2 mode, this is the length of the IV (which
     *   must be the same as the block length of the cipher).
     * For block ciphers in CTR mode, this is the length of the counter
     *   (which must be the same as the block length of the cipher).
     */
    le32 iv_len;
    /* length of source data */
    le32 src_data_len;
    /* length of destination data */
    le32 dst_data_len;
    le32 padding;
};

struct virtio_crypto_cipher_data_vlf {
    /* Device read only portion */

    /*
     * Initialization Vector or Counter data.
     *
     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
     *   SNOW3G in UEA2 mode, this is the Initialization Vector (IV)
     *   value.
     * For block ciphers in CTR mode, this is the counter.
     * For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
     *
     * The IV/Counter will be updated after every partial cryptographic
     * operation.
     */
    u8 iv[iv_len];
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Destination data */
    u8 dst_data[dst_data_len];
};
\end{lstlisting}

Session mode requests of algorithm chaining are as follows:

\begin{lstlisting}
struct virtio_crypto_alg_chain_data_flf {
    le32 iv_len;
    /* Length of source data */
    le32 src_data_len;
    /* Length of destination data */
    le32 dst_data_len;
    /* Starting point for cipher processing in source data */
    le32 cipher_start_src_offset;
    /* Length of the source data that the cipher will be computed on */
    le32 len_to_cipher;
    /* Starting point for hash processing in source data */
    le32 hash_start_src_offset;
    /* Length of the source data that the hash will be computed on */
    le32 len_to_hash;
    /* Length of the additional auth data */
    le32 aad_len;
    /* Length of the hash result */
    le32 hash_result_len;
    le32 reserved;
};

struct virtio_crypto_alg_chain_data_vlf {
    /* Device read only portion */

    /* Initialization Vector or Counter data */
    u8 iv[iv_len];
    /* Source data */
    u8 src_data[src_data_len];
    /* Additional authenticated data if exists */
    u8 aad[aad_len];

    /* Device write only portion */

    /* Destination data */
    u8 dst_data[dst_data_len];
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

Session mode requests of symmetric algorithm are as follows:

\begin{lstlisting}
struct virtio_crypto_sym_data_flf {
    /* Device read only portion */

#define VIRTIO_CRYPTO_SYM_DATA_REQ_HDR_SIZE    40
    u8 op_type_flf[VIRTIO_CRYPTO_SYM_DATA_REQ_HDR_SIZE];

    /* See above VIRTIO_CRYPTO_SYM_OP_* */
    le32 op_type;
    le32 padding;
};

struct virtio_crypto_sym_data_vlf {
    u8 op_type_vlf[sym_para_len];
};
\end{lstlisting}

Each request uses the virtio_crypto_sym_data_flf structure and the
virtio_crypto_sym_data_flf structure to store information used to run the
CIPHER operations.

\field{op_type_flf} is the \field{op_type} specific header, it MUST starts
with or be one of the following structures:
\begin{itemize*}
\item struct virtio_crypto_cipher_data_flf
\item struct virtio_crypto_alg_chain_data_flf
\end{itemize*}

The length of \field{op_type_flf} is fixed to 40 bytes, the data of unused
part (if has) will be ingored.

\field{op_type_vlf} is the \field{op_type} specific parameters, it MUST starts
with or be one of the following structures:
\begin{itemize*}
\item struct virtio_crypto_cipher_data_vlf
\item struct virtio_crypto_alg_chain_data_vlf
\end{itemize*}

\field{sym_para_len} is the size of the specific structure used.

Stateless mode CIPHER service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_cipher_data_flf_stateless {
    struct {
        /* See VIRTIO_CRYPTO_CIPHER* above */
        le32 algo;
        /* length of key */
        le32 key_len;

        /* See VIRTIO_CRYPTO_OP_* above */
        le32 op;
    } sess_para;

    /*
     * Byte Length of valid IV/Counter data pointed to by the below iv data.
     */
    le32 iv_len;
    /* length of source data */
    le32 src_data_len;
    /* length of destination data */
    le32 dst_data_len;
};

struct virtio_crypto_cipher_data_vlf_stateless {
    /* Device read only portion */

    /* The cipher key */
    u8 cipher_key[key_len];

    /* Initialization Vector or Counter data. */
    u8 iv[iv_len];
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */
    /* Destination data */
    u8 dst_data[dst_data_len];
};
\end{lstlisting}

Stateless mode requests of algorithm chaining are as follows:

\begin{lstlisting}
struct virtio_crypto_alg_chain_data_flf_stateless {
    struct {
        /* See VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_* above */
        le32 alg_chain_order;
        /* length of the additional authenticated data in bytes */
        le32 aad_len;

        struct {
            /* See VIRTIO_CRYPTO_CIPHER* above */
            le32 algo;
            /* length of key */
            le32 key_len;
            /* See VIRTIO_CRYPTO_OP_* above */
            le32 op;
        } cipher;

        struct {
            /* See VIRTIO_CRYPTO_HASH_* or VIRTIO_CRYPTO_MAC_* above */
            le32 algo;
            /* length of authenticated key */
            le32 auth_key_len;
            /* See VIRTIO_CRYPTO_SYM_HASH_MODE_* above */
            le32 hash_mode;
        } hash;
    } sess_para;

    le32 iv_len;
    /* Length of source data */
    le32 src_data_len;
    /* Length of destination data */
    le32 dst_data_len;
    /* Starting point for cipher processing in source data */
    le32 cipher_start_src_offset;
    /* Length of the source data that the cipher will be computed on */
    le32 len_to_cipher;
    /* Starting point for hash processing in source data */
    le32 hash_start_src_offset;
    /* Length of the source data that the hash will be computed on */
    le32 len_to_hash;
    /* Length of the additional auth data */
    le32 aad_len;
    /* Length of the hash result */
    le32 hash_result_len;
    le32 reserved;
};

struct virtio_crypto_alg_chain_data_vlf_stateless {
    /* Device read only portion */

    /* The cipher key */
    u8 cipher_key[key_len];
    /* The auth key */
    u8 auth_key[auth_key_len];
    /* Initialization Vector or Counter data */
    u8 iv[iv_len];
    /* Additional authenticated data if exists */
    u8 aad[aad_len];
    /* Source data */
    u8 src_data[src_data_len];

    /* Device write only portion */

    /* Destination data */
    u8 dst_data[dst_data_len];
    /* Hash result data */
    u8 hash_result[hash_result_len];
};
\end{lstlisting}

Stateless mode requests of symmetric algorithm are as follows:

\begin{lstlisting}
struct virtio_crypto_sym_data_flf_stateless {
    /* Device read only portion */
#define VIRTIO_CRYPTO_SYM_DATE_REQ_HDR_STATELESS_SIZE    72
    u8 op_type_flf[VIRTIO_CRYPTO_SYM_DATE_REQ_HDR_STATELESS_SIZE];

    /* Device write only portion */
    /* See above VIRTIO_CRYPTO_SYM_OP_* */
    le32 op_type;
};

struct virtio_crypto_sym_data_vlf_stateless {
    u8 op_type_vlf[sym_para_len];
};
\end{lstlisting}

\field{op_type_flf} is the \field{op_type} specific header, it MUST starts
with or be one of the following structures:
\begin{itemize*}
\item struct virtio_crypto_cipher_data_flf_stateless
\item struct virtio_crypto_alg_chain_data_flf_stateless
\end{itemize*}

The length of \field{op_type_flf} is fixed to 72 bytes, the data of unused
part (if has) will be ingored.

\field{op_type_vlf} is the \field{op_type} specific parameters, it MUST starts
with or be one of the following structures:
\begin{itemize*}
\item struct virtio_crypto_cipher_data_vlf_stateless
\item struct virtio_crypto_alg_chain_data_vlf_stateless
\end{itemize*}

\field{sym_para_len} is the size of the specific structure used.

\drivernormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}

\begin{itemize*}
\item If the driver uses the session mode, then the driver MUST set \field{session_id}
    in struct virtio_crypto_op_header to a valid value assigned by the device when the
    session was created.
\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, 1) if the
    driver uses the stateless mode, then the driver MUST set the \field{flag} field in
    struct virtio_crypto_op_header to ZERO and MUST set the fields in struct
    virtio_crypto_cipher_data_flf_stateless.sess_para or struct
    virtio_crypto_alg_chain_data_flf_stateless.sess_para, 2) if the driver uses the
    session mode, then the driver MUST set the \field{flag} field in struct
    virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_SESSION_MODE.
\item The driver MUST set the \field{opcode} field in struct virtio_crypto_op_header
    to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
\item The driver MUST specify the fields of struct virtio_crypto_cipher_data_flf in
    struct virtio_crypto_sym_data_flf and struct virtio_crypto_cipher_data_vlf in
    struct virtio_crypto_sym_data_vlf if the request is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
\item The driver MUST specify the fields of struct virtio_crypto_alg_chain_data_flf
    in struct virtio_crypto_sym_data_flf and struct virtio_crypto_alg_chain_data_vlf
    in struct virtio_crypto_sym_data_vlf if the request is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING
    type.
\end{itemize*}

\devicenormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}

\begin{itemize*}
\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the device
    MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide
	which mode the driver uses.
\item The device MUST parse the virtio_crypto_sym_data_req based on the \field{opcode}
    field in general header.
\item The device MUST parse the fields of struct virtio_crypto_cipher_data_flf in
    struct virtio_crypto_sym_data_flf and struct virtio_crypto_cipher_data_vlf in
    struct virtio_crypto_sym_data_vlf if the request is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
\item The device MUST parse the fields of struct virtio_crypto_alg_chain_data_flf
    in struct virtio_crypto_sym_data_flf and struct virtio_crypto_alg_chain_data_vlf
    in struct virtio_crypto_sym_data_vlf if the request is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING
    type.
\item The device MUST copy the result of cryptographic operation in the dst_data[] in
    both plain CIPHER mode and algorithms chain mode.
\item The device MUST check the \field{para}.\field{add_len} is bigger than 0 before
    parse the additional authenticated data in plain algorithms chain mode.
\item The device MUST copy the result of HASH/MAC operation in the hash_result[] is
    of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type.
\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to
    one of the following values of enum VIRTIO_CRYPTO_STATUS:
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if the operation success.
\item VIRTIO_CRYPTO_NOTSUPP if the requested algorithm or operation is unsupported.
\item VIRTIO_CRYPTO_INVSESS if the session ID is invalid in session mode.
\item VIRTIO_CRYPTO_ERR if failure not mentioned above occurs.
\end{itemize*}
\end{itemize*}

\subsubsection{AEAD Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / AEAD Service Operation}

Session mode requests of symmetric algorithm are as follows:

\begin{lstlisting}
struct virtio_crypto_aead_data_flf {
    /*
     * Byte Length of valid IV data.
     *
     * For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
     *   case iv points to J0.
     * For CCM mode, this is the length of the nonce, which can be in the
     *   range 7 to 13 inclusive.
     */
    le32 iv_len;
    /* length of additional auth data */
    le32 aad_len;
    /* length of source data */
    le32 src_data_len;
    /* length of dst data, this should be at least src_data_len + tag_len */
    le32 dst_data_len;
    /* Authentication tag length */
    le32 tag_len;
    le32 reserved;
};

struct virtio_crypto_aead_data_vlf {
    /* Device read only portion */

    /*
     * Initialization Vector data.
     *
     * For GCM mode, this is either the IV (if the length is 96 bits) or J0
     *   (for other sizes), where J0 is as defined by NIST SP800-38D.
     *   Regardless of the IV length, a full 16 bytes needs to be allocated.
     * For CCM mode, the first byte is reserved, and the nonce should be
     *   written starting at &iv[1] (to allow space for the implementation
     *   to write in the flags in the first byte).  Note that a full 16 bytes
     *   should be allocated, even though the iv_len field will have
     *   a value less than this.
     *
     * The IV will be updated after every partial cryptographic operation.
     */
    u8 iv[iv_len];
    /* Source data */
    u8 src_data[src_data_len];
    /* Additional authenticated data if exists */
    u8 aad[aad_len];

    /* Device write only portion */
    /* Pointer to output data */
    u8 dst_data[dst_data_len];
};
\end{lstlisting}

Each request uses the virtio_crypto_aead_data_flf structure and the
virtio_crypto_aead_data_flf structure to store information used to run the
AEAD operations.

Stateless mode AEAD service requests are as follows:

\begin{lstlisting}
struct virtio_crypto_aead_data_flf_stateless {
    struct {
        /* See VIRTIO_CRYPTO_AEAD_* above */
        le32 algo;
        /* length of key */
        le32 key_len;
        /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
        le32 op;
    } sess_para;

    /* Byte Length of valid IV data. */
    le32 iv_len;
    /* Authentication tag length */
    le32 tag_len;
    /* length of additional auth data */
    le32 aad_len;
    /* length of source data */
    le32 src_data_len;
    /* length of dst data, this should be at least src_data_len + tag_len */
    le32 dst_data_len;
};

struct virtio_crypto_aead_data_vlf_stateless {
    /* Device read only portion */

    /* The cipher key */
    u8 key[key_len];
    /* Initialization Vector data. */
    u8 iv[iv_len];
    /* Source data */
    u8 src_data[src_data_len];
    /* Additional authenticated data if exists */
    u8 aad[aad_len];

    /* Device write only portion */
    /* Pointer to output data */
    u8 dst_data[dst_data_len];
};
\end{lstlisting}

\drivernormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}

\begin{itemize*}
\item If the driver uses the session mode, then the driver MUST set
    \field{session_id} in struct virtio_crypto_op_header to a valid value assigned
    by the device when the session was created.
\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, 1) if
    the driver uses the stateless mode, then the driver MUST set the \field{flag}
    field in struct virtio_crypto_op_header to ZERO and MUST set the fields in
    struct virtio_crypto_aead_data_flf_stateless.sess_para, 2) if the driver uses
    the session mode, then the driver MUST set the \field{flag} field in struct
    virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_SESSION_MODE.
\item The driver MUST set the \field{opcode} field in struct virtio_crypto_op_header
    to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
\end{itemize*}

\devicenormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}

\begin{itemize*}
\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, the
    device MUST parse the virtio_crypto_aead_data_vlf_stateless based on the \field{opcode}
	field in general header.
\item The device MUST copy the result of cryptographic operation in the dst_data[].
\item The device MUST copy the authentication tag in the dst_data[] offset the cipher result.
\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to
    one of the following values of enum VIRTIO_CRYPTO_STATUS:
\item When the \field{opcode} field is VIRTIO_CRYPTO_AEAD_DECRYPT, the device MUST
    verify and return the verification result to the driver.
\begin{itemize*}
\item VIRTIO_CRYPTO_OK if the operation success.
\item VIRTIO_CRYPTO_NOTSUPP if the requested algorithm or operation is unsupported.
\item VIRTIO_CRYPTO_BADMSG if the verification result is incorrect.
\item VIRTIO_CRYPTO_INVSESS if the session ID invalid when in session mode.
\item VIRTIO_CRYPTO_ERR if any failure not mentioned above occurs.
\end{itemize*}
\end{itemize*}