This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, api-next has been updated via 7cc568a011f1623a343399f5cff6688baf834639 (commit) via b962b9194d63b679afc5218858a3742ec6b3dda1 (commit) via 8483bfa972e4af9ee80ab3318caf99270c37daa0 (commit) via 506267929ac4b1eee22263abf8721088d7b4a5c7 (commit) via e204106fb2e255b76e32a1376c935cee4c5a8e90 (commit) via b11eb35bf651c8e7b636f3ae63f10e756a3132d2 (commit) via aaf3b3a688dff27255cb318b219651099521a4fb (commit) via 8ef9bf024d0a42d99ae5218ec9b00d48f4f7ab35 (commit) via bbc78105ff8a1d9cd591b672eb2bb878a62c76b2 (commit) via 89c4f15c0c7d63a10161c716367bcb392c23c20b (commit) via e3e2773d6bf9b25f10b487c048cf61a0a0f1e887 (commit) via a6e2ebeb671ea322cea1af81a35b1c564f06f33f (commit) via e89a66c12db16f6ff4619683f58cd1a63f16eb10 (commit) via ae8385cb0a0f5a222684775eea0efc5bb034252f (commit) via 22a158d4082d8d810443dd7a4191522c6f95b742 (commit) via 18d1eb9e00ef871c0da9e60989d83455b7fda4c2 (commit) via 815f7ada60297c08469ab62cee369df4770ae2aa (commit) via f8fa58a9061def1f7fdfc5adbb09c7fa67e1d425 (commit) via 98c59aa12adb2acda489261a631cb85c6bdbb358 (commit) via 036c1011222ee0e75d8572332aff9043510c3ec3 (commit) via 5f4692a06e9241411ccba088142782638f1f9f96 (commit) via 1b2c9fb5cb2a64a6ca0c623173dea966f45c5e4a (commit) from 5718327018debbb02aacb464493504c95fbe57a3 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 7cc568a011f1623a343399f5cff6688baf834639 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Jan 18 14:45:03 2018 +0200
api: ipsec: inbound inner packet checksum capability
Add inbound inner packet checksum check capability. When e.g. L4 checksum checking is not implemented in HW, it may be better to leave checking for application, as it would check only those packets that need the check.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 665dc07b..2d1c4d9b 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -238,6 +238,11 @@ typedef struct odp_ipsec_capability_t { */ odp_support_t retain_header;
+ /** + * Inner packet checksum check offload support in inbound direction. + */ + odp_proto_chksums_t chksums_in; + /** Maximum number of different destination CoSes in classification * pipelining. The same CoS may be used for many SAs. This is equal or * less than 'max_cos' capability in classifier API.
commit b962b9194d63b679afc5218858a3742ec6b3dda1 Author: Petri Savolainen petri.savolainen@linaro.org Date: Tue Jan 23 13:50:24 2018 +0200
api: ipsec: outbound TFC padding and dummy packets
Specify how application can request TFC padding and dummy packet creation at output. Application can use odp_ipsec_out_opt_t options to reguest addition of TFC padding, or creation of a TFC dummy packet (next header = 59). IP parameter override options are needed for tunnel mode dummy packet creation as there's no IP header to copy e.g. DSCP or flow label values to tunnel IP header.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 721f9685..665dc07b 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -991,6 +991,22 @@ typedef struct odp_ipsec_out_opt_t { /** Use fragmentation mode option */ uint32_t frag_mode: 1;
+ /** Use TFC padding length option */ + uint32_t tfc_pad: 1; + + /** Tunnel mode TFC dummy packet. This can be used only + * in tunnel mode. When the flag is set, packet length + * and content is ignored and instead a TFC dummy + * packet is created during IPSEC operation. The dummy + * packet length is defined by 'tfc_pad_len' option. + * If the SA is configured to copy IP header fields + * from inner IP packet, those fields must be passed + * with IP parameters option. */ + uint32_t tfc_dummy: 1; + + /** Use IP parameters option */ + uint32_t ip_param: 1; + } flag;
/** All flag bits */ @@ -1000,6 +1016,26 @@ typedef struct odp_ipsec_out_opt_t { /** Fragmentation mode */ odp_ipsec_frag_mode_t frag_mode;
+ /** TFC padding length + * + * Number of TFC padding bytes added to the packet during IPSEC + * processing. Resulting packet should not exceed the maximum packet + * length of the pool, otherwise IPSEC operation may fail. + * Implementation guarantees that the padding does not contain any + * confidential information. */ + uint32_t tfc_pad_len; + + /** Union of IP parameters */ + union { + /** Override IPv4 parameters in outer header creation. + * IP addresses are ignored. */ + odp_ipsec_ipv4_param_t ipv4; + + /** Override IPv6 parameters in outer header creation. + * IP addresses are ignored. */ + odp_ipsec_ipv6_param_t ipv6; + }; + } odp_ipsec_out_opt_t;
/** @@ -1302,7 +1338,13 @@ int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in, * The operation does packet transformation according to IPSEC standards (see * e.g. RFC 4302 and 4303). Resulting packets are well formed IP packets * with IPSEC, etc headers constructed according to the standards. The amount - * and content of packet data before the IP header is undefined. + * and content of packet data before the IP header is undefined. Use outbound + * operation parameters to specify the amount of TFC padding appended to + * the packet during IPSEC transformation. Options can be used also to create + * TFC dummy packets. Packet data content is ignored in tunnel mode TFC dummy + * packet creation as tfc_pad_len option defines solely the packet length. + * In all other cases, payload length for the IPSEC transformation is specified + * by odp_packet_len() minus odp_packet_l3_offset() plus tfc_pad_len option. * * Each successfully transformed packet has a valid value for these metadata: * - L3 offset: Offset to the first byte of the (outmost) IP header
commit 8483bfa972e4af9ee80ab3318caf99270c37daa0 Author: Petri Savolainen petri.savolainen@linaro.org Date: Tue Jan 23 13:46:26 2018 +0200
api: ipsec: inbound TFC padding and dummy packets
Specify how application can recognize TFC padding and dummy packets at input. Packet metadata for L3/L4 protocol type indicate if the original packet was an IP or a TFC dummy packet. When packet length is larger than protocol fields indicate, some TFC padding remain in the packet.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 08533d80..721f9685 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -1226,12 +1226,23 @@ typedef struct odp_ipsec_status_t { * e.g. RFC 4302 and 4303). Resulting packets are well formed, reconstructed * original IP packets, with IPSEC headers removed and valid header field values * restored. The amount and content of packet data before the IP header is - * undefined. + * undefined. Some amount of TFC padding may follow the IP packet payload, + * in which case packet length is larger than protocol headers indicate. + * TFC dummy packets have l3_type set to ODP_PROTO_L3_TYPE_NONE in tunnel mode + * or l4_type set to ODP_PROTO_L4_TYPE_NO_NEXT in transport mode. Dummy + * packets contain implementation specific amount of (dummy) data. Furthermore, + * inline IPSEC processing may drop dummy packets. * * Each successfully transformed packet has a valid value for these metadata * regardless of the inner packet parse configuration * (odp_ipsec_inbound_config_t): - * - L3 offset: Offset to the first byte of the (outmost) IP header + * - l3_offset: Offset to the first byte of the original IP packet. The value + * is implementation specific for tunnel mode TFC dummy packets. + * - l3_type: Specifies if the original packet is IPv4 or IPv6. For tunnel + * mode TFC dummy packets set to ODP_PROTO_L3_TYPE_NONE. + * - l4_type: Always set to ODP_PROTO_L4_TYPE_NO_NEXT for transport mode dummy + * packets. Otherwise, depends on parse configuration. Default + * value is ODP_PROTO_L4_TYPE_NONE. * - pktio: For inline IPSEC processed packets, original packet input * interface *
commit 506267929ac4b1eee22263abf8721088d7b4a5c7 Author: Petri Savolainen petri.savolainen@linaro.org Date: Tue Jan 23 13:37:20 2018 +0200
api: ipsec: outbound operation option flags
Add flags to select which options application uses. Currently, there's no ambiguity, but as soon as there are multiple options implementation needs to know which options are used and which are ignored.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 1060a3ee..08533d80 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -983,6 +983,20 @@ typedef struct odp_ipsec_op_flag_t { * These may be used to override some SA level options */ typedef struct odp_ipsec_out_opt_t { + /** Union of all flag bits */ + union { + /** Option flags. Set flag for those options that are + * used, all other options are ignored. */ + struct { + /** Use fragmentation mode option */ + uint32_t frag_mode: 1; + + } flag; + + /** All flag bits */ + uint32_t all_flags; + }; + /** Fragmentation mode */ odp_ipsec_frag_mode_t frag_mode;
commit e204106fb2e255b76e32a1376c935cee4c5a8e90 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Jan 18 13:26:56 2018 +0200
api: ipsec: rename fragmentation mode option
Rename outbound operation fragmentation options to frag_mode. Frag_mode is used elsewhere in the API and "mode" is too generic term for it (not future proof).
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index c78afbe3..1060a3ee 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -984,7 +984,7 @@ typedef struct odp_ipsec_op_flag_t { */ typedef struct odp_ipsec_out_opt_t { /** Fragmentation mode */ - odp_ipsec_frag_mode_t mode; + odp_ipsec_frag_mode_t frag_mode;
} odp_ipsec_out_opt_t;
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 43d7b9f5..65be5aff 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -1307,7 +1307,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt, ipsec_sa = _odp_ipsec_sa_use(sa); ODP_ASSERT(NULL != ipsec_sa);
- if ((opt && opt->mode == ODP_IPSEC_FRAG_CHECK) || + if ((opt && opt->frag_mode == ODP_IPSEC_FRAG_CHECK) || (!opt && ipsec_sa->out.frag_mode == ODP_IPSEC_FRAG_CHECK)) mtu = ipsec_sa->out.mtu; else diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 0f49c7e1..2850ddfa 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -572,7 +572,7 @@ static void test_out_ipv4_ah_sha256_frag_check(void) ipsec_test_part test2 = { .pkt_in = &pkt_ipv4_icmp_0, .num_opt = 1, - .opt = { .mode = ODP_IPSEC_FRAG_DISABLED, }, + .opt = { .frag_mode = ODP_IPSEC_FRAG_DISABLED, }, .out_pkt = 1, .out = { { .status.warn.all = 0, @@ -665,7 +665,7 @@ static void test_out_ipv4_esp_null_sha256_frag_check(void) ipsec_test_part test2 = { .pkt_in = &pkt_ipv4_icmp_0, .num_opt = 1, - .opt = { .mode = ODP_IPSEC_FRAG_DISABLED, }, + .opt = { .frag_mode = ODP_IPSEC_FRAG_DISABLED, }, .out_pkt = 1, .out = { { .status.warn.all = 0,
commit b11eb35bf651c8e7b636f3ae63f10e756a3132d2 Author: Petri Savolainen petri.savolainen@linaro.org Date: Thu Jan 18 11:02:27 2018 +0200
api: ipsec: IP header parameter types
Create IP header parameter types, so that those can be used also outside of SA parameter struct.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index 47e3045f..c78afbe3 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -382,6 +382,44 @@ typedef struct odp_ipsec_crypto_param_t {
} odp_ipsec_crypto_param_t;
+/** IPv4 header parameters */ +typedef struct odp_ipsec_ipv4_param_t { + /** IPv4 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv4 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv4 Differentiated Services Code Point */ + uint8_t dscp; + + /** IPv4 Don't Fragment bit */ + uint8_t df; + + /** IPv4 Time To Live */ + uint8_t ttl; + +} odp_ipsec_ipv4_param_t; + +/** IPv6 header parameters */ +typedef struct odp_ipsec_ipv6_param_t { + /** IPv6 source address (NETWORK ENDIAN) */ + void *src_addr; + + /** IPv6 destination address (NETWORK ENDIAN) */ + void *dst_addr; + + /** IPv6 flow label */ + uint32_t flabel; + + /** IPv6 Differentiated Services Code Point */ + uint8_t dscp; + + /** IPv6 hop limit */ + uint8_t hlimit; + +} odp_ipsec_ipv6_param_t; + /** * IPSEC tunnel parameters * @@ -397,40 +435,10 @@ typedef struct odp_ipsec_tunnel_param_t { /** Variant mappings for tunnel parameters */ union { /** IPv4 header parameters */ - struct { - /** IPv4 source address (NETWORK ENDIAN) */ - void *src_addr; - - /** IPv4 destination address (NETWORK ENDIAN) */ - void *dst_addr; - - /** IPv4 Differentiated Services Code Point */ - uint8_t dscp; - - /** IPv4 Don't Fragment bit */ - uint8_t df; - - /** IPv4 Time To Live */ - uint8_t ttl; - } ipv4; + odp_ipsec_ipv4_param_t ipv4;
/** IPv6 header parameters */ - struct { - /** IPv6 source address (NETWORK ENDIAN) */ - void *src_addr; - - /** IPv6 destination address (NETWORK ENDIAN) */ - void *dst_addr; - - /** IPv6 Differentiated Services Code Point */ - uint8_t dscp; - - /** IPv6 flow label */ - uint32_t flabel; - - /** IPv6 hop limit */ - uint8_t hlimit; - } ipv6; + odp_ipsec_ipv6_param_t ipv6; }; } odp_ipsec_tunnel_param_t;
commit aaf3b3a688dff27255cb318b219651099521a4fb Author: Petri Savolainen petri.savolainen@linaro.org Date: Wed Jan 31 15:03:20 2018 +0200
api: packet: add protocol type enumeration
Add enumerations for L3 and L4 protocol types, and functions to request those.
Signed-off-by: Petri Savolainen petri.savolainen@linaro.org Reviewed-by: Balasubramanian Manoharan bala.manoharan@linaro.org Reviewed-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/abi-default/packet.h b/include/odp/api/abi-default/packet.h index 3d687673..b83288d4 100644 --- a/include/odp/api/abi-default/packet.h +++ b/include/odp/api/abi-default/packet.h @@ -30,6 +30,34 @@ typedef _odp_abi_packet_seg_t *odp_packet_seg_t; #define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)0xffffffff) #define ODP_PACKET_OFFSET_INVALID 0xffff
+typedef uint8_t odp_proto_l3_type_t; + +#define ODP_PROTO_L3_TYPE_NONE 0 +#define ODP_PROTO_L3_TYPE_ARP 1 +#define ODP_PROTO_L3_TYPE_RARP 2 +#define ODP_PROTO_L3_TYPE_MPLS 3 +#define ODP_PROTO_L3_TYPE_IPV4 4 +#define ODP_PROTO_L3_TYPE_IPV6 6 + +typedef uint8_t odp_proto_l4_type_t; + +/* Numbers from IANA Assigned Internet Protocol Numbers list */ +#define ODP_PROTO_L4_TYPE_NONE 0 +#define ODP_PROTO_L4_TYPE_ICMPV4 1 +#define ODP_PROTO_L4_TYPE_IGMP 2 +#define ODP_PROTO_L4_TYPE_IPV4 4 +#define ODP_PROTO_L4_TYPE_TCP 6 +#define ODP_PROTO_L4_TYPE_UDP 17 +#define ODP_PROTO_L4_TYPE_IPV6 41 +#define ODP_PROTO_L4_TYPE_GRE 47 +#define ODP_PROTO_L4_TYPE_ESP 50 +#define ODP_PROTO_L4_TYPE_AH 51 +#define ODP_PROTO_L4_TYPE_ICMPV6 58 +#define ODP_PROTO_L4_TYPE_NO_NEXT 59 +#define ODP_PROTO_L4_TYPE_IPCOMP 108 +#define ODP_PROTO_L4_TYPE_SCTP 132 +#define ODP_PROTO_L4_TYPE_ROHC 142 + typedef enum { ODP_PACKET_GREEN = 0, ODP_PACKET_YELLOW = 1, diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 3222ff5c..4be515c7 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -71,6 +71,79 @@ extern "C" { * Packet is red */
+/** + * @typedef odp_proto_l3_type_t + * Layer 3 protocol type + */ + +/** + * @def ODP_PROTO_L3_TYPE_NONE + * Layer 3 protocol type not defined + * + * @def ODP_PROTO_L3_TYPE_ARP + * Layer 3 protocol is ARP + * + * @def ODP_PROTO_L3_TYPE_RARP + * Layer 3 protocol is RARP + * + * @def ODP_PROTO_L3_TYPE_MPLS + * Layer 3 protocol is MPLS + * + * @def ODP_PROTO_L3_TYPE_IPV4 + * Layer 3 protocol type is IPv4 + * + * @def ODP_PROTO_L3_TYPE_IPV6 + * Layer 3 protocol type is IPv6 + */ + +/** + * @def ODP_PROTO_L4_TYPE_NONE + * Layer 4 protocol type not defined + * + * @def ODP_PROTO_L4_TYPE_ICMPV4 + * Layer 4 protocol type is ICMPv4 + * + * @def ODP_PROTO_L4_TYPE_IGMP + * Layer 4 protocol type is IGMP + * + * @def ODP_PROTO_L4_TYPE_IPV4 + * Layer 4 protocol type is IPv4 + * + * @def ODP_PROTO_L4_TYPE_TCP + * Layer 4 protocol type is TCP + * + * @def ODP_PROTO_L4_TYPE_UDP + * Layer 4 protocol type is UDP + * + * @def ODP_PROTO_L4_TYPE_IPV6 + * Layer 4 protocol type is IPv6 + * + * @def ODP_PROTO_L4_TYPE_GRE + * Layer 4 protocol type is GRE + * + * @def ODP_PROTO_L4_TYPE_ESP + * Layer 4 protocol type is IPSEC ESP + * + * @def ODP_PROTO_L4_TYPE_AH + * Layer 4 protocol type is IPSEC AH + * + * @def ODP_PROTO_L4_TYPE_ICMPV6 + * Layer 4 protocol type is ICMPv6 + * + * @def ODP_PROTO_L4_TYPE_NO_NEXT + * Layer 4 protocol type is "No Next Header". + * Protocol / next header number is 59. + * + * @def ODP_PROTO_L4_TYPE_IPCOMP + * Layer 4 protocol type is IP Payload Compression Protocol + * + * @def ODP_PROTO_L4_TYPE_SCTP + * Layer 4 protocol type is SCTP + * + * @def ODP_PROTO_L4_TYPE_ROHC + * Layer 4 protocol type is ROHC + */ + /** * Protocol */ @@ -1542,6 +1615,28 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt); */ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset);
+/** + * Layer 3 protocol type + * + * Returns layer 3 protocol type. Initial type value is ODP_PROTO_L3_TYPE_NONE. + * + * @param pkt Packet handle + * + * @return Layer 3 protocol type + */ +odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt); + +/** + * Layer 4 protocol type + * + * Returns layer 4 protocol type. Initial type value is ODP_PROTO_L4_TYPE_NONE. + * + * @param pkt Packet handle + * + * @return Layer 4 protocol type + */ +odp_proto_l4_type_t odp_packet_l4_type(odp_packet_t pkt); + /** * Layer 3 checksum check status * diff --git a/platform/linux-generic/include-abi/odp/api/abi/packet.h b/platform/linux-generic/include-abi/odp/api/abi/packet.h index 1aa7cbd5..137cd3ec 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/packet.h +++ b/platform/linux-generic/include-abi/odp/api/abi/packet.h @@ -47,6 +47,34 @@ static inline odp_packet_seg_t _odp_packet_seg_from_ndx(uint8_t ndx)
#define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)-1)
+typedef uint8_t odp_proto_l3_type_t; + +#define ODP_PROTO_L3_TYPE_NONE 0 +#define ODP_PROTO_L3_TYPE_ARP 1 +#define ODP_PROTO_L3_TYPE_RARP 2 +#define ODP_PROTO_L3_TYPE_MPLS 3 +#define ODP_PROTO_L3_TYPE_IPV4 4 +#define ODP_PROTO_L3_TYPE_IPV6 6 + +typedef uint8_t odp_proto_l4_type_t; + +/* Numbers from IANA Assigned Internet Protocol Numbers list */ +#define ODP_PROTO_L4_TYPE_NONE 0 +#define ODP_PROTO_L4_TYPE_ICMPV4 1 +#define ODP_PROTO_L4_TYPE_IGMP 2 +#define ODP_PROTO_L4_TYPE_IPV4 4 +#define ODP_PROTO_L4_TYPE_TCP 6 +#define ODP_PROTO_L4_TYPE_UDP 17 +#define ODP_PROTO_L4_TYPE_IPV6 41 +#define ODP_PROTO_L4_TYPE_GRE 47 +#define ODP_PROTO_L4_TYPE_ESP 50 +#define ODP_PROTO_L4_TYPE_AH 51 +#define ODP_PROTO_L4_TYPE_ICMPV6 58 +#define ODP_PROTO_L4_TYPE_NO_NEXT 59 +#define ODP_PROTO_L4_TYPE_IPCOMP 108 +#define ODP_PROTO_L4_TYPE_SCTP 132 +#define ODP_PROTO_L4_TYPE_ROHC 142 + typedef enum { ODP_PACKET_GREEN = 0, ODP_PACKET_YELLOW = 1,
commit 8ef9bf024d0a42d99ae5218ec9b00d48f4f7ab35 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 08:03:56 2018 +0300
linux-gen: ipsec: support ChaCha20-Poly1305
Support IPsec ChaCha20-Poly1305 on top of linux-generic's crypto support.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index b6192377..43d7b9f5 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -112,6 +112,7 @@ int odp_ipsec_auth_capability(odp_auth_alg_t auth, continue;
if (ODP_AUTH_ALG_AES_GCM == auth || + ODP_AUTH_ALG_CHACHA20_POLY1305 == auth || ODP_DEPRECATE(ODP_AUTH_ALG_AES128_GCM) == auth) { uint8_t aad_len = 12;
diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c index 031adef6..d9773540 100644 --- a/platform/linux-generic/odp_ipsec_sad.c +++ b/platform/linux-generic/odp_ipsec_sad.c @@ -210,6 +210,8 @@ uint32_t _odp_ipsec_cipher_iv_len(odp_cipher_alg_t cipher) #endif case ODP_CIPHER_ALG_AES_GCM: return 12; + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + return 12; default: return (uint32_t)-1; } @@ -240,6 +242,8 @@ uint32_t _odp_ipsec_auth_digest_len(odp_auth_alg_t auth) case ODP_AUTH_ALG_AES_GCM: case ODP_AUTH_ALG_AES_GMAC: return 16; + case ODP_AUTH_ALG_CHACHA20_POLY1305: + return 16; default: return (uint32_t)-1; } @@ -392,6 +396,11 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) ipsec_sa->esp_iv_len = 8; ipsec_sa->esp_block_len = 16; break; + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + ipsec_sa->use_counter_iv = 1; + ipsec_sa->esp_iv_len = 8; + ipsec_sa->esp_block_len = 1; + break; default: goto error; } @@ -411,6 +420,9 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param) ipsec_sa->esp_block_len = 16; crypto_param.auth_iv.length = 12; break; + case ODP_AUTH_ALG_CHACHA20_POLY1305: + crypto_param.auth_aad_len = sizeof(ipsec_aad_t); + break; default: break; }
commit bbc78105ff8a1d9cd591b672eb2bb878a62c76b2 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 08:03:19 2018 +0300
validation: ipsec: add ChaCha20-Poly1305 test vectors
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index 5d3112a2..31bd557f 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -177,6 +177,10 @@ int ipsec_check(odp_bool_t ah, if (!capa.ciphers.bit.aes_gcm) return ODP_TEST_INACTIVE; break; + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + if (!capa.ciphers.bit.chacha20_poly1305) + return ODP_TEST_INACTIVE; + break; default: fprintf(stderr, "Unsupported cipher algorithm\n"); return ODP_TEST_INACTIVE; @@ -212,6 +216,10 @@ int ipsec_check(odp_bool_t ah, if (!capa.auths.bit.aes_gmac) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_CHACHA20_POLY1305: + if (!capa.auths.bit.chacha20_poly1305) + return ODP_TEST_INACTIVE; + break; default: fprintf(stderr, "Unsupported authentication algorithm\n"); return ODP_TEST_INACTIVE; @@ -313,6 +321,12 @@ int ipsec_check_esp_null_aes_gmac_128(void) ODP_AUTH_ALG_AES_GMAC, 128); }
+int ipsec_check_esp_chacha20_poly1305(void) +{ + return ipsec_check_esp(ODP_CIPHER_ALG_CHACHA20_POLY1305, 256, + ODP_AUTH_ALG_CHACHA20_POLY1305, 0); +} + void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, odp_bool_t in, odp_bool_t ah, diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h index 31ebed78..7ba9ef10 100644 --- a/test/validation/api/ipsec/ipsec.h +++ b/test/validation/api/ipsec/ipsec.h @@ -91,5 +91,6 @@ int ipsec_check_esp_aes_gcm_128(void); int ipsec_check_esp_aes_gcm_256(void); int ipsec_check_ah_aes_gmac_128(void); int ipsec_check_esp_null_aes_gmac_128(void); +int ipsec_check_esp_chacha20_poly1305(void);
#endif diff --git a/test/validation/api/ipsec/ipsec_test_in.c b/test/validation/api/ipsec/ipsec_test_in.c index 8a82abe4..8138defb 100644 --- a/test/validation/api/ipsec/ipsec_test_in.c +++ b/test/validation/api/ipsec/ipsec_test_in.c @@ -1136,6 +1136,37 @@ static void test_in_ipv4_mcgrew_gcm_15_esp(void) ipsec_sa_destroy(sa); }
+static void test_in_ipv4_rfc7634_chacha(void) +{ + odp_ipsec_tunnel_param_t tunnel = {}; + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + + ipsec_sa_param_fill(¶m, + true, false, 0x01020304, &tunnel, + ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634, + ODP_AUTH_ALG_CHACHA20_POLY1305, NULL, + &key_rfc7634_salt); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_test_part test = { + .pkt_in = &pkt_ipv4_rfc7634_esp, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_ipv4_rfc7634}, + }, + }; + + ipsec_check_in_one(&test, sa); + + ipsec_sa_destroy(sa); +} + static void test_in_ipv4_ah_aes_gmac_128(void) { odp_ipsec_sa_param_t param; @@ -1474,6 +1505,8 @@ odp_testinfo_t ipsec_in_suite[] = { #endif ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_mcgrew_gcm_15_esp, ipsec_check_esp_null_aes_gmac_128), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_rfc7634_chacha, + ipsec_check_esp_chacha20_poly1305), ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_ah_sha256, ipsec_check_ah_sha256), ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_ah_sha256_tun_ipv4, diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 971fbbf8..0f49c7e1 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -500,6 +500,48 @@ static void test_out_ipv4_esp_null_aes_gmac_128(void) ipsec_sa_destroy(sa); }
+static void test_out_ipv4_esp_chacha20_poly1305(void) +{ + odp_ipsec_sa_param_t param; + odp_ipsec_sa_t sa; + odp_ipsec_sa_t sa2; + + ipsec_sa_param_fill(¶m, + false, false, 123, NULL, + ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634, + ODP_AUTH_ALG_CHACHA20_POLY1305, NULL, + &key_rfc7634_salt); + + sa = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); + + ipsec_sa_param_fill(¶m, + true, false, 123, NULL, + ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634, + ODP_AUTH_ALG_CHACHA20_POLY1305, NULL, + &key_rfc7634_salt); + + sa2 = odp_ipsec_sa_create(¶m); + + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); + + ipsec_test_part test = { + .pkt_in = &pkt_ipv4_icmp_0, + .out_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .pkt_out = &pkt_ipv4_icmp_0 }, + }, + }; + + ipsec_check_out_in_one(&test, sa, sa2); + + ipsec_sa_destroy(sa2); + ipsec_sa_destroy(sa); +} + static void test_out_ipv4_ah_sha256_frag_check(void) { odp_ipsec_sa_param_t param; @@ -978,6 +1020,8 @@ odp_testinfo_t ipsec_out_suite[] = { ipsec_check_ah_aes_gmac_128), ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_null_aes_gmac_128, ipsec_check_esp_null_aes_gmac_128), + ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_chacha20_poly1305, + ipsec_check_esp_chacha20_poly1305), ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_sha256_frag_check, ipsec_check_ah_sha256), ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_sha256_frag_check_2, diff --git a/test/validation/api/ipsec/test_vectors.h b/test/validation/api/ipsec/test_vectors.h index 4732d6ca..f14fdb2b 100644 --- a/test/validation/api/ipsec/test_vectors.h +++ b/test/validation/api/ipsec/test_vectors.h @@ -48,6 +48,11 @@ KEY(key_mcgrew_gcm_salt_12, 0xd9, 0x66, 0x42, 0x67); KEY(key_mcgrew_gcm_15, 0x4c, 0x80, 0xcd, 0xef, 0xbb, 0x5d, 0x10, 0xda, 0x90, 0x6a, 0xc7, 0x3c, 0x36, 0x13, 0xa6, 0x34); KEY(key_mcgrew_gcm_salt_15, 0x22, 0x43, 0x3c, 0x64); +KEY(key_rfc7634, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f); +KEY(key_rfc7634_salt, 0xa0, 0xa1, 0xa2, 0xa3);
static const ODP_UNUSED ipsec_test_packet pkt_ipv4_icmp_0 = { .len = 142, @@ -1730,6 +1735,67 @@ static const ipsec_test_packet pkt_mcgrew_gcm_test_15_esp = { }, };
+static const ODP_UNUSED ipsec_test_packet pkt_ipv4_rfc7634 = { + .len = 98, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x54, 0xa6, 0xf2, 0x00, 0x00, + 0x40, 0x01, 0xe7, 0x78, 0xc6, 0x33, 0x64, 0x05, + 0xc0, 0x00, 0x02, 0x05, + + /* ICMP */ + 0x08, 0x00, 0x5b, 0x7a, 0x3a, 0x08, 0x00, 0x00, + 0x55, 0x3b, 0xec, 0x10, 0x00, 0x07, 0x36, 0x27, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }, +}; + +static const ODP_UNUSED ipsec_test_packet pkt_ipv4_rfc7634_esp = { + .len = 154, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH - not a part of RFC, added for simplicity */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x8c, 0x23, 0x45, 0x00, 0x00, + 0x40, 0x32, 0xde, 0x5b, 0xcb, 0x00, 0x71, 0x99, + 0xcb, 0x00, 0x71, 0x05, + + /* ESP */ + 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x24, 0x03, 0x94, 0x28, 0xb9, 0x7f, 0x41, 0x7e, + 0x3c, 0x13, 0x75, 0x3a, 0x4f, 0x05, 0x08, 0x7b, + 0x67, 0xc3, 0x52, 0xe6, 0xa7, 0xfa, 0xb1, 0xb9, + 0x82, 0xd4, 0x66, 0xef, 0x40, 0x7a, 0xe5, 0xc6, + 0x14, 0xee, 0x80, 0x99, 0xd5, 0x28, 0x44, 0xeb, + 0x61, 0xaa, 0x95, 0xdf, 0xab, 0x4c, 0x02, 0xf7, + 0x2a, 0xa7, 0x1e, 0x7c, 0x4c, 0x4f, 0x64, 0xc9, + 0xbe, 0xfe, 0x2f, 0xac, 0xc6, 0x38, 0xe8, 0xf3, + 0xcb, 0xec, 0x16, 0x3f, 0xac, 0x46, 0x9b, 0x50, + 0x27, 0x73, 0xf6, 0xfb, 0x94, 0xe6, 0x64, 0xda, + 0x91, 0x65, 0xb8, 0x28, 0x29, 0xf6, 0x41, 0xe0, + 0x76, 0xaa, 0xa8, 0x26, 0x6b, 0x7f, 0xb0, 0xf7, + 0xb1, 0x1b, 0x36, 0x99, 0x07, 0xe1, 0xad, 0x43, + }, +}; + static const ODP_UNUSED ipsec_test_packet pkt_ipv6_icmp_0_esp_udp_null_sha256_1 = { .len = 206,
commit 89c4f15c0c7d63a10161c716367bcb392c23c20b Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 04:50:06 2018 +0300
linux-gen: crypto: implement AES-CMAC
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index faa415cd..5579ade5 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -25,6 +25,7 @@
#include <openssl/rand.h> #include <openssl/hmac.h> +#include <openssl/cmac.h> #include <openssl/evp.h>
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(OPENSSL_NO_POLY1305) @@ -108,6 +109,14 @@ static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = { {.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0}, .iv_len = 12 } };
+static const odp_crypto_auth_capability_t auth_capa_aes_cmac[] = { +{.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 12, .key_len = 24, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 16, .key_len = 24, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 12, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; + #if _ODP_HAVE_CHACHA20_POLY1305 static const odp_crypto_auth_capability_t auth_capa_chacha20_poly1305[] = { {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } }; @@ -177,6 +186,7 @@ static odp_crypto_global_t *global;
typedef struct crypto_local_t { HMAC_CTX *hmac_ctx[MAX_SESSIONS]; + CMAC_CTX *cmac_ctx[MAX_SESSIONS]; EVP_CIPHER_CTX *cipher_ctx[MAX_SESSIONS]; EVP_CIPHER_CTX *mac_cipher_ctx[MAX_SESSIONS]; uint8_t *ctx_valid; @@ -344,6 +354,93 @@ odp_crypto_alg_err_t auth_hmac_check(odp_packet_t pkt, return ODP_CRYPTO_ALG_ERR_NONE; }
+static void +auth_cmac_init(odp_crypto_generic_session_t *session) +{ + CMAC_CTX *ctx = local.cmac_ctx[session->idx]; + + CMAC_Init(ctx, + session->auth.key, + session->p.auth_key.length, + session->auth.evp_cipher, + NULL); +} + +static +void packet_cmac(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session, + uint8_t *hash) +{ + CMAC_CTX *ctx = local.cmac_ctx[session->idx]; + uint32_t offset = param->auth_range.offset; + uint32_t len = param->auth_range.length; + size_t outlen; + + ODP_ASSERT(offset + len <= odp_packet_len(pkt)); + + /* Reinitialize CMAC calculation without resetting the key */ + CMAC_Init(ctx, NULL, 0, NULL, NULL); + + while (len > 0) { + uint32_t seglen = 0; /* GCC */ + void *mapaddr = odp_packet_offset(pkt, offset, &seglen, NULL); + uint32_t maclen = len > seglen ? seglen : len; + + CMAC_Update(ctx, mapaddr, maclen); + offset += maclen; + len -= maclen; + } + + CMAC_Final(ctx, hash, &outlen); +} + +static +odp_crypto_alg_err_t auth_cmac_gen(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) +{ + uint8_t hash[EVP_MAX_MD_SIZE]; + + /* Hash it */ + packet_cmac(pkt, param, session, hash); + + /* Copy to the output location */ + odp_packet_copy_from_mem(pkt, + param->hash_result_offset, + session->p.auth_digest_len, + hash); + + return ODP_CRYPTO_ALG_ERR_NONE; +} + +static +odp_crypto_alg_err_t auth_cmac_check(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) +{ + uint32_t bytes = session->p.auth_digest_len; + uint8_t hash_in[EVP_MAX_MD_SIZE]; + uint8_t hash_out[EVP_MAX_MD_SIZE]; + + /* Copy current value out and clear it before authentication */ + odp_packet_copy_to_mem(pkt, param->hash_result_offset, + bytes, hash_in); + + _odp_packet_set_data(pkt, param->hash_result_offset, + 0, bytes); + + /* Hash it */ + packet_cmac(pkt, param, session, hash_out); + + /* Verify match */ + if (0 != memcmp(hash_in, hash_out, bytes)) + return ODP_CRYPTO_ALG_ERR_ICV_CHECK; + + /* Matched */ + return ODP_CRYPTO_ALG_ERR_NONE; +} + static int internal_aad(EVP_CIPHER_CTX *ctx, odp_packet_t pkt, @@ -1001,6 +1098,35 @@ static int process_auth_hmac_param(odp_crypto_generic_session_t *session, return 0; }
+static int process_auth_cmac_param(odp_crypto_generic_session_t *session, + const EVP_CIPHER *cipher) +{ + /* Verify Key len is valid */ + if ((uint32_t)EVP_CIPHER_key_length(cipher) != + session->p.auth_key.length) + return -1; + + /* Set function */ + if (ODP_CRYPTO_OP_ENCODE == session->p.op) + session->auth.func = auth_cmac_gen; + else + session->auth.func = auth_cmac_check; + session->auth.init = auth_cmac_init; + + session->auth.evp_cipher = cipher; + + /* Number of valid bytes */ + if (session->p.auth_digest_len < + (unsigned)EVP_CIPHER_block_size(cipher) / 2) + return -1; + + /* Convert keys */ + memcpy(session->auth.key, session->p.auth_key.data, + session->p.auth_key.length); + + return 0; +} + int odp_crypto_capability(odp_crypto_capability_t *capa) { if (NULL == capa) @@ -1030,6 +1156,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.aes_gcm = 1; capa->auths.bit.aes_ccm = 1; capa->auths.bit.aes_gmac = 1; + capa->auths.bit.aes_cmac = 1; #if _ODP_HAVE_CHACHA20_POLY1305 capa->auths.bit.chacha20_poly1305 = 1; #endif @@ -1138,6 +1265,10 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, src = auth_capa_aes_ccm; num = sizeof(auth_capa_aes_ccm) / size; break; + case ODP_AUTH_ALG_AES_CMAC: + src = auth_capa_aes_cmac; + num = sizeof(auth_capa_aes_cmac) / size; + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_AUTH_ALG_CHACHA20_POLY1305: src = auth_capa_chacha20_poly1305; @@ -1374,6 +1505,19 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, rc = -1; } break; + case ODP_AUTH_ALG_AES_CMAC: + if (param->auth_key.length == 16) + rc = process_auth_cmac_param(session, + EVP_aes_128_cbc()); + else if (param->auth_key.length == 24) + rc = process_auth_cmac_param(session, + EVP_aes_192_cbc()); + else if (param->auth_key.length == 32) + rc = process_auth_cmac_param(session, + EVP_aes_256_cbc()); + else + rc = -1; + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_AUTH_ALG_CHACHA20_POLY1305: /* ChaCha20_Poly1305 requires to do both auth and @@ -1561,6 +1705,7 @@ int _odp_crypto_init_local(void)
for (i = 0; i < MAX_SESSIONS; i++) { local.hmac_ctx[i] = HMAC_CTX_new(); + local.cmac_ctx[i] = CMAC_CTX_new(); local.cipher_ctx[i] = EVP_CIPHER_CTX_new(); local.mac_cipher_ctx[i] = EVP_CIPHER_CTX_new();
@@ -1584,6 +1729,8 @@ int _odp_crypto_term_local(void) unsigned i;
for (i = 0; i < MAX_SESSIONS; i++) { + if (local.cmac_ctx[i] != NULL) + CMAC_CTX_free(local.cmac_ctx[i]); if (local.hmac_ctx[i] != NULL) HMAC_CTX_free(local.hmac_ctx[i]); if (local.cipher_ctx[i] != NULL)
commit e3e2773d6bf9b25f10b487c048cf61a0a0f1e887 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 04:07:42 2018 +0300
linux-gen: crypto: rename auth functions
Point that current authentication functions use HMAC by including hmac in their names.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index e9d43619..faa415cd 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -149,8 +149,6 @@ struct odp_crypto_generic_session_t { struct { uint8_t key[EVP_MAX_KEY_LENGTH]; uint8_t iv_data[EVP_MAX_IV_LENGTH]; - uint32_t key_length; - uint32_t bytes; union { const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher; @@ -260,13 +258,13 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) #endif
static void -auth_init(odp_crypto_generic_session_t *session) +auth_hmac_init(odp_crypto_generic_session_t *session) { HMAC_CTX *ctx = local.hmac_ctx[session->idx];
HMAC_Init_ex(ctx, session->auth.key, - session->auth.key_length, + session->p.auth_key.length, session->auth.evp_md, NULL); } @@ -301,9 +299,9 @@ void packet_hmac(odp_packet_t pkt, }
static -odp_crypto_alg_err_t auth_gen(odp_packet_t pkt, - const odp_crypto_packet_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t auth_hmac_gen(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) { uint8_t hash[EVP_MAX_MD_SIZE];
@@ -320,9 +318,9 @@ odp_crypto_alg_err_t auth_gen(odp_packet_t pkt, }
static -odp_crypto_alg_err_t auth_check(odp_packet_t pkt, - const odp_crypto_packet_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t auth_hmac_check(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) { uint32_t bytes = session->p.auth_digest_len; uint8_t hash_in[EVP_MAX_MD_SIZE]; @@ -824,12 +822,24 @@ static int process_aes_gmac_param(odp_crypto_generic_session_t *session, return 0; }
+static void +aes_ccm_encrypt_init(odp_crypto_generic_session_t *session) +{ + EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx]; + + EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + NULL, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, + session->p.cipher_iv.length, NULL); + EVP_CIPHER_CTX_set_padding(ctx, 0); +} + static odp_crypto_alg_err_t aes_ccm_encrypt(odp_packet_t pkt, const odp_crypto_packet_op_param_t *param, odp_crypto_generic_session_t *session) { - EVP_CIPHER_CTX *ctx; + EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx]; const uint8_t *aad_head = param->aad_ptr; uint32_t aad_len = session->p.auth_aad_len; void *iv_ptr; @@ -847,16 +857,9 @@ odp_crypto_alg_err_t aes_ccm_encrypt(odp_packet_t pkt, else return ODP_CRYPTO_ALG_ERR_IV_INVALID;
- /* Encrypt it */ - ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, - NULL, NULL); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, - session->p.cipher_iv.length, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, session->p.auth_digest_len, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, session->cipher.key_data, iv_ptr); - EVP_CIPHER_CTX_set_padding(ctx, 0);
/* Set len */ EVP_EncryptUpdate(ctx, NULL, &dummy_len, NULL, in_len); @@ -882,18 +885,28 @@ odp_crypto_alg_err_t aes_ccm_encrypt(odp_packet_t pkt, odp_packet_copy_from_mem(pkt, param->hash_result_offset, session->p.auth_digest_len, block);
- EVP_CIPHER_CTX_free(ctx); - return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE : ODP_CRYPTO_ALG_ERR_NONE; }
+static void +aes_ccm_decrypt_init(odp_crypto_generic_session_t *session) +{ + EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx]; + + EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + session->cipher.key_data, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, + session->p.cipher_iv.length, NULL); + EVP_CIPHER_CTX_set_padding(ctx, 0); +} + static odp_crypto_alg_err_t aes_ccm_decrypt(odp_packet_t pkt, const odp_crypto_packet_op_param_t *param, odp_crypto_generic_session_t *session) { - EVP_CIPHER_CTX *ctx; + EVP_CIPHER_CTX *ctx = local.cipher_ctx[session->idx]; const uint8_t *aad_head = param->aad_ptr; uint32_t aad_len = session->p.auth_aad_len; void *iv_ptr; @@ -911,18 +924,11 @@ odp_crypto_alg_err_t aes_ccm_decrypt(odp_packet_t pkt, else return ODP_CRYPTO_ALG_ERR_IV_INVALID;
- /* Decrypt it */ - ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, - NULL, NULL); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, - session->p.cipher_iv.length, NULL); odp_packet_copy_to_mem(pkt, param->hash_result_offset, session->p.auth_digest_len, block); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, session->p.auth_digest_len, block); EVP_DecryptInit_ex(ctx, NULL, NULL, session->cipher.key_data, iv_ptr); - EVP_CIPHER_CTX_set_padding(ctx, 0);
/* Set len */ EVP_DecryptUpdate(ctx, NULL, &dummy_len, NULL, in_len); @@ -943,8 +949,6 @@ odp_crypto_alg_err_t aes_ccm_decrypt(odp_packet_t pkt, odp_packet_copy_from_mem(pkt, param->cipher_range.offset, in_len, data);
- EVP_CIPHER_CTX_free(ctx); - return ret <= 0 ? ODP_CRYPTO_ALG_ERR_ICV_CHECK : ODP_CRYPTO_ALG_ERR_NONE; } @@ -963,24 +967,26 @@ static int process_aes_ccm_param(odp_crypto_generic_session_t *session, session->cipher.evp_cipher = cipher;
/* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) + if (ODP_CRYPTO_OP_ENCODE == session->p.op) { session->cipher.func = aes_ccm_encrypt; - else + session->cipher.init = aes_ccm_encrypt_init; + } else { session->cipher.func = aes_ccm_decrypt; + session->cipher.init = aes_ccm_decrypt_init; + }
return 0; }
-static int process_auth_param(odp_crypto_generic_session_t *session, - uint32_t key_length, - const EVP_MD *evp_md) +static int process_auth_hmac_param(odp_crypto_generic_session_t *session, + const EVP_MD *evp_md) { /* Set function */ if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->auth.func = auth_gen; + session->auth.func = auth_hmac_gen; else - session->auth.func = auth_check; - session->auth.init = auth_init; + session->auth.func = auth_hmac_check; + session->auth.init = auth_hmac_init;
session->auth.evp_md = evp_md;
@@ -989,9 +995,8 @@ static int process_auth_param(odp_crypto_generic_session_t *session, return -1;
/* Convert keys */ - session->auth.key_length = key_length; memcpy(session->auth.key, session->p.auth_key.data, - session->auth.key_length); + session->p.auth_key.length);
return 0; } @@ -1312,10 +1317,10 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, #endif /* Fallthrough */ case ODP_AUTH_ALG_MD5_HMAC: - rc = process_auth_param(session, 16, EVP_md5()); + rc = process_auth_hmac_param(session, EVP_md5()); break; case ODP_AUTH_ALG_SHA1_HMAC: - rc = process_auth_param(session, 20, EVP_sha1()); + rc = process_auth_hmac_param(session, EVP_sha1()); break; #if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: @@ -1324,10 +1329,10 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, #endif /* Fallthrough */ case ODP_AUTH_ALG_SHA256_HMAC: - rc = process_auth_param(session, 32, EVP_sha256()); + rc = process_auth_hmac_param(session, EVP_sha256()); break; case ODP_AUTH_ALG_SHA512_HMAC: - rc = process_auth_param(session, 64, EVP_sha512()); + rc = process_auth_hmac_param(session, EVP_sha512()); break; #if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: @@ -1363,6 +1368,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, * cipher at the same time */ if (param->cipher_alg == ODP_CIPHER_ALG_AES_CCM) { session->auth.func = null_crypto_routine; + session->auth.init = null_crypto_init_routine; rc = 0; } else { rc = -1;
commit a6e2ebeb671ea322cea1af81a35b1c564f06f33f Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 03:47:34 2018 +0300
linux-gen: crypto: provide AES-CCM implementation
AES-CCM support in OpenSSL is quite unique: it requires whole data to be passed in single EVP_EncryptUpdate/EVP_DecryptUpdate call. Supporting this requires copying data back-and-forth between packet and temporary buffer.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 66dc8f23..e9d43619 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -61,6 +61,14 @@ static const odp_crypto_cipher_capability_t cipher_capa_aes_gcm[] = { {.key_len = 24, .iv_len = 12}, {.key_len = 32, .iv_len = 12} };
+static const odp_crypto_cipher_capability_t cipher_capa_aes_ccm[] = { +{.key_len = 16, .iv_len = 11}, +{.key_len = 16, .iv_len = 13}, +{.key_len = 24, .iv_len = 11}, +{.key_len = 24, .iv_len = 13}, +{.key_len = 32, .iv_len = 11}, +{.key_len = 32, .iv_len = 13} }; + #if _ODP_HAVE_CHACHA20_POLY1305 static const odp_crypto_cipher_capability_t cipher_capa_chacha20_poly1305[] = { {.key_len = 32, .iv_len = 12} }; @@ -93,6 +101,9 @@ static const odp_crypto_auth_capability_t auth_capa_sha512_hmac[] = { static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = { {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } };
+static const odp_crypto_auth_capability_t auth_capa_aes_ccm[] = { +{.digest_len = 8, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } }; + static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = { {.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0}, .iv_len = 12 } }; @@ -813,6 +824,153 @@ static int process_aes_gmac_param(odp_crypto_generic_session_t *session, return 0; }
+static +odp_crypto_alg_err_t aes_ccm_encrypt(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) +{ + EVP_CIPHER_CTX *ctx; + const uint8_t *aad_head = param->aad_ptr; + uint32_t aad_len = session->p.auth_aad_len; + void *iv_ptr; + int dummy_len = 0; + int cipher_len; + uint32_t in_len = param->cipher_range.length; + uint8_t data[in_len]; + uint8_t block[EVP_MAX_MD_SIZE]; + int ret; + + if (param->cipher_iv_ptr) + iv_ptr = param->cipher_iv_ptr; + else if (session->p.cipher_iv.data) + iv_ptr = session->cipher.iv_data; + else + return ODP_CRYPTO_ALG_ERR_IV_INVALID; + + /* Encrypt it */ + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + NULL, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, + session->p.cipher_iv.length, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, + session->p.auth_digest_len, NULL); + EVP_EncryptInit_ex(ctx, NULL, NULL, session->cipher.key_data, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + /* Set len */ + EVP_EncryptUpdate(ctx, NULL, &dummy_len, NULL, in_len); + + /* Authenticate header data (if any) without encrypting them */ + if (aad_len > 0) + EVP_EncryptUpdate(ctx, NULL, &dummy_len, + aad_head, aad_len); + + odp_packet_copy_to_mem(pkt, param->cipher_range.offset, in_len, + data); + + EVP_EncryptUpdate(ctx, data, &cipher_len, data, in_len); + + ret = EVP_EncryptFinal_ex(ctx, data + cipher_len, &dummy_len); + cipher_len += dummy_len; + + odp_packet_copy_from_mem(pkt, param->cipher_range.offset, in_len, + data); + + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, + session->p.auth_digest_len, block); + odp_packet_copy_from_mem(pkt, param->hash_result_offset, + session->p.auth_digest_len, block); + + EVP_CIPHER_CTX_free(ctx); + + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE : + ODP_CRYPTO_ALG_ERR_NONE; +} + +static +odp_crypto_alg_err_t aes_ccm_decrypt(odp_packet_t pkt, + const odp_crypto_packet_op_param_t *param, + odp_crypto_generic_session_t *session) +{ + EVP_CIPHER_CTX *ctx; + const uint8_t *aad_head = param->aad_ptr; + uint32_t aad_len = session->p.auth_aad_len; + void *iv_ptr; + int dummy_len = 0; + int cipher_len; + uint32_t in_len = param->cipher_range.length; + uint8_t data[in_len]; + uint8_t block[EVP_MAX_MD_SIZE]; + int ret; + + if (param->cipher_iv_ptr) + iv_ptr = param->cipher_iv_ptr; + else if (session->p.cipher_iv.data) + iv_ptr = session->cipher.iv_data; + else + return ODP_CRYPTO_ALG_ERR_IV_INVALID; + + /* Decrypt it */ + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + NULL, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, + session->p.cipher_iv.length, NULL); + odp_packet_copy_to_mem(pkt, param->hash_result_offset, + session->p.auth_digest_len, block); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, + session->p.auth_digest_len, block); + EVP_DecryptInit_ex(ctx, NULL, NULL, session->cipher.key_data, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + /* Set len */ + EVP_DecryptUpdate(ctx, NULL, &dummy_len, NULL, in_len); + + /* Authenticate header data (if any) without encrypting them */ + if (aad_len > 0) + EVP_DecryptUpdate(ctx, NULL, &dummy_len, + aad_head, aad_len); + + odp_packet_copy_to_mem(pkt, param->cipher_range.offset, in_len, + data); + + ret = EVP_DecryptUpdate(ctx, data, &cipher_len, data, in_len); + + EVP_DecryptFinal_ex(ctx, data + cipher_len, &dummy_len); + cipher_len += dummy_len; + + odp_packet_copy_from_mem(pkt, param->cipher_range.offset, in_len, + data); + + EVP_CIPHER_CTX_free(ctx); + + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_ICV_CHECK : + ODP_CRYPTO_ALG_ERR_NONE; +} + +static int process_aes_ccm_param(odp_crypto_generic_session_t *session, + const EVP_CIPHER *cipher) +{ + /* Verify Key len is valid */ + if ((uint32_t)EVP_CIPHER_key_length(cipher) != + session->p.cipher_key.length) + return -1; + + memcpy(session->cipher.key_data, session->p.cipher_key.data, + session->p.cipher_key.length); + + session->cipher.evp_cipher = cipher; + + /* Set function */ + if (ODP_CRYPTO_OP_ENCODE == session->p.op) + session->cipher.func = aes_ccm_encrypt; + else + session->cipher.func = aes_ccm_decrypt; + + return 0; +} + static int process_auth_param(odp_crypto_generic_session_t *session, uint32_t key_length, const EVP_MD *evp_md) @@ -854,6 +1012,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->ciphers.bit.aes_cbc = 1; capa->ciphers.bit.aes_ctr = 1; capa->ciphers.bit.aes_gcm = 1; + capa->ciphers.bit.aes_ccm = 1; #if _ODP_HAVE_CHACHA20_POLY1305 capa->ciphers.bit.chacha20_poly1305 = 1; #endif @@ -864,6 +1023,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.sha256_hmac = 1; capa->auths.bit.sha512_hmac = 1; capa->auths.bit.aes_gcm = 1; + capa->auths.bit.aes_ccm = 1; capa->auths.bit.aes_gmac = 1; #if _ODP_HAVE_CHACHA20_POLY1305 capa->auths.bit.chacha20_poly1305 = 1; @@ -911,6 +1071,10 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, src = cipher_capa_aes_gcm; num = sizeof(cipher_capa_aes_gcm) / size; break; + case ODP_CIPHER_ALG_AES_CCM: + src = cipher_capa_aes_ccm; + num = sizeof(cipher_capa_aes_ccm) / size; + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_CIPHER_ALG_CHACHA20_POLY1305: src = cipher_capa_chacha20_poly1305; @@ -965,6 +1129,10 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, src = auth_capa_aes_gmac; num = sizeof(auth_capa_aes_gmac) / size; break; + case ODP_AUTH_ALG_AES_CCM: + src = auth_capa_aes_ccm; + num = sizeof(auth_capa_aes_ccm) / size; + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_AUTH_ALG_CHACHA20_POLY1305: src = auth_capa_chacha20_poly1305; @@ -1093,6 +1261,20 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, else rc = -1; break; + case ODP_CIPHER_ALG_AES_CCM: + /* AES-CCM requires to do both auth and + * cipher at the same time */ + if (param->auth_alg != ODP_AUTH_ALG_AES_CCM) + rc = -1; + else if (param->cipher_key.length == 16) + rc = process_aes_ccm_param(session, EVP_aes_128_ccm()); + else if (param->cipher_key.length == 24) + rc = process_aes_ccm_param(session, EVP_aes_192_ccm()); + else if (param->cipher_key.length == 32) + rc = process_aes_ccm_param(session, EVP_aes_256_ccm()); + else + rc = -1; + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_CIPHER_ALG_CHACHA20_POLY1305: /* ChaCha20_Poly1305 requires to do both auth and @@ -1176,6 +1358,16 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, else rc = -1; break; + case ODP_AUTH_ALG_AES_CCM: + /* AES-CCM requires to do both auth and + * cipher at the same time */ + if (param->cipher_alg == ODP_CIPHER_ALG_AES_CCM) { + session->auth.func = null_crypto_routine; + rc = 0; + } else { + rc = -1; + } + break; #if _ODP_HAVE_CHACHA20_POLY1305 case ODP_AUTH_ALG_CHACHA20_POLY1305: /* ChaCha20_Poly1305 requires to do both auth and
commit e89a66c12db16f6ff4619683f58cd1a63f16eb10 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 08:03:56 2018 +0300
linux-gen: crypto: support ChaCha20-Poly1305
OpenSSL >= 1.1.0 supports ChaCha20-Poly1305 AEAD cipher, so let's support it in linux-generic.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 00db3f9f..66dc8f23 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -27,6 +27,12 @@ #include <openssl/hmac.h> #include <openssl/evp.h>
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(OPENSSL_NO_POLY1305) +#define _ODP_HAVE_CHACHA20_POLY1305 1 +#else +#define _ODP_HAVE_CHACHA20_POLY1305 0 +#endif + #define MAX_SESSIONS 32
/* @@ -55,6 +61,11 @@ static const odp_crypto_cipher_capability_t cipher_capa_aes_gcm[] = { {.key_len = 24, .iv_len = 12}, {.key_len = 32, .iv_len = 12} };
+#if _ODP_HAVE_CHACHA20_POLY1305 +static const odp_crypto_cipher_capability_t cipher_capa_chacha20_poly1305[] = { +{.key_len = 32, .iv_len = 12} }; +#endif + /* * Authentication algorithm capabilities * @@ -86,6 +97,11 @@ static const odp_crypto_auth_capability_t auth_capa_aes_gmac[] = { {.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0}, .iv_len = 12 } };
+#if _ODP_HAVE_CHACHA20_POLY1305 +static const odp_crypto_auth_capability_t auth_capa_chacha20_poly1305[] = { +{.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } }; +#endif + /** Forward declaration of session structure */ typedef struct odp_crypto_generic_session_t odp_crypto_generic_session_t;
@@ -838,6 +854,9 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->ciphers.bit.aes_cbc = 1; capa->ciphers.bit.aes_ctr = 1; capa->ciphers.bit.aes_gcm = 1; +#if _ODP_HAVE_CHACHA20_POLY1305 + capa->ciphers.bit.chacha20_poly1305 = 1; +#endif
capa->auths.bit.null = 1; capa->auths.bit.md5_hmac = 1; @@ -846,6 +865,9 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.sha512_hmac = 1; capa->auths.bit.aes_gcm = 1; capa->auths.bit.aes_gmac = 1; +#if _ODP_HAVE_CHACHA20_POLY1305 + capa->auths.bit.chacha20_poly1305 = 1; +#endif
#if ODP_DEPRECATED_API capa->ciphers.bit.aes128_cbc = 1; @@ -889,6 +911,12 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, src = cipher_capa_aes_gcm; num = sizeof(cipher_capa_aes_gcm) / size; break; +#if _ODP_HAVE_CHACHA20_POLY1305 + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + src = cipher_capa_chacha20_poly1305; + num = sizeof(cipher_capa_chacha20_poly1305) / size; + break; +#endif default: return -1; } @@ -937,6 +965,12 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, src = auth_capa_aes_gmac; num = sizeof(auth_capa_aes_gmac) / size; break; +#if _ODP_HAVE_CHACHA20_POLY1305 + case ODP_AUTH_ALG_CHACHA20_POLY1305: + src = auth_capa_chacha20_poly1305; + num = sizeof(auth_capa_chacha20_poly1305) / size; + break; +#endif default: return -1; } @@ -1059,6 +1093,17 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, else rc = -1; break; +#if _ODP_HAVE_CHACHA20_POLY1305 + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + /* ChaCha20_Poly1305 requires to do both auth and + * cipher at the same time */ + if (param->auth_alg != ODP_AUTH_ALG_CHACHA20_POLY1305) + rc = -1; + else + rc = process_aes_gcm_param(session, + EVP_chacha20_poly1305()); + break; +#endif default: rc = -1; } @@ -1131,6 +1176,19 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, else rc = -1; break; +#if _ODP_HAVE_CHACHA20_POLY1305 + case ODP_AUTH_ALG_CHACHA20_POLY1305: + /* ChaCha20_Poly1305 requires to do both auth and + * cipher at the same time */ + if (param->cipher_alg == ODP_CIPHER_ALG_CHACHA20_POLY1305) { + session->auth.func = null_crypto_routine; + session->auth.init = null_crypto_init_routine; + rc = 0; + } else { + rc = -1; + } + break; +#endif default: rc = -1; }
commit ae8385cb0a0f5a222684775eea0efc5bb034252f Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Tue Jan 30 07:13:49 2018 +0300
linux-gen: crypto: drop stale enum
Drop crypto_kind_t, unused now.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 93736a2c..00db3f9f 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -159,8 +159,6 @@ typedef struct crypto_local_t {
static __thread crypto_local_t local;
-typedef enum { KIND_HMAC, KIND_CIPHER, KIND_MAC_CIPHER } crypto_kind_t; - static inline void crypto_init(odp_crypto_generic_session_t *session) { if (local.ctx_valid[session->idx])
commit 22a158d4082d8d810443dd7a4191522c6f95b742 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 04:49:51 2018 +0300
validation: crypto: add AES-CMAC test vectors
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index ae843acf..f310329a 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -54,6 +54,8 @@ static const char *auth_alg_name(odp_auth_alg_t auth) return "ODP_AUTH_ALG_AES_GMAC"; case ODP_AUTH_ALG_AES_CCM: return "ODP_AUTH_ALG_AES_CCM"; + case ODP_AUTH_ALG_AES_CMAC: + return "ODP_AUTH_ALG_AES_CMAC"; case ODP_AUTH_ALG_CHACHA20_POLY1305: return "ODP_AUTH_ALG_CHACHA20_POLY1305"; default: @@ -503,6 +505,9 @@ static void check_alg(odp_crypto_op_t op, if (auth_alg == ODP_AUTH_ALG_AES_GMAC && !(capa.auths.bit.aes_gmac)) rc = -1; + if (auth_alg == ODP_AUTH_ALG_AES_CMAC && + !(capa.auths.bit.aes_cmac)) + rc = -1; if (auth_alg == ODP_AUTH_ALG_AES_CCM && !(capa.auths.bit.aes_ccm)) rc = -1; @@ -721,6 +726,10 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.auths.bit.aes_ccm) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_AES_CMAC: + if (!capability.auths.bit.aes_cmac) + return ODP_TEST_INACTIVE; + break; case ODP_AUTH_ALG_CHACHA20_POLY1305: if (!capability.auths.bit.chacha20_poly1305) return ODP_TEST_INACTIVE; @@ -1285,6 +1294,36 @@ static void crypto_test_check_alg_aes_gmac_ovr_iv(void) true); }
+static int check_alg_aes_cmac(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_AES_CMAC); +} + +static void crypto_test_gen_alg_aes_cmac(void) +{ + unsigned int test_vec_num = (sizeof(aes_cmac_reference) / + sizeof(aes_cmac_reference[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_CMAC, + aes_cmac_reference, + ARRAY_SIZE(aes_cmac_reference), + false); +} + +static void crypto_test_check_alg_aes_cmac(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_CMAC, + aes_cmac_reference, + ARRAY_SIZE(aes_cmac_reference), + false); +} + int crypto_suite_sync_init(void) { suite_context.pool = odp_pool_lookup("packet_pool"); @@ -1414,6 +1453,10 @@ odp_testinfo_t crypto_suite[] = { check_alg_aes_gmac), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac_ovr_iv, check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_cmac, + check_alg_aes_cmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_cmac, + check_alg_aes_cmac), ODP_TEST_INFO_NULL, };
diff --git a/test/validation/api/crypto/test_vectors.h b/test/validation/api/crypto/test_vectors.h index 15cd91d2..23ed9525 100644 --- a/test/validation/api/crypto/test_vectors.h +++ b/test/validation/api/crypto/test_vectors.h @@ -605,6 +605,103 @@ static crypto_test_reference_t aes_gmac_reference[] = { }, };
+/* + * Test vectors from SP800-38B / CSRC examples + * 12-byte vectors are just truncated 16-byte vectors + */ +static crypto_test_reference_t aes_cmac_reference[] = { + { + .auth_key_length = AES128_KEY_LEN, + .auth_key = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 16, + .digest = { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }, + }, + { + .auth_key_length = AES192_KEY_LEN, + .auth_key = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 16, + .digest = { 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, + 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 }, + }, + { + .auth_key_length = AES256_KEY_LEN, + .auth_key = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 16, + .digest = { 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, + 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c }, + }, + { + .auth_key_length = AES128_KEY_LEN, + .auth_key = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 12, + .digest = { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d }, + }, + { + .auth_key_length = AES192_KEY_LEN, + .auth_key = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 12, + .digest = { 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, + 0x06, 0x62, 0xf6, 0x5e }, + }, + { + .auth_key_length = AES256_KEY_LEN, + .auth_key = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 }, + .length = 16, + .plaintext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}, + .ciphertext = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a + }, + .digest_length = 12, + .digest = { 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, + 0xbd, 0x4b, 0xf2, 0x8d }, + } +}; + /* * Test vector from RFC 7539, sections 2.8.2, A.5 */
commit 18d1eb9e00ef871c0da9e60989d83455b7fda4c2 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 03:45:33 2018 +0300
validation: crypto: add test vectors for AES-CCM
Neither RFC 3610 nor SP 800-38C contains test vectors for 192 and 256 bit keys and none contains test vectors for 11-bit IV (used in IPsec). So I've used 1st test vector from RFC 3610 and generated the rest of test vectors.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index 5c38ae85..ae843acf 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -52,6 +52,8 @@ static const char *auth_alg_name(odp_auth_alg_t auth) return "ODP_AUTH_ALG_AES_GCM"; case ODP_AUTH_ALG_AES_GMAC: return "ODP_AUTH_ALG_AES_GMAC"; + case ODP_AUTH_ALG_AES_CCM: + return "ODP_AUTH_ALG_AES_CCM"; case ODP_AUTH_ALG_CHACHA20_POLY1305: return "ODP_AUTH_ALG_CHACHA20_POLY1305"; default: @@ -72,6 +74,8 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher) return "ODP_CIPHER_ALG_AES_CBC"; case ODP_CIPHER_ALG_AES_GCM: return "ODP_CIPHER_ALG_AES_GCM"; + case ODP_CIPHER_ALG_AES_CCM: + return "ODP_CIPHER_ALG_AES_CCM"; case ODP_CIPHER_ALG_CHACHA20_POLY1305: return "ODP_CIPHER_ALG_CHACHA20_POLY1305"; default: @@ -477,6 +481,9 @@ static void check_alg(odp_crypto_op_t op, if (cipher_alg == ODP_CIPHER_ALG_AES_GCM && !(capa.ciphers.bit.aes_gcm)) rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_AES_CCM && + !(capa.ciphers.bit.aes_ccm)) + rc = -1; if (cipher_alg == ODP_CIPHER_ALG_CHACHA20_POLY1305 && !(capa.ciphers.bit.chacha20_poly1305)) rc = -1; @@ -496,6 +503,9 @@ static void check_alg(odp_crypto_op_t op, if (auth_alg == ODP_AUTH_ALG_AES_GMAC && !(capa.auths.bit.aes_gmac)) rc = -1; + if (auth_alg == ODP_AUTH_ALG_AES_CCM && + !(capa.auths.bit.aes_ccm)) + rc = -1; if (auth_alg == ODP_AUTH_ALG_CHACHA20_POLY1305 && !(capa.auths.bit.chacha20_poly1305)) rc = -1; @@ -664,6 +674,10 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.ciphers.bit.aes_gcm) return ODP_TEST_INACTIVE; break; + case ODP_CIPHER_ALG_AES_CCM: + if (!capability.ciphers.bit.aes_ccm) + return ODP_TEST_INACTIVE; + break; case ODP_CIPHER_ALG_CHACHA20_POLY1305: if (!capability.ciphers.bit.chacha20_poly1305) return ODP_TEST_INACTIVE; @@ -703,6 +717,10 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.auths.bit.aes_gmac) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_AES_CCM: + if (!capability.auths.bit.aes_ccm) + return ODP_TEST_INACTIVE; + break; case ODP_AUTH_ALG_CHACHA20_POLY1305: if (!capability.auths.bit.chacha20_poly1305) return ODP_TEST_INACTIVE; @@ -912,6 +930,51 @@ static void crypto_test_dec_alg_aes_gcm_ovr_iv(void) true); }
+static int check_alg_aes_ccm(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CCM, ODP_AUTH_ALG_AES_CCM); +} + +static void crypto_test_enc_alg_aes_ccm(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CCM, + ODP_AUTH_ALG_AES_CCM, + aes_ccm_reference, + ARRAY_SIZE(aes_ccm_reference), + false); +} + +static void crypto_test_enc_alg_aes_ccm_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CCM, + ODP_AUTH_ALG_AES_CCM, + aes_ccm_reference, + ARRAY_SIZE(aes_ccm_reference), + true); +} + +static void crypto_test_dec_alg_aes_ccm(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CCM, + ODP_AUTH_ALG_AES_CCM, + aes_ccm_reference, + ARRAY_SIZE(aes_ccm_reference), + false); +} + +static void crypto_test_dec_alg_aes_ccm_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CCM, + ODP_AUTH_ALG_AES_CCM, + aes_ccm_reference, + ARRAY_SIZE(aes_ccm_reference), + true); +} + static int check_alg_aes_cbc(void) { return check_alg_support(ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL); @@ -1311,6 +1374,14 @@ odp_testinfo_t crypto_suite[] = { check_alg_aes_gcm), ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm_ovr_iv, check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ccm, + check_alg_aes_ccm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ccm_ovr_iv, + check_alg_aes_ccm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ccm, + check_alg_aes_ccm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ccm_ovr_iv, + check_alg_aes_ccm), ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_chacha20_poly1305, check_alg_chacha20_poly1305), ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_chacha20_poly1305_ovr_iv, diff --git a/test/validation/api/crypto/test_vectors.h b/test/validation/api/crypto/test_vectors.h index 97f0620a..15cd91d2 100644 --- a/test/validation/api/crypto/test_vectors.h +++ b/test/validation/api/crypto/test_vectors.h @@ -444,6 +444,134 @@ static crypto_test_reference_t aes_gcm_reference[] = { } };
+static crypto_test_reference_t aes_ccm_reference[] = { + /* + * AES-CCM reference from RFC 3610 + */ + { + .cipher_key_length = AES128_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf}, + .cipher_iv_length = 13, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0x58, 0x8c, 0x97, 0x9a, 0x61, 0xc6, 0x63, 0xd2, + 0xf0, 0x66, 0xd0, 0xc2, 0xc0, 0xf9, 0x89, 0x80, + 0x6d, 0x5f, 0x6b, 0x61, 0xda, 0xc3, 0x84 }, + .digest_length = 8, + .digest = { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 } + }, + /* The rest of test vectors are generated manually, no "interesting" + * vectors for use cases in RFC 3610 or SP 800-38C. */ + { + .cipher_key_length = AES192_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7}, + .cipher_iv_length = 13, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0x57, 0x9f, 0xb8, 0x6e, 0xdd, 0xb4, 0xa6, 0x4a, + 0xae, 0x5f, 0xe9, 0x6d, 0xbd, 0x75, 0x44, 0x05, + 0x33, 0xa9, 0xfc, 0x3a, 0x84, 0x57, 0x36 }, + .digest_length = 8, + .digest = { 0x67, 0xae, 0xc8, 0x0a, 0xc5, 0x88, 0xab, 0x16 } + }, + { + .cipher_key_length = AES256_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf}, + .cipher_iv_length = 13, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0x59, 0x61, 0x55, 0x10, 0xa7, 0xc4, 0x3b, 0xfb, + 0x12, 0x3d, 0x63, 0x6b, 0x46, 0x13, 0xc0, 0x3c, + 0x6c, 0xe2, 0x69, 0x07, 0x10, 0x2a, 0x3f }, + .digest_length = 8, + .digest = { 0xb5, 0x57, 0x2a, 0x17, 0x2d, 0x49, 0x16, 0xd5 } + }, + { + .cipher_key_length = AES128_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf}, + .cipher_iv_length = 11, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0xaa, 0x2d, 0x3e, 0xcb, 0xa6, 0x68, 0x63, 0x75, + 0x8f, 0x03, 0x01, 0x51, 0x16, 0xde, 0x30, 0xed, + 0x8a, 0xb5, 0x42, 0xdc, 0xfa, 0x72, 0xd0 }, + .digest_length = 8, + .digest = { 0x63, 0xe7, 0x01, 0x5c, 0x69, 0xaf, 0xb4, 0x0c } + }, + { + .cipher_key_length = AES192_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7}, + .cipher_iv_length = 11, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0xee, 0x99, 0x99, 0x1e, 0xc5, 0x8f, 0xd7, 0x7e, + 0x56, 0x71, 0x16, 0x39, 0x8e, 0xc4, 0x4f, 0xcc, + 0x14, 0x45, 0x57, 0x3e, 0x38, 0x76, 0x51 }, + .digest_length = 8, + .digest = { 0x31, 0x29, 0x47, 0xa4, 0x6d, 0x76, 0x34, 0xb4 } + }, + { + .cipher_key_length = AES256_KEY_LEN, + .cipher_key = { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf}, + .cipher_iv_length = 11, + .cipher_iv = { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xa0, + 0xa1, 0xa2, 0xa3 }, + .aad_length = 8, + .aad = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, + .length = 23, + .plaintext = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e }, + .ciphertext = { 0xfa, 0x07, 0x47, 0x5c, 0xe8, 0xc9, 0x37, 0x88, + 0x54, 0x64, 0xb8, 0xc3, 0x85, 0xbb, 0x76, 0x0b, + 0xf2, 0xc2, 0x4c, 0x4e, 0x31, 0x16, 0x77 }, + .digest_length = 8, + .digest = { 0x88, 0x56, 0x7e, 0x19, 0x84, 0x13, 0x29, 0xc4 } + }, +}; + static crypto_test_reference_t aes_gmac_reference[] = { { .auth_key_length = AES128_KEY_LEN,
commit 815f7ada60297c08469ab62cee369df4770ae2aa Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 08:03:19 2018 +0300
validation: crypto: add ChaCha20-Poly1305 test vectors
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index 0448972b..5c38ae85 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -52,6 +52,8 @@ static const char *auth_alg_name(odp_auth_alg_t auth) return "ODP_AUTH_ALG_AES_GCM"; case ODP_AUTH_ALG_AES_GMAC: return "ODP_AUTH_ALG_AES_GMAC"; + case ODP_AUTH_ALG_CHACHA20_POLY1305: + return "ODP_AUTH_ALG_CHACHA20_POLY1305"; default: return "Unknown"; } @@ -70,6 +72,8 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher) return "ODP_CIPHER_ALG_AES_CBC"; case ODP_CIPHER_ALG_AES_GCM: return "ODP_CIPHER_ALG_AES_GCM"; + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + return "ODP_CIPHER_ALG_CHACHA20_POLY1305"; default: return "Unknown"; } @@ -473,6 +477,9 @@ static void check_alg(odp_crypto_op_t op, if (cipher_alg == ODP_CIPHER_ALG_AES_GCM && !(capa.ciphers.bit.aes_gcm)) rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_CHACHA20_POLY1305 && + !(capa.ciphers.bit.chacha20_poly1305)) + rc = -1; if (cipher_alg == ODP_CIPHER_ALG_DES && !(capa.ciphers.bit.des)) rc = -1; @@ -489,6 +496,9 @@ static void check_alg(odp_crypto_op_t op, if (auth_alg == ODP_AUTH_ALG_AES_GMAC && !(capa.auths.bit.aes_gmac)) rc = -1; + if (auth_alg == ODP_AUTH_ALG_CHACHA20_POLY1305 && + !(capa.auths.bit.chacha20_poly1305)) + rc = -1; if (auth_alg == ODP_AUTH_ALG_MD5_HMAC && !(capa.auths.bit.md5_hmac)) rc = -1; @@ -654,6 +664,10 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.ciphers.bit.aes_gcm) return ODP_TEST_INACTIVE; break; + case ODP_CIPHER_ALG_CHACHA20_POLY1305: + if (!capability.ciphers.bit.chacha20_poly1305) + return ODP_TEST_INACTIVE; + break; default: fprintf(stderr, "Unsupported cipher algorithm\n"); return ODP_TEST_INACTIVE; @@ -689,6 +703,10 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.auths.bit.aes_gmac) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_CHACHA20_POLY1305: + if (!capability.auths.bit.chacha20_poly1305) + return ODP_TEST_INACTIVE; + break; default: fprintf(stderr, "Unsupported authentication algorithm\n"); return ODP_TEST_INACTIVE; @@ -785,6 +803,52 @@ static void crypto_test_dec_alg_3des_cbc_ovr_iv(void) true); }
+static int check_alg_chacha20_poly1305(void) +{ + return check_alg_support(ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305); +} + +static void crypto_test_enc_alg_chacha20_poly1305(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305, + chacha20_poly1305_reference, + ARRAY_SIZE(chacha20_poly1305_reference), + false); +} + +static void crypto_test_enc_alg_chacha20_poly1305_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305, + chacha20_poly1305_reference, + ARRAY_SIZE(chacha20_poly1305_reference), + true); +} + +static void crypto_test_dec_alg_chacha20_poly1305(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305, + chacha20_poly1305_reference, + ARRAY_SIZE(chacha20_poly1305_reference), + false); +} + +static void crypto_test_dec_alg_chacha20_poly1305_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_CHACHA20_POLY1305, + ODP_AUTH_ALG_CHACHA20_POLY1305, + chacha20_poly1305_reference, + ARRAY_SIZE(chacha20_poly1305_reference), + true); +} + static int check_alg_aes_gcm(void) { return check_alg_support(ODP_CIPHER_ALG_AES_GCM, ODP_AUTH_ALG_AES_GCM); @@ -1247,6 +1311,14 @@ odp_testinfo_t crypto_suite[] = { check_alg_aes_gcm), ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm_ovr_iv, check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_chacha20_poly1305, + check_alg_chacha20_poly1305), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_chacha20_poly1305_ovr_iv, + check_alg_chacha20_poly1305), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_chacha20_poly1305, + check_alg_chacha20_poly1305), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_chacha20_poly1305_ovr_iv, + check_alg_chacha20_poly1305), ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5, check_alg_hmac_md5), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, diff --git a/test/validation/api/crypto/test_vectors.h b/test/validation/api/crypto/test_vectors.h index ff69717d..97f0620a 100644 --- a/test/validation/api/crypto/test_vectors.h +++ b/test/validation/api/crypto/test_vectors.h @@ -477,6 +477,144 @@ static crypto_test_reference_t aes_gmac_reference[] = { }, };
+/* + * Test vector from RFC 7539, sections 2.8.2, A.5 + */ +static crypto_test_reference_t chacha20_poly1305_reference[] = { + { + .cipher_key_length = CHACHA20_POLY1305_KEY_LEN, + .cipher_key = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f}, + .cipher_iv_length = CHACHA20_POLY1305_IV_LEN, + .cipher_iv = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47 }, + .length = 114, + .plaintext = { 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, + 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, + 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, + 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, + 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, + 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, + 0x74, 0x2e }, + .ciphertext = { 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, + 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, + 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, + 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, + 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, + 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, + 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, + 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, + 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, + 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, + 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, + 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, + 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, + 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, + 0x61, 0x16 }, + .aad_length = 12, + .aad = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7 }, + .digest_length = 16, + .digest = { 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, + 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 } + }, + { + .cipher_key_length = CHACHA20_POLY1305_KEY_LEN, + .cipher_key = { 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, + 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, + 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, + 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0}, + .cipher_iv_length = CHACHA20_POLY1305_IV_LEN, + .cipher_iv = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08 }, + .length = 265, + .plaintext = { 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x73, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x64, 0x72, 0x61, 0x66, + 0x74, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, + 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, + 0x6f, 0x66, 0x20, 0x73, 0x69, 0x78, 0x20, 0x6d, + 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, + 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x2c, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6f, + 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, + 0x6e, 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, + 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x70, 0x72, + 0x69, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x75, 0x73, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, + 0x66, 0x74, 0x73, 0x20, 0x61, 0x73, 0x20, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, + 0x6d, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x73, 0x20, + 0x2f, 0xe2, 0x80, 0x9c, 0x77, 0x6f, 0x72, 0x6b, + 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x2e, 0x2f, 0xe2, 0x80, + 0x9d }, + .ciphertext = { 0x64, 0xa0, 0x86, 0x15, 0x75, 0x86, 0x1a, 0xf4, + 0x60, 0xf0, 0x62, 0xc7, 0x9b, 0xe6, 0x43, 0xbd, + 0x5e, 0x80, 0x5c, 0xfd, 0x34, 0x5c, 0xf3, 0x89, + 0xf1, 0x08, 0x67, 0x0a, 0xc7, 0x6c, 0x8c, 0xb2, + 0x4c, 0x6c, 0xfc, 0x18, 0x75, 0x5d, 0x43, 0xee, + 0xa0, 0x9e, 0xe9, 0x4e, 0x38, 0x2d, 0x26, 0xb0, + 0xbd, 0xb7, 0xb7, 0x3c, 0x32, 0x1b, 0x01, 0x00, + 0xd4, 0xf0, 0x3b, 0x7f, 0x35, 0x58, 0x94, 0xcf, + 0x33, 0x2f, 0x83, 0x0e, 0x71, 0x0b, 0x97, 0xce, + 0x98, 0xc8, 0xa8, 0x4a, 0xbd, 0x0b, 0x94, 0x81, + 0x14, 0xad, 0x17, 0x6e, 0x00, 0x8d, 0x33, 0xbd, + 0x60, 0xf9, 0x82, 0xb1, 0xff, 0x37, 0xc8, 0x55, + 0x97, 0x97, 0xa0, 0x6e, 0xf4, 0xf0, 0xef, 0x61, + 0xc1, 0x86, 0x32, 0x4e, 0x2b, 0x35, 0x06, 0x38, + 0x36, 0x06, 0x90, 0x7b, 0x6a, 0x7c, 0x02, 0xb0, + 0xf9, 0xf6, 0x15, 0x7b, 0x53, 0xc8, 0x67, 0xe4, + 0xb9, 0x16, 0x6c, 0x76, 0x7b, 0x80, 0x4d, 0x46, + 0xa5, 0x9b, 0x52, 0x16, 0xcd, 0xe7, 0xa4, 0xe9, + 0x90, 0x40, 0xc5, 0xa4, 0x04, 0x33, 0x22, 0x5e, + 0xe2, 0x82, 0xa1, 0xb0, 0xa0, 0x6c, 0x52, 0x3e, + 0xaf, 0x45, 0x34, 0xd7, 0xf8, 0x3f, 0xa1, 0x15, + 0x5b, 0x00, 0x47, 0x71, 0x8c, 0xbc, 0x54, 0x6a, + 0x0d, 0x07, 0x2b, 0x04, 0xb3, 0x56, 0x4e, 0xea, + 0x1b, 0x42, 0x22, 0x73, 0xf5, 0x48, 0x27, 0x1a, + 0x0b, 0xb2, 0x31, 0x60, 0x53, 0xfa, 0x76, 0x99, + 0x19, 0x55, 0xeb, 0xd6, 0x31, 0x59, 0x43, 0x4e, + 0xce, 0xbb, 0x4e, 0x46, 0x6d, 0xae, 0x5a, 0x10, + 0x73, 0xa6, 0x72, 0x76, 0x27, 0x09, 0x7a, 0x10, + 0x49, 0xe6, 0x17, 0xd9, 0x1d, 0x36, 0x10, 0x94, + 0xfa, 0x68, 0xf0, 0xff, 0x77, 0x98, 0x71, 0x30, + 0x30, 0x5b, 0xea, 0xba, 0x2e, 0xda, 0x04, 0xdf, + 0x99, 0x7b, 0x71, 0x4d, 0x6c, 0x6f, 0x2c, 0x29, + 0xa6, 0xad, 0x5c, 0xb4, 0x02, 0x2b, 0x02, 0x70, + 0x9b }, + .aad_length = 12, + .aad = { 0xf3, 0x33, 0x88, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4e, 0x91 }, + .digest_length = CHACHA20_POLY1305_CHECK_LEN, + .digest = { 0xee, 0xad, 0x9d, 0x67, 0x89, 0x0c, 0xbb, 0x22, + 0x39, 0x23, 0x36, 0xfe, 0xa1, 0x85, 0x1f, 0x38 } + }, +}; + static crypto_test_reference_t hmac_md5_reference[] = { { .auth_key_length = HMAC_MD5_KEY_LEN, diff --git a/test/validation/api/crypto/test_vectors_len.h b/test/validation/api/crypto/test_vectors_len.h index 8933017b..860840cf 100644 --- a/test/validation/api/crypto/test_vectors_len.h +++ b/test/validation/api/crypto/test_vectors_len.h @@ -9,7 +9,7 @@ /* Maximum */ #define MAX_KEY_LEN 64 #define MAX_IV_LEN 16 -#define MAX_DATA_LEN 128 +#define MAX_DATA_LEN 270 #define MAX_AAD_LEN 12 #define MAX_DIGEST_LEN 64
@@ -55,4 +55,9 @@ #define HMAC_SHA512_256_CHECK_LEN 32 #define HMAC_SHA512_CHECK_LEN 64
+/* ChaCha20-Poly1305 */ +#define CHACHA20_POLY1305_KEY_LEN 32 +#define CHACHA20_POLY1305_IV_LEN 12 +#define CHACHA20_POLY1305_CHECK_LEN 16 + #endif
commit f8fa58a9061def1f7fdfc5adbb09c7fa67e1d425 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 02:37:10 2018 +0300
validation: crypto: use single definitions for AES key lengths
Merge defines for AES-CBC/CTR/GCM keys.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/test_vectors.h b/test/validation/api/crypto/test_vectors.h index 9c0b844d..ff69717d 100644 --- a/test/validation/api/crypto/test_vectors.h +++ b/test/validation/api/crypto/test_vectors.h @@ -74,7 +74,7 @@ static crypto_test_reference_t tdes_cbc_reference[] = {
static crypto_test_reference_t aes_cbc_reference[] = { { - .cipher_key_length = AES128_CBC_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b, 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06}, .cipher_iv_length = AES_CBC_IV_LEN, @@ -86,7 +86,7 @@ static crypto_test_reference_t aes_cbc_reference[] = { 0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a } }, { - .cipher_key_length = AES128_CBC_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0, 0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a}, .cipher_iv_length = AES_CBC_IV_LEN, @@ -103,7 +103,7 @@ static crypto_test_reference_t aes_cbc_reference[] = { 0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 } }, { - .cipher_key_length = AES128_CBC_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x6c, 0x3e, 0xa0, 0x47, 0x76, 0x30, 0xce, 0x21, 0xa2, 0xce, 0x33, 0x4a, 0xa7, 0x46, 0xc2, 0xcd}, .cipher_iv_length = AES_CBC_IV_LEN, @@ -119,7 +119,7 @@ static crypto_test_reference_t aes_cbc_reference[] = { 0x85, 0x79, 0x69, 0x5d, 0x83, 0xba, 0x26, 0x84 } }, { - .cipher_key_length = AES128_CBC_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74, 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49}, .cipher_iv_length = AES_CBC_IV_LEN, @@ -144,7 +144,7 @@ static crypto_test_reference_t aes_cbc_reference[] = { 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55 } }, { - .cipher_key_length = AES192_CBC_KEY_LEN, + .cipher_key_length = AES192_KEY_LEN, .cipher_key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c}, @@ -162,7 +162,7 @@ static crypto_test_reference_t aes_cbc_reference[] = { 0x53, 0x1c, 0xc6, 0x98, 0x85, 0xc3, 0x00, 0xe6}, }, { - .cipher_key_length = AES256_CBC_KEY_LEN, + .cipher_key_length = AES256_KEY_LEN, .cipher_key = { 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, @@ -188,7 +188,7 @@ static crypto_test_reference_t aes_cbc_reference[] = {
static crypto_test_reference_t aes_ctr_reference[] = { { - .cipher_key_length = AES128_CTR_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}, .cipher_iv_length = AES_CTR_IV_LEN, @@ -213,7 +213,7 @@ static crypto_test_reference_t aes_ctr_reference[] = { 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee } }, { - .cipher_key_length = AES192_CTR_KEY_LEN, + .cipher_key_length = AES192_KEY_LEN, .cipher_key = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b}, @@ -239,7 +239,7 @@ static crypto_test_reference_t aes_ctr_reference[] = { 0x5a, 0x97, 0xda, 0xec, 0x58, 0xc6, 0xb0, 0x50 } }, { - .cipher_key_length = AES256_CTR_KEY_LEN, + .cipher_key_length = AES256_KEY_LEN, .cipher_key = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, @@ -272,7 +272,7 @@ static crypto_test_reference_t aes_ctr_reference[] = { */ static crypto_test_reference_t aes_gcm_reference[] = { { - .cipher_key_length = AES128_GCM_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x4c, 0x80, 0xcd, 0xef, 0xbb, 0x5d, 0x10, 0xda, 0x90, 0x6a, 0xc7, 0x3c, 0x36, 0x13, 0xa6, 0x34}, .cipher_iv_length = AES_GCM_IV_LEN, @@ -305,7 +305,7 @@ static crypto_test_reference_t aes_gcm_reference[] = { 0x2f, 0xd0, 0x47, 0x96, 0x56, 0x2d, 0xfd, 0xb4 } }, { - .cipher_key_length = AES128_GCM_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08}, .cipher_iv_length = AES_GCM_IV_LEN, @@ -335,7 +335,7 @@ static crypto_test_reference_t aes_gcm_reference[] = { 0xc3, 0x09, 0xe9, 0xd8, 0x5a, 0x41, 0xad, 0x4a } }, { - .cipher_key_length = AES128_GCM_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, .cipher_iv_length = AES_GCM_IV_LEN, @@ -365,7 +365,7 @@ static crypto_test_reference_t aes_gcm_reference[] = { 0x8a, 0xd2, 0xb6, 0x9e, 0x47, 0x99, 0xc7, 0x1d } }, { - .cipher_key_length = AES128_GCM_KEY_LEN, + .cipher_key_length = AES128_KEY_LEN, .cipher_key = { 0x3d, 0xe0, 0x98, 0x74, 0xb3, 0x88, 0xe6, 0x49, 0x19, 0x88, 0xd0, 0xc3, 0x60, 0x7e, 0xae, 0x1f}, .cipher_iv_length = AES_GCM_IV_LEN, @@ -388,7 +388,7 @@ static crypto_test_reference_t aes_gcm_reference[] = { 0x95, 0xf1, 0x12, 0xe4, 0xe7, 0xd0, 0x5d, 0x35 } }, { - .cipher_key_length = AES192_GCM_KEY_LEN, + .cipher_key_length = AES192_KEY_LEN, .cipher_key = { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c}, @@ -413,7 +413,7 @@ static crypto_test_reference_t aes_gcm_reference[] = { 0x18, 0x02, 0x7b, 0x5b, 0x4c, 0xd7, 0xa6, 0x36 } }, { - .cipher_key_length = AES256_GCM_KEY_LEN, + .cipher_key_length = AES256_KEY_LEN, .cipher_key = { 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, 0xab, 0xbc, 0xcd, 0xde, 0xf0, 0x01, 0x12, 0x23, @@ -446,7 +446,7 @@ static crypto_test_reference_t aes_gcm_reference[] = {
static crypto_test_reference_t aes_gmac_reference[] = { { - .auth_key_length = AES128_GCM_KEY_LEN, + .auth_key_length = AES128_KEY_LEN, .auth_key = { 0x4c, 0x80, 0xcd, 0xef, 0xbb, 0x5d, 0x10, 0xda, 0x90, 0x6a, 0xc7, 0x3c, 0x36, 0x13, 0xa6, 0x34}, .auth_iv_length = AES_GCM_IV_LEN, diff --git a/test/validation/api/crypto/test_vectors_len.h b/test/validation/api/crypto/test_vectors_len.h index 2551b054..8933017b 100644 --- a/test/validation/api/crypto/test_vectors_len.h +++ b/test/validation/api/crypto/test_vectors_len.h @@ -17,43 +17,24 @@ #define TDES_CBC_KEY_LEN 24 #define TDES_CBC_IV_LEN 8
-/* AES-CBC common */ -#define AES_CBC_IV_LEN 16 - -/* AES128-CBC */ -#define AES128_CBC_KEY_LEN 16 +/* AES common */
-/* AES192-CBC */ -#define AES192_CBC_KEY_LEN 24 +#define AES128_KEY_LEN 16
-/* AES256-CBC */ -#define AES256_CBC_KEY_LEN 32 +#define AES192_KEY_LEN 24
-/* AES-CBC common */ -#define AES_CTR_IV_LEN 16 +#define AES256_KEY_LEN 32
-/* AES128-CTR */ -#define AES128_CTR_KEY_LEN 16 - -/* AES192-CTR */ -#define AES192_CTR_KEY_LEN 24 +/* AES-CBC */ +#define AES_CBC_IV_LEN 16
-/* AES256-CTR */ -#define AES256_CTR_KEY_LEN 32 +/* AES-CTR */ +#define AES_CTR_IV_LEN 16
-/* AES-GCM common */ +/* AES-GCM */ #define AES_GCM_IV_LEN 12 #define AES_GCM_DIGEST_LEN 16
-/* AES128-GCM */ -#define AES128_GCM_KEY_LEN 16 - -/* AES192-GCM */ -#define AES192_GCM_KEY_LEN 24 - -/* AES256-GCM */ -#define AES256_GCM_KEY_LEN 32 - /* HMAC-MD5 */ #define HMAC_MD5_KEY_LEN 16 #define HMAC_MD5_96_CHECK_LEN 12
commit 98c59aa12adb2acda489261a631cb85c6bdbb358 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 04:27:52 2018 +0300
validation: crypto: drop obsolete GMAC-related hack
Checking that cipher is not NULL was required because GMAC used NULL cipher to specify it's IV. Now it is obosolete, as auths has their own IV.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index 2b0ba1cd..0448972b 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -580,9 +580,6 @@ static void check_alg(odp_crypto_op_t op, for (i = 0; i < cipher_num; i++) { cipher_ok |= cipher_tested[i]; if (!cipher_tested[i]) { - /* GMAC-related hacks */ - if (cipher_alg == ODP_CIPHER_ALG_NULL) - continue; printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " "iv_len=%" PRIu32 "\n", cipher_alg_name(cipher_alg),
commit 036c1011222ee0e75d8572332aff9043510c3ec3 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 21:06:45 2018 +0300
validation: crypto: use unix file format
Merge f925f103c90591776f73863d30159357b08bf71e changed EOL to DOS convention in this file. Change it back.
Fixes: f925f103c90591776f73863d30159357b08bf71e Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c index 1d92c656..2b0ba1cd 100644 --- a/test/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/validation/api/crypto/odp_crypto_test_inp.c @@ -1,1296 +1,1296 @@ -/* Copyright (c) 2014-2018, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "config.h" - -#include <odp_api.h> -#include <CUnit/Basic.h> -#include <odp_cunit_common.h> -#include "test_vectors.h" -#include "odp_crypto_test_inp.h" -#include "crypto.h" - -#define MAX_ALG_CAPA 32 - -struct suite_context_s { - odp_bool_t packet; - odp_crypto_op_mode_t op_mode; - odp_crypto_op_mode_t pref_mode; - odp_pool_t pool; - odp_queue_t queue; -}; - -static struct suite_context_s suite_context; - -static int packet_cmp_mem(odp_packet_t pkt, uint32_t offset, - void *s, uint32_t len) -{ - uint8_t buf[len]; - - odp_packet_copy_to_mem(pkt, offset, len, buf); - - return memcmp(buf, s, len); -} - -static const char *auth_alg_name(odp_auth_alg_t auth) -{ - switch (auth) { - case ODP_AUTH_ALG_NULL: - return "ODP_AUTH_ALG_NULL"; - case ODP_AUTH_ALG_MD5_HMAC: - return "ODP_AUTH_ALG_MD5_HMAC"; - case ODP_AUTH_ALG_SHA1_HMAC: - return "ODP_AUTH_ALG_SHA1_HMAC"; - case ODP_AUTH_ALG_SHA256_HMAC: - return "ODP_AUTH_ALG_SHA256_HMAC"; - case ODP_AUTH_ALG_SHA512_HMAC: - return "ODP_AUTH_ALG_SHA512_HMAC"; - case ODP_AUTH_ALG_AES_GCM: - return "ODP_AUTH_ALG_AES_GCM"; - case ODP_AUTH_ALG_AES_GMAC: - return "ODP_AUTH_ALG_AES_GMAC"; - default: - return "Unknown"; - } -} - -static const char *cipher_alg_name(odp_cipher_alg_t cipher) -{ - switch (cipher) { - case ODP_CIPHER_ALG_NULL: - return "ODP_CIPHER_ALG_NULL"; - case ODP_CIPHER_ALG_DES: - return "ODP_CIPHER_ALG_DES"; - case ODP_CIPHER_ALG_3DES_CBC: - return "ODP_CIPHER_ALG_3DES_CBC"; - case ODP_CIPHER_ALG_AES_CBC: - return "ODP_CIPHER_ALG_AES_CBC"; - case ODP_CIPHER_ALG_AES_GCM: - return "ODP_CIPHER_ALG_AES_GCM"; - default: - return "Unknown"; - } -} - -static int alg_op(odp_packet_t pkt, - odp_bool_t *ok, - odp_crypto_session_t session, - uint8_t *cipher_iv_ptr, - uint8_t *auth_iv_ptr, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, - uint8_t *aad, - unsigned int plaintext_len) -{ - int rc; - odp_crypto_op_result_t result; - odp_crypto_op_param_t op_params; - odp_bool_t posted; - odp_event_subtype_t subtype; - - /* Prepare input/output params */ - memset(&op_params, 0, sizeof(op_params)); - op_params.session = session; - op_params.pkt = pkt; - op_params.out_pkt = pkt; - op_params.ctx = (void *)0xdeadbeef; - - op_params.cipher_range = *cipher_range; - op_params.auth_range = *auth_range; - if (cipher_iv_ptr) - op_params.cipher_iv_ptr = cipher_iv_ptr; - if (auth_iv_ptr) - op_params.auth_iv_ptr = auth_iv_ptr; - - op_params.aad_ptr = aad; - - op_params.hash_result_offset = plaintext_len; - - rc = odp_crypto_operation(&op_params, &posted, &result); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_operation()"); - return rc; - } - - if (posted) { - odp_event_t event; - odp_crypto_compl_t compl_event; - - /* Poll completion queue for results */ - do { - event = odp_queue_deq(suite_context.queue); - } while (event == ODP_EVENT_INVALID); - - CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == odp_event_type(event)); - CU_ASSERT(ODP_EVENT_NO_SUBTYPE == odp_event_subtype(event)); - CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == - odp_event_types(event, &subtype)); - CU_ASSERT(ODP_EVENT_NO_SUBTYPE == subtype); - - compl_event = odp_crypto_compl_from_event(event); - CU_ASSERT(odp_crypto_compl_to_u64(compl_event) == - odp_crypto_compl_to_u64( - odp_crypto_compl_from_event(event))); - odp_crypto_compl_result(compl_event, &result); - odp_crypto_compl_free(compl_event); - } - - CU_ASSERT(result.pkt == pkt); - CU_ASSERT(result.ctx == (void *)0xdeadbeef); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_type(odp_packet_to_event(result.pkt))); - CU_ASSERT(ODP_EVENT_PACKET_BASIC == - odp_event_subtype(odp_packet_to_event(result.pkt))); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_types(odp_packet_to_event(result.pkt), &subtype)); - CU_ASSERT(ODP_EVENT_PACKET_BASIC == subtype); - - *ok = result.ok; - - return 0; -} - -static int alg_packet_op(odp_packet_t pkt, - odp_bool_t *ok, - odp_crypto_session_t session, - uint8_t *cipher_iv_ptr, - uint8_t *auth_iv_ptr, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, - uint8_t *aad, - unsigned int plaintext_len) -{ - int rc; - odp_crypto_packet_result_t result; - odp_crypto_packet_op_param_t op_params; - odp_event_subtype_t subtype; - odp_packet_t out_pkt = pkt; - - /* Prepare input/output params */ - memset(&op_params, 0, sizeof(op_params)); - op_params.session = session; - - op_params.cipher_range = *cipher_range; - op_params.auth_range = *auth_range; - if (cipher_iv_ptr) - op_params.cipher_iv_ptr = cipher_iv_ptr; - if (auth_iv_ptr) - op_params.auth_iv_ptr = auth_iv_ptr; - - op_params.aad_ptr = aad; - - op_params.hash_result_offset = plaintext_len; - - rc = odp_crypto_op(&pkt, &out_pkt, &op_params, 1); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_packet_op()"); - return rc; - } - - CU_ASSERT(out_pkt == pkt); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_type(odp_packet_to_event(pkt))); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == - odp_event_subtype(odp_packet_to_event(pkt))); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_types(odp_packet_to_event(pkt), &subtype)); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); - - rc = odp_crypto_result(&result, pkt); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_packet_result()"); - return rc; - } - - if (!result.ok) - CU_ASSERT(odp_packet_has_error(pkt)); - - *ok = result.ok; - - return 0; -} - -static int alg_packet_op_enq(odp_packet_t pkt, - odp_bool_t *ok, - odp_crypto_session_t session, - uint8_t *cipher_iv_ptr, - uint8_t *auth_iv_ptr, - odp_packet_data_range_t *cipher_range, - odp_packet_data_range_t *auth_range, - uint8_t *aad, - unsigned int plaintext_len) -{ - int rc; - odp_event_t event; - odp_crypto_packet_result_t result; - odp_crypto_packet_op_param_t op_params; - odp_event_subtype_t subtype; - odp_packet_t out_pkt = pkt; - - /* Prepare input/output params */ - memset(&op_params, 0, sizeof(op_params)); - op_params.session = session; - - op_params.cipher_range = *cipher_range; - op_params.auth_range = *auth_range; - if (cipher_iv_ptr) - op_params.cipher_iv_ptr = cipher_iv_ptr; - if (auth_iv_ptr) - op_params.auth_iv_ptr = auth_iv_ptr; - - op_params.aad_ptr = aad; - - op_params.hash_result_offset = plaintext_len; - - rc = odp_crypto_op_enq(&pkt, &pkt, &op_params, 1); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_op_enq()"); - return rc; - } - - /* Poll completion queue for results */ - do { - event = odp_queue_deq(suite_context.queue); - } while (event == ODP_EVENT_INVALID); - - CU_ASSERT(ODP_EVENT_PACKET == odp_event_type(event)); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == odp_event_subtype(event)); - CU_ASSERT(ODP_EVENT_PACKET == odp_event_types(event, &subtype)); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); - - pkt = odp_crypto_packet_from_event(event); - - CU_ASSERT(out_pkt == pkt); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_type(odp_packet_to_event(pkt))); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == - odp_event_subtype(odp_packet_to_event(pkt))); - CU_ASSERT(ODP_EVENT_PACKET == - odp_event_types(odp_packet_to_event(pkt), &subtype)); - CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); - - rc = odp_crypto_result(&result, pkt); - if (rc < 0) { - CU_FAIL("Failed odp_crypto_packet_result()"); - return rc; - } - - CU_ASSERT((!odp_packet_has_error(pkt)) == result.ok); - - *ok = result.ok; - - return 0; -} - -typedef enum crypto_test { - NORMAL_TEST = 0, /**< Plain execution */ - REPEAT_TEST, /**< Rerun without reinitializing the session */ - WRONG_DIGEST_TEST, /**< Check against wrong digest */ - MAX_TEST, /**< Final mark */ -} crypto_test; - -/* Basic algorithm run function for async inplace mode. - * Creates a session from input parameters and runs one operation - * on input_vec. Checks the output of the crypto operation against - * output_vec. Operation completion event is dequeued polling the - * session output queue. Completion context pointer is retrieved - * and checked against the one set before the operation. - * Completion event can be a separate buffer or the input packet - * buffer can be used. - * */ -static void alg_test(odp_crypto_op_t op, - odp_cipher_alg_t cipher_alg, - odp_auth_alg_t auth_alg, - crypto_test_reference_t *ref, - odp_bool_t ovr_iv) -{ - odp_crypto_session_t session; - int rc; - odp_crypto_ses_create_err_t status; - odp_bool_t ok = false; - int iteration; - odp_crypto_session_param_t ses_params; - odp_packet_data_range_t cipher_range; - odp_packet_data_range_t auth_range; - odp_crypto_key_t cipher_key = { - .data = ref->cipher_key, - .length = ref->cipher_key_length - }; - odp_crypto_key_t auth_key = { - .data = ref->auth_key, - .length = ref->auth_key_length - }; - odp_crypto_iv_t cipher_iv = { - .data = ovr_iv ? NULL : ref->cipher_iv, - .length = ref->cipher_iv_length - }; - odp_crypto_iv_t auth_iv = { - .data = ovr_iv ? NULL : ref->auth_iv, - .length = ref->auth_iv_length - }; - - /* Create a crypto session */ - odp_crypto_session_param_init(&ses_params); - ses_params.op = op; - ses_params.auth_cipher_text = false; - ses_params.op_mode = suite_context.op_mode; - ses_params.pref_mode = suite_context.pref_mode; - ses_params.cipher_alg = cipher_alg; - ses_params.auth_alg = auth_alg; - ses_params.compl_queue = suite_context.queue; - ses_params.output_pool = suite_context.pool; - ses_params.cipher_key = cipher_key; - ses_params.cipher_iv = cipher_iv; - ses_params.auth_iv = auth_iv; - ses_params.auth_key = auth_key; - ses_params.auth_digest_len = ref->digest_length; - ses_params.auth_aad_len = ref->aad_length; - - rc = odp_crypto_session_create(&ses_params, &session, &status); - CU_ASSERT_FATAL(!rc); - CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE); - CU_ASSERT(odp_crypto_session_to_u64(session) != - odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); - - cipher_range.offset = 0; - cipher_range.length = ref->length; - auth_range.offset = 0; - auth_range.length = ref->length; - - /* Prepare input data */ - odp_packet_t pkt = odp_packet_alloc(suite_context.pool, - ref->length + ref->digest_length); - CU_ASSERT(pkt != ODP_PACKET_INVALID); - if (pkt == ODP_PACKET_INVALID) - goto cleanup; - - for (iteration = NORMAL_TEST; iteration < MAX_TEST; iteration++) { - /* checking against wrong digest is meaningless for NULL digest - * or when generating digest */ - if (iteration == WRONG_DIGEST_TEST && - (auth_alg == ODP_AUTH_ALG_NULL || - op == ODP_CRYPTO_OP_ENCODE)) - continue; - - if (op == ODP_CRYPTO_OP_ENCODE) { - odp_packet_copy_from_mem(pkt, 0, ref->length, - ref->plaintext); - } else { - odp_packet_copy_from_mem(pkt, 0, ref->length, - ref->ciphertext); - odp_packet_copy_from_mem(pkt, ref->length, - ref->digest_length, - ref->digest); - if (iteration == WRONG_DIGEST_TEST) { - uint8_t byte = ~ref->digest[0]; - - odp_packet_copy_from_mem(pkt, ref->length, - 1, &byte); - } - } - - if (!suite_context.packet) - rc = alg_op(pkt, &ok, session, - ovr_iv ? ref->cipher_iv : NULL, - ovr_iv ? ref->auth_iv : NULL, - &cipher_range, &auth_range, - ref->aad, ref->length); - else if (ODP_CRYPTO_ASYNC == suite_context.op_mode) - rc = alg_packet_op_enq(pkt, &ok, session, - ovr_iv ? ref->cipher_iv : NULL, - ovr_iv ? ref->auth_iv : NULL, - &cipher_range, &auth_range, - ref->aad, ref->length); - else - rc = alg_packet_op(pkt, &ok, session, - ovr_iv ? ref->cipher_iv : NULL, - ovr_iv ? ref->auth_iv : NULL, - &cipher_range, &auth_range, - ref->aad, ref->length); - if (rc < 0) - break; - - if (iteration == WRONG_DIGEST_TEST) { - CU_ASSERT(!ok); - continue; - } - - CU_ASSERT(ok); - - if (op == ODP_CRYPTO_OP_ENCODE) { - CU_ASSERT(!packet_cmp_mem(pkt, 0, - ref->ciphertext, - ref->length)); - CU_ASSERT(!packet_cmp_mem(pkt, ref->length, - ref->digest, - ref->digest_length)); - } else { - CU_ASSERT(!packet_cmp_mem(pkt, 0, - ref->plaintext, - ref->length)); - } - } - - odp_packet_free(pkt); - -cleanup: - rc = odp_crypto_session_destroy(session); - CU_ASSERT(!rc); -} - -static void check_alg(odp_crypto_op_t op, - odp_cipher_alg_t cipher_alg, - odp_auth_alg_t auth_alg, - crypto_test_reference_t *ref, - size_t count, - odp_bool_t ovr_iv) -{ - odp_crypto_capability_t capa; - odp_crypto_cipher_capability_t cipher_capa[MAX_ALG_CAPA]; - odp_crypto_auth_capability_t auth_capa[MAX_ALG_CAPA]; - int rc, cipher_num, auth_num, i; - odp_bool_t cipher_tested[MAX_ALG_CAPA]; - odp_bool_t auth_tested[MAX_ALG_CAPA]; - odp_bool_t cipher_ok = false; - odp_bool_t auth_ok = false; - size_t idx; - - rc = odp_crypto_capability(&capa); - CU_ASSERT(!rc); - - if (cipher_alg == ODP_CIPHER_ALG_3DES_CBC && - !(capa.ciphers.bit.trides_cbc)) - rc = -1; - if (cipher_alg == ODP_CIPHER_ALG_AES_CBC && - !(capa.ciphers.bit.aes_cbc)) - rc = -1; - if (cipher_alg == ODP_CIPHER_ALG_AES_CTR && - !(capa.ciphers.bit.aes_ctr)) - rc = -1; - if (cipher_alg == ODP_CIPHER_ALG_AES_GCM && - !(capa.ciphers.bit.aes_gcm)) - rc = -1; - if (cipher_alg == ODP_CIPHER_ALG_DES && - !(capa.ciphers.bit.des)) - rc = -1; - if (cipher_alg == ODP_CIPHER_ALG_NULL && - !(capa.ciphers.bit.null)) - rc = -1; - - CU_ASSERT(!rc); - CU_ASSERT((~capa.ciphers.all_bits & capa.hw_ciphers.all_bits) == 0); - - if (auth_alg == ODP_AUTH_ALG_AES_GCM && - !(capa.auths.bit.aes_gcm)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_AES_GMAC && - !(capa.auths.bit.aes_gmac)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_MD5_HMAC && - !(capa.auths.bit.md5_hmac)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_NULL && - !(capa.auths.bit.null)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_SHA1_HMAC && - !(capa.auths.bit.sha1_hmac)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC && - !(capa.auths.bit.sha256_hmac)) - rc = -1; - if (auth_alg == ODP_AUTH_ALG_SHA512_HMAC && - !(capa.auths.bit.sha512_hmac)) - rc = -1; - - CU_ASSERT(!rc); - CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0); - - cipher_num = odp_crypto_cipher_capability(cipher_alg, cipher_capa, - MAX_ALG_CAPA); - - CU_ASSERT(cipher_num > 0); - CU_ASSERT(cipher_num <= MAX_ALG_CAPA); - if (cipher_num > MAX_ALG_CAPA) - cipher_num = MAX_ALG_CAPA; - - auth_num = odp_crypto_auth_capability(auth_alg, auth_capa, - MAX_ALG_CAPA); - - CU_ASSERT(auth_num > 0); - CU_ASSERT(auth_num <= MAX_ALG_CAPA); - if (auth_num > MAX_ALG_CAPA) - auth_num = MAX_ALG_CAPA; - - memset(cipher_tested, 0, sizeof(cipher_tested)); - memset(auth_tested, 0, sizeof(auth_tested)); - - for (idx = 0; idx < count; idx++) { - int cipher_idx = -1, auth_idx = -1; - - for (i = 0; i < cipher_num; i++) { - if (cipher_capa[i].key_len == - ref[idx].cipher_key_length && - cipher_capa[i].iv_len == - ref[idx].cipher_iv_length) { - cipher_idx = i; - break; - } - } - - if (cipher_idx < 0) { - printf("\n Unsupported: alg=%s, key_len=%" PRIu32 - ", iv_len=%" PRIu32 "\n", - cipher_alg_name(cipher_alg), - ref[idx].cipher_key_length, - ref[idx].cipher_iv_length); - continue; - } - - for (i = 0; i < auth_num; i++) { - if (auth_capa[i].digest_len == - ref[idx].digest_length && - auth_capa[i].iv_len == - ref[idx].auth_iv_length && - auth_capa[i].key_len == - ref[idx].auth_key_length) { - auth_idx = i; - break; - } - } - - if (auth_idx < 0) { - printf("\n Unsupported: alg=%s, key_len=%" PRIu32 - ", iv_len=%" PRIu32 ", digest_len=%" PRIu32 "\n", - auth_alg_name(auth_alg), - ref[idx].auth_key_length, - ref[idx].auth_iv_length, - ref[idx].digest_length); - continue; - } - - alg_test(op, cipher_alg, auth_alg, &ref[idx], ovr_iv); - - cipher_tested[cipher_idx] = true; - auth_tested[auth_idx] = true; - } - - for (i = 0; i < cipher_num; i++) { - cipher_ok |= cipher_tested[i]; - if (!cipher_tested[i]) { - /* GMAC-related hacks */ - if (cipher_alg == ODP_CIPHER_ALG_NULL) - continue; - printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " - "iv_len=%" PRIu32 "\n", - cipher_alg_name(cipher_alg), - cipher_capa[i].key_len, - cipher_capa[i].iv_len); - } - } - - for (i = 0; i < auth_num; i++) { - auth_ok |= auth_tested[i]; - if (!auth_tested[i]) - printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " - "digest_len=%" PRIu32 "\n", - auth_alg_name(auth_alg), - auth_capa[i].key_len, - auth_capa[i].digest_len); - } - - /* Verify that we were able to run at least several tests */ - CU_ASSERT(cipher_ok); - CU_ASSERT(auth_ok); -} - -/** - * Check if given cipher and authentication algorithms are supported - * - * @param cipher Cipher algorithm - * @param auth Authentication algorithm - * - * @retval ODP_TEST_ACTIVE when both algorithms are supported - * @retval ODP_TEST_INACTIVE when either algorithm is not supported - */ -static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) -{ - odp_crypto_capability_t capability; - - if (odp_crypto_capability(&capability)) - return ODP_TEST_INACTIVE; - - if (suite_context.packet) { - if (suite_context.op_mode == ODP_CRYPTO_SYNC && - capability.sync_mode == ODP_SUPPORT_NO) - return ODP_TEST_INACTIVE; - if (suite_context.op_mode == ODP_CRYPTO_ASYNC && - capability.async_mode == ODP_SUPPORT_NO) - return ODP_TEST_INACTIVE; - } - - /* Cipher algorithms */ - switch (cipher) { - case ODP_CIPHER_ALG_NULL: - if (!capability.ciphers.bit.null) - return ODP_TEST_INACTIVE; - break; - case ODP_CIPHER_ALG_DES: - if (!capability.ciphers.bit.des) - return ODP_TEST_INACTIVE; - break; - case ODP_CIPHER_ALG_3DES_CBC: - if (!capability.ciphers.bit.trides_cbc) - return ODP_TEST_INACTIVE; - break; - case ODP_CIPHER_ALG_AES_CBC: - if (!capability.ciphers.bit.aes_cbc) - return ODP_TEST_INACTIVE; - break; - case ODP_CIPHER_ALG_AES_CTR: - if (!capability.ciphers.bit.aes_ctr) - return ODP_TEST_INACTIVE; - break; - case ODP_CIPHER_ALG_AES_GCM: - if (!capability.ciphers.bit.aes_gcm) - return ODP_TEST_INACTIVE; - break; - default: - fprintf(stderr, "Unsupported cipher algorithm\n"); - return ODP_TEST_INACTIVE; - } - - /* Authentication algorithms */ - switch (auth) { - case ODP_AUTH_ALG_NULL: - if (!capability.auths.bit.null) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_MD5_HMAC: - if (!capability.auths.bit.md5_hmac) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_SHA1_HMAC: - if (!capability.auths.bit.sha1_hmac) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_SHA256_HMAC: - if (!capability.auths.bit.sha256_hmac) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_SHA512_HMAC: - if (!capability.auths.bit.sha512_hmac) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_AES_GCM: - if (!capability.auths.bit.aes_gcm) - return ODP_TEST_INACTIVE; - break; - case ODP_AUTH_ALG_AES_GMAC: - if (!capability.auths.bit.aes_gmac) - return ODP_TEST_INACTIVE; - break; - default: - fprintf(stderr, "Unsupported authentication algorithm\n"); - return ODP_TEST_INACTIVE; - } - - return ODP_TEST_ACTIVE; -} - -static int check_alg_null(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL); -} - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -static void crypto_test_enc_alg_null(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_NULL, - null_reference, - ARRAY_SIZE(null_reference), - false); -} - -static void crypto_test_dec_alg_null(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_NULL, - null_reference, - ARRAY_SIZE(null_reference), - false); -} - -static int check_alg_3des_cbc(void) -{ - return check_alg_support(ODP_CIPHER_ALG_3DES_CBC, ODP_AUTH_ALG_NULL); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for 3DES_CBC algorithm. IV for the operation is the session IV. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer.*/ -static void crypto_test_enc_alg_3des_cbc(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_3DES_CBC, - ODP_AUTH_ALG_NULL, - tdes_cbc_reference, - ARRAY_SIZE(tdes_cbc_reference), - false); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for 3DES_CBC algorithm. IV for the operation is the operation IV. - * */ -static void crypto_test_enc_alg_3des_cbc_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_3DES_CBC, - ODP_AUTH_ALG_NULL, - tdes_cbc_reference, - ARRAY_SIZE(tdes_cbc_reference), - true); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for 3DES_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_3des_cbc(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_3DES_CBC, - ODP_AUTH_ALG_NULL, - tdes_cbc_reference, - ARRAY_SIZE(tdes_cbc_reference), - false); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for 3DES_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_3des_cbc_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_3DES_CBC, - ODP_AUTH_ALG_NULL, - tdes_cbc_reference, - ARRAY_SIZE(tdes_cbc_reference), - true); -} - -static int check_alg_aes_gcm(void) -{ - return check_alg_support(ODP_CIPHER_ALG_AES_GCM, ODP_AUTH_ALG_AES_GCM); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_GCM algorithm. IV for the operation is the session IV. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer.*/ -static void crypto_test_enc_alg_aes_gcm(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_GCM, - ODP_AUTH_ALG_AES_GCM, - aes_gcm_reference, - ARRAY_SIZE(aes_gcm_reference), - false); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_GCM algorithm. IV for the operation is the session IV. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer.*/ -static void crypto_test_enc_alg_aes_gcm_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_GCM, - ODP_AUTH_ALG_AES_GCM, - aes_gcm_reference, - ARRAY_SIZE(aes_gcm_reference), - true); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for 3DES_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_gcm(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_GCM, - ODP_AUTH_ALG_AES_GCM, - aes_gcm_reference, - ARRAY_SIZE(aes_gcm_reference), - false); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for 3DES_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_gcm_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_GCM, - ODP_AUTH_ALG_AES_GCM, - aes_gcm_reference, - ARRAY_SIZE(aes_gcm_reference), - true); -} - -static int check_alg_aes_cbc(void) -{ - return check_alg_support(ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_CBC algorithm. IV for the operation is the session IV. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer.*/ -static void crypto_test_enc_alg_aes_cbc(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_CBC, - ODP_AUTH_ALG_NULL, - aes_cbc_reference, - ARRAY_SIZE(aes_cbc_reference), - false); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_CBC algorithm. IV for the operation is the operation IV. - * */ -static void crypto_test_enc_alg_aes_cbc_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_CBC, - ODP_AUTH_ALG_NULL, - aes_cbc_reference, - ARRAY_SIZE(aes_cbc_reference), - true); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for AES128_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_cbc(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_CBC, - ODP_AUTH_ALG_NULL, - aes_cbc_reference, - ARRAY_SIZE(aes_cbc_reference), - false); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for AES128_CBC algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_cbc_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_CBC, - ODP_AUTH_ALG_NULL, - aes_cbc_reference, - ARRAY_SIZE(aes_cbc_reference), - true); -} - -static int check_alg_aes_ctr(void) -{ - return check_alg_support(ODP_CIPHER_ALG_AES_CTR, ODP_AUTH_ALG_NULL); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_CTR algorithm. IV for the operation is the session IV. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer.*/ -static void crypto_test_enc_alg_aes_ctr(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_CTR, - ODP_AUTH_ALG_NULL, - aes_ctr_reference, - ARRAY_SIZE(aes_ctr_reference), - false); -} - -/* This test verifies the correctness of encode (plaintext -> ciphertext) - * operation for AES128_CTR algorithm. IV for the operation is the operation IV. - * */ -static void crypto_test_enc_alg_aes_ctr_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_AES_CTR, - ODP_AUTH_ALG_NULL, - aes_ctr_reference, - ARRAY_SIZE(aes_ctr_reference), - true); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for AES128_CTR algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_ctr(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_CTR, - ODP_AUTH_ALG_NULL, - aes_ctr_reference, - ARRAY_SIZE(aes_ctr_reference), - false); -} - -/* This test verifies the correctness of decode (ciphertext -> plaintext) - * operation for AES128_CTR algorithm. IV for the operation is the session IV - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_dec_alg_aes_ctr_ovr_iv(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_AES_CTR, - ODP_AUTH_ALG_NULL, - aes_ctr_reference, - ARRAY_SIZE(aes_ctr_reference), - true); -} - -static int check_alg_hmac_md5(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_MD5_HMAC); -} - -/* This test verifies the correctness of HMAC_MD5 digest operation. - * The output check length is truncated to 12 bytes (96 bits) as - * returned by the crypto operation API call. - * Note that hash digest is a one-way operation. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_gen_alg_hmac_md5(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_MD5_HMAC, - hmac_md5_reference, - ARRAY_SIZE(hmac_md5_reference), - false); -} - -static void crypto_test_check_alg_hmac_md5(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_MD5_HMAC, - hmac_md5_reference, - ARRAY_SIZE(hmac_md5_reference), - false); -} - -static int check_alg_hmac_sha1(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); -} - -/* This test verifies the correctness of HMAC_SHA1 digest operation. - * The output check length is truncated to 12 bytes (96 bits) as - * returned by the crypto operation API call. - * Note that hash digest is a one-way operation. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_gen_alg_hmac_sha1(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA1_HMAC, - hmac_sha1_reference, - ARRAY_SIZE(hmac_sha1_reference), - false); -} - -static void crypto_test_check_alg_hmac_sha1(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA1_HMAC, - hmac_sha1_reference, - ARRAY_SIZE(hmac_sha1_reference), - false); -} - -static int check_alg_hmac_sha256(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC); -} - -/* This test verifies the correctness of HMAC_SHA256 digest operation. - * The output check length is truncated to 16 bytes (128 bits) as - * returned by the crypto operation API call. - * Note that hash digest is a one-way operation. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_gen_alg_hmac_sha256(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA256_HMAC, - hmac_sha256_reference, - ARRAY_SIZE(hmac_sha256_reference), - false); -} - -static void crypto_test_check_alg_hmac_sha256(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA256_HMAC, - hmac_sha256_reference, - ARRAY_SIZE(hmac_sha256_reference), - false); -} - -static int check_alg_hmac_sha512(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); -} - -/* This test verifies the correctness of HMAC_SHA512 digest operation. - * The output check length is truncated to 32 bytes (256 bits) as - * returned by the crypto operation API call. - * Note that hash digest is a one-way operation. - * In addition the test verifies if the implementation can use the - * packet buffer as completion event buffer. - * */ -static void crypto_test_gen_alg_hmac_sha512(void) -{ - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA512_HMAC, - hmac_sha512_reference, - ARRAY_SIZE(hmac_sha512_reference), - false); -} - -static void crypto_test_check_alg_hmac_sha512(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_SHA512_HMAC, - hmac_sha512_reference, - ARRAY_SIZE(hmac_sha512_reference), - false); -} - -static int check_alg_aes_gmac(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_AES_GMAC); -} - -static void crypto_test_gen_alg_aes_gmac(void) -{ - unsigned int test_vec_num = (sizeof(aes_gmac_reference) / - sizeof(aes_gmac_reference[0])); - unsigned int i; - - for (i = 0; i < test_vec_num; i++) - check_alg(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_AES_GMAC, - aes_gmac_reference, - ARRAY_SIZE(aes_gmac_reference), - false); -} - -static void crypto_test_gen_alg_aes_gmac_ovr_iv(void) -{ - unsigned int test_vec_num = (sizeof(aes_gmac_reference) / - sizeof(aes_gmac_reference[0])); - unsigned int i; - - for (i = 0; i < test_vec_num; i++) - alg_test(ODP_CRYPTO_OP_ENCODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_AES_GMAC, - &aes_gmac_reference[i], - true); -} - -static void crypto_test_check_alg_aes_gmac(void) -{ - check_alg(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_AES_GMAC, - aes_gmac_reference, - ARRAY_SIZE(aes_gmac_reference), - false); -} - -static void crypto_test_check_alg_aes_gmac_ovr_iv(void) -{ - unsigned int test_vec_num = (sizeof(aes_gmac_reference) / - sizeof(aes_gmac_reference[0])); - unsigned int i; - - for (i = 0; i < test_vec_num; i++) - alg_test(ODP_CRYPTO_OP_DECODE, - ODP_CIPHER_ALG_NULL, - ODP_AUTH_ALG_AES_GMAC, - &aes_gmac_reference[i], - true); -} - -int crypto_suite_sync_init(void) -{ - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - suite_context.queue = ODP_QUEUE_INVALID; - suite_context.pref_mode = ODP_CRYPTO_SYNC; - return 0; -} - -int crypto_suite_async_init(void) -{ - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - suite_context.queue = odp_queue_lookup("crypto-out"); - if (suite_context.queue == ODP_QUEUE_INVALID) - return -1; - - suite_context.pref_mode = ODP_CRYPTO_ASYNC; - return 0; -} - -int crypto_suite_packet_sync_init(void) -{ - suite_context.packet = true; - suite_context.op_mode = ODP_CRYPTO_SYNC; - - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - suite_context.queue = ODP_QUEUE_INVALID; - return 0; -} - -int crypto_suite_packet_async_init(void) -{ - suite_context.packet = true; - suite_context.op_mode = ODP_CRYPTO_ASYNC; - - suite_context.pool = odp_pool_lookup("packet_pool"); - if (suite_context.pool == ODP_POOL_INVALID) - return -1; - - suite_context.queue = odp_queue_lookup("crypto-out"); - if (suite_context.queue == ODP_QUEUE_INVALID) - return -1; - return 0; -} - -odp_testinfo_t crypto_suite[] = { - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_null, - check_alg_null), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_null, - check_alg_null), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc, - check_alg_3des_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc, - check_alg_3des_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc_ovr_iv, - check_alg_3des_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc_ovr_iv, - check_alg_3des_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cbc, - check_alg_aes_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cbc, - check_alg_aes_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cbc_ovr_iv, - check_alg_aes_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cbc_ovr_iv, - check_alg_aes_cbc), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ctr, - check_alg_aes_ctr), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ctr, - check_alg_aes_ctr), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ctr_ovr_iv, - check_alg_aes_ctr), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ctr_ovr_iv, - check_alg_aes_ctr), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_gcm, - check_alg_aes_gcm), - ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_gcm_ovr_iv, - check_alg_aes_gcm), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm, - check_alg_aes_gcm), - ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm_ovr_iv, - check_alg_aes_gcm), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5, - check_alg_hmac_md5), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, - check_alg_hmac_md5), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha1, - check_alg_hmac_sha1), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha1, - check_alg_hmac_sha1), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, - check_alg_hmac_sha256), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, - check_alg_hmac_sha256), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha512, - check_alg_hmac_sha512), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha512, - check_alg_hmac_sha512), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_gmac, - check_alg_aes_gmac), - ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_gmac_ovr_iv, - check_alg_aes_gmac), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac, - check_alg_aes_gmac), - ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac_ovr_iv, - check_alg_aes_gmac), - ODP_TEST_INFO_NULL, -}; - -int crypto_suite_term(void) -{ - int i; - int first = 1; - - for (i = 0; crypto_suite[i].pName; i++) { - if (crypto_suite[i].check_active && - crypto_suite[i].check_active() == ODP_TEST_INACTIVE) { - if (first) { - first = 0; - printf("\n\n Inactive tests:\n"); - } - printf(" %s\n", crypto_suite[i].pName); - } - } - return 0; -} +/* Copyright (c) 2014-2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#include <odp_api.h> +#include <CUnit/Basic.h> +#include <odp_cunit_common.h> +#include "test_vectors.h" +#include "odp_crypto_test_inp.h" +#include "crypto.h" + +#define MAX_ALG_CAPA 32 + +struct suite_context_s { + odp_bool_t packet; + odp_crypto_op_mode_t op_mode; + odp_crypto_op_mode_t pref_mode; + odp_pool_t pool; + odp_queue_t queue; +}; + +static struct suite_context_s suite_context; + +static int packet_cmp_mem(odp_packet_t pkt, uint32_t offset, + void *s, uint32_t len) +{ + uint8_t buf[len]; + + odp_packet_copy_to_mem(pkt, offset, len, buf); + + return memcmp(buf, s, len); +} + +static const char *auth_alg_name(odp_auth_alg_t auth) +{ + switch (auth) { + case ODP_AUTH_ALG_NULL: + return "ODP_AUTH_ALG_NULL"; + case ODP_AUTH_ALG_MD5_HMAC: + return "ODP_AUTH_ALG_MD5_HMAC"; + case ODP_AUTH_ALG_SHA1_HMAC: + return "ODP_AUTH_ALG_SHA1_HMAC"; + case ODP_AUTH_ALG_SHA256_HMAC: + return "ODP_AUTH_ALG_SHA256_HMAC"; + case ODP_AUTH_ALG_SHA512_HMAC: + return "ODP_AUTH_ALG_SHA512_HMAC"; + case ODP_AUTH_ALG_AES_GCM: + return "ODP_AUTH_ALG_AES_GCM"; + case ODP_AUTH_ALG_AES_GMAC: + return "ODP_AUTH_ALG_AES_GMAC"; + default: + return "Unknown"; + } +} + +static const char *cipher_alg_name(odp_cipher_alg_t cipher) +{ + switch (cipher) { + case ODP_CIPHER_ALG_NULL: + return "ODP_CIPHER_ALG_NULL"; + case ODP_CIPHER_ALG_DES: + return "ODP_CIPHER_ALG_DES"; + case ODP_CIPHER_ALG_3DES_CBC: + return "ODP_CIPHER_ALG_3DES_CBC"; + case ODP_CIPHER_ALG_AES_CBC: + return "ODP_CIPHER_ALG_AES_CBC"; + case ODP_CIPHER_ALG_AES_GCM: + return "ODP_CIPHER_ALG_AES_GCM"; + default: + return "Unknown"; + } +} + +static int alg_op(odp_packet_t pkt, + odp_bool_t *ok, + odp_crypto_session_t session, + uint8_t *cipher_iv_ptr, + uint8_t *auth_iv_ptr, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint8_t *aad, + unsigned int plaintext_len) +{ + int rc; + odp_crypto_op_result_t result; + odp_crypto_op_param_t op_params; + odp_bool_t posted; + odp_event_subtype_t subtype; + + /* Prepare input/output params */ + memset(&op_params, 0, sizeof(op_params)); + op_params.session = session; + op_params.pkt = pkt; + op_params.out_pkt = pkt; + op_params.ctx = (void *)0xdeadbeef; + + op_params.cipher_range = *cipher_range; + op_params.auth_range = *auth_range; + if (cipher_iv_ptr) + op_params.cipher_iv_ptr = cipher_iv_ptr; + if (auth_iv_ptr) + op_params.auth_iv_ptr = auth_iv_ptr; + + op_params.aad_ptr = aad; + + op_params.hash_result_offset = plaintext_len; + + rc = odp_crypto_operation(&op_params, &posted, &result); + if (rc < 0) { + CU_FAIL("Failed odp_crypto_operation()"); + return rc; + } + + if (posted) { + odp_event_t event; + odp_crypto_compl_t compl_event; + + /* Poll completion queue for results */ + do { + event = odp_queue_deq(suite_context.queue); + } while (event == ODP_EVENT_INVALID); + + CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == odp_event_type(event)); + CU_ASSERT(ODP_EVENT_NO_SUBTYPE == odp_event_subtype(event)); + CU_ASSERT(ODP_EVENT_CRYPTO_COMPL == + odp_event_types(event, &subtype)); + CU_ASSERT(ODP_EVENT_NO_SUBTYPE == subtype); + + compl_event = odp_crypto_compl_from_event(event); + CU_ASSERT(odp_crypto_compl_to_u64(compl_event) == + odp_crypto_compl_to_u64( + odp_crypto_compl_from_event(event))); + odp_crypto_compl_result(compl_event, &result); + odp_crypto_compl_free(compl_event); + } + + CU_ASSERT(result.pkt == pkt); + CU_ASSERT(result.ctx == (void *)0xdeadbeef); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_type(odp_packet_to_event(result.pkt))); + CU_ASSERT(ODP_EVENT_PACKET_BASIC == + odp_event_subtype(odp_packet_to_event(result.pkt))); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_types(odp_packet_to_event(result.pkt), &subtype)); + CU_ASSERT(ODP_EVENT_PACKET_BASIC == subtype); + + *ok = result.ok; + + return 0; +} + +static int alg_packet_op(odp_packet_t pkt, + odp_bool_t *ok, + odp_crypto_session_t session, + uint8_t *cipher_iv_ptr, + uint8_t *auth_iv_ptr, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint8_t *aad, + unsigned int plaintext_len) +{ + int rc; + odp_crypto_packet_result_t result; + odp_crypto_packet_op_param_t op_params; + odp_event_subtype_t subtype; + odp_packet_t out_pkt = pkt; + + /* Prepare input/output params */ + memset(&op_params, 0, sizeof(op_params)); + op_params.session = session; + + op_params.cipher_range = *cipher_range; + op_params.auth_range = *auth_range; + if (cipher_iv_ptr) + op_params.cipher_iv_ptr = cipher_iv_ptr; + if (auth_iv_ptr) + op_params.auth_iv_ptr = auth_iv_ptr; + + op_params.aad_ptr = aad; + + op_params.hash_result_offset = plaintext_len; + + rc = odp_crypto_op(&pkt, &out_pkt, &op_params, 1); + if (rc < 0) { + CU_FAIL("Failed odp_crypto_packet_op()"); + return rc; + } + + CU_ASSERT(out_pkt == pkt); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_type(odp_packet_to_event(pkt))); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == + odp_event_subtype(odp_packet_to_event(pkt))); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_types(odp_packet_to_event(pkt), &subtype)); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); + + rc = odp_crypto_result(&result, pkt); + if (rc < 0) { + CU_FAIL("Failed odp_crypto_packet_result()"); + return rc; + } + + if (!result.ok) + CU_ASSERT(odp_packet_has_error(pkt)); + + *ok = result.ok; + + return 0; +} + +static int alg_packet_op_enq(odp_packet_t pkt, + odp_bool_t *ok, + odp_crypto_session_t session, + uint8_t *cipher_iv_ptr, + uint8_t *auth_iv_ptr, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, + uint8_t *aad, + unsigned int plaintext_len) +{ + int rc; + odp_event_t event; + odp_crypto_packet_result_t result; + odp_crypto_packet_op_param_t op_params; + odp_event_subtype_t subtype; + odp_packet_t out_pkt = pkt; + + /* Prepare input/output params */ + memset(&op_params, 0, sizeof(op_params)); + op_params.session = session; + + op_params.cipher_range = *cipher_range; + op_params.auth_range = *auth_range; + if (cipher_iv_ptr) + op_params.cipher_iv_ptr = cipher_iv_ptr; + if (auth_iv_ptr) + op_params.auth_iv_ptr = auth_iv_ptr; + + op_params.aad_ptr = aad; + + op_params.hash_result_offset = plaintext_len; + + rc = odp_crypto_op_enq(&pkt, &pkt, &op_params, 1); + if (rc < 0) { + CU_FAIL("Failed odp_crypto_op_enq()"); + return rc; + } + + /* Poll completion queue for results */ + do { + event = odp_queue_deq(suite_context.queue); + } while (event == ODP_EVENT_INVALID); + + CU_ASSERT(ODP_EVENT_PACKET == odp_event_type(event)); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == odp_event_subtype(event)); + CU_ASSERT(ODP_EVENT_PACKET == odp_event_types(event, &subtype)); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); + + pkt = odp_crypto_packet_from_event(event); + + CU_ASSERT(out_pkt == pkt); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_type(odp_packet_to_event(pkt))); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == + odp_event_subtype(odp_packet_to_event(pkt))); + CU_ASSERT(ODP_EVENT_PACKET == + odp_event_types(odp_packet_to_event(pkt), &subtype)); + CU_ASSERT(ODP_EVENT_PACKET_CRYPTO == subtype); + + rc = odp_crypto_result(&result, pkt); + if (rc < 0) { + CU_FAIL("Failed odp_crypto_packet_result()"); + return rc; + } + + CU_ASSERT((!odp_packet_has_error(pkt)) == result.ok); + + *ok = result.ok; + + return 0; +} + +typedef enum crypto_test { + NORMAL_TEST = 0, /**< Plain execution */ + REPEAT_TEST, /**< Rerun without reinitializing the session */ + WRONG_DIGEST_TEST, /**< Check against wrong digest */ + MAX_TEST, /**< Final mark */ +} crypto_test; + +/* Basic algorithm run function for async inplace mode. + * Creates a session from input parameters and runs one operation + * on input_vec. Checks the output of the crypto operation against + * output_vec. Operation completion event is dequeued polling the + * session output queue. Completion context pointer is retrieved + * and checked against the one set before the operation. + * Completion event can be a separate buffer or the input packet + * buffer can be used. + * */ +static void alg_test(odp_crypto_op_t op, + odp_cipher_alg_t cipher_alg, + odp_auth_alg_t auth_alg, + crypto_test_reference_t *ref, + odp_bool_t ovr_iv) +{ + odp_crypto_session_t session; + int rc; + odp_crypto_ses_create_err_t status; + odp_bool_t ok = false; + int iteration; + odp_crypto_session_param_t ses_params; + odp_packet_data_range_t cipher_range; + odp_packet_data_range_t auth_range; + odp_crypto_key_t cipher_key = { + .data = ref->cipher_key, + .length = ref->cipher_key_length + }; + odp_crypto_key_t auth_key = { + .data = ref->auth_key, + .length = ref->auth_key_length + }; + odp_crypto_iv_t cipher_iv = { + .data = ovr_iv ? NULL : ref->cipher_iv, + .length = ref->cipher_iv_length + }; + odp_crypto_iv_t auth_iv = { + .data = ovr_iv ? NULL : ref->auth_iv, + .length = ref->auth_iv_length + }; + + /* Create a crypto session */ + odp_crypto_session_param_init(&ses_params); + ses_params.op = op; + ses_params.auth_cipher_text = false; + ses_params.op_mode = suite_context.op_mode; + ses_params.pref_mode = suite_context.pref_mode; + ses_params.cipher_alg = cipher_alg; + ses_params.auth_alg = auth_alg; + ses_params.compl_queue = suite_context.queue; + ses_params.output_pool = suite_context.pool; + ses_params.cipher_key = cipher_key; + ses_params.cipher_iv = cipher_iv; + ses_params.auth_iv = auth_iv; + ses_params.auth_key = auth_key; + ses_params.auth_digest_len = ref->digest_length; + ses_params.auth_aad_len = ref->aad_length; + + rc = odp_crypto_session_create(&ses_params, &session, &status); + CU_ASSERT_FATAL(!rc); + CU_ASSERT(status == ODP_CRYPTO_SES_CREATE_ERR_NONE); + CU_ASSERT(odp_crypto_session_to_u64(session) != + odp_crypto_session_to_u64(ODP_CRYPTO_SESSION_INVALID)); + + cipher_range.offset = 0; + cipher_range.length = ref->length; + auth_range.offset = 0; + auth_range.length = ref->length; + + /* Prepare input data */ + odp_packet_t pkt = odp_packet_alloc(suite_context.pool, + ref->length + ref->digest_length); + CU_ASSERT(pkt != ODP_PACKET_INVALID); + if (pkt == ODP_PACKET_INVALID) + goto cleanup; + + for (iteration = NORMAL_TEST; iteration < MAX_TEST; iteration++) { + /* checking against wrong digest is meaningless for NULL digest + * or when generating digest */ + if (iteration == WRONG_DIGEST_TEST && + (auth_alg == ODP_AUTH_ALG_NULL || + op == ODP_CRYPTO_OP_ENCODE)) + continue; + + if (op == ODP_CRYPTO_OP_ENCODE) { + odp_packet_copy_from_mem(pkt, 0, ref->length, + ref->plaintext); + } else { + odp_packet_copy_from_mem(pkt, 0, ref->length, + ref->ciphertext); + odp_packet_copy_from_mem(pkt, ref->length, + ref->digest_length, + ref->digest); + if (iteration == WRONG_DIGEST_TEST) { + uint8_t byte = ~ref->digest[0]; + + odp_packet_copy_from_mem(pkt, ref->length, + 1, &byte); + } + } + + if (!suite_context.packet) + rc = alg_op(pkt, &ok, session, + ovr_iv ? ref->cipher_iv : NULL, + ovr_iv ? ref->auth_iv : NULL, + &cipher_range, &auth_range, + ref->aad, ref->length); + else if (ODP_CRYPTO_ASYNC == suite_context.op_mode) + rc = alg_packet_op_enq(pkt, &ok, session, + ovr_iv ? ref->cipher_iv : NULL, + ovr_iv ? ref->auth_iv : NULL, + &cipher_range, &auth_range, + ref->aad, ref->length); + else + rc = alg_packet_op(pkt, &ok, session, + ovr_iv ? ref->cipher_iv : NULL, + ovr_iv ? ref->auth_iv : NULL, + &cipher_range, &auth_range, + ref->aad, ref->length); + if (rc < 0) + break; + + if (iteration == WRONG_DIGEST_TEST) { + CU_ASSERT(!ok); + continue; + } + + CU_ASSERT(ok); + + if (op == ODP_CRYPTO_OP_ENCODE) { + CU_ASSERT(!packet_cmp_mem(pkt, 0, + ref->ciphertext, + ref->length)); + CU_ASSERT(!packet_cmp_mem(pkt, ref->length, + ref->digest, + ref->digest_length)); + } else { + CU_ASSERT(!packet_cmp_mem(pkt, 0, + ref->plaintext, + ref->length)); + } + } + + odp_packet_free(pkt); + +cleanup: + rc = odp_crypto_session_destroy(session); + CU_ASSERT(!rc); +} + +static void check_alg(odp_crypto_op_t op, + odp_cipher_alg_t cipher_alg, + odp_auth_alg_t auth_alg, + crypto_test_reference_t *ref, + size_t count, + odp_bool_t ovr_iv) +{ + odp_crypto_capability_t capa; + odp_crypto_cipher_capability_t cipher_capa[MAX_ALG_CAPA]; + odp_crypto_auth_capability_t auth_capa[MAX_ALG_CAPA]; + int rc, cipher_num, auth_num, i; + odp_bool_t cipher_tested[MAX_ALG_CAPA]; + odp_bool_t auth_tested[MAX_ALG_CAPA]; + odp_bool_t cipher_ok = false; + odp_bool_t auth_ok = false; + size_t idx; + + rc = odp_crypto_capability(&capa); + CU_ASSERT(!rc); + + if (cipher_alg == ODP_CIPHER_ALG_3DES_CBC && + !(capa.ciphers.bit.trides_cbc)) + rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_AES_CBC && + !(capa.ciphers.bit.aes_cbc)) + rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_AES_CTR && + !(capa.ciphers.bit.aes_ctr)) + rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_AES_GCM && + !(capa.ciphers.bit.aes_gcm)) + rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_DES && + !(capa.ciphers.bit.des)) + rc = -1; + if (cipher_alg == ODP_CIPHER_ALG_NULL && + !(capa.ciphers.bit.null)) + rc = -1; + + CU_ASSERT(!rc); + CU_ASSERT((~capa.ciphers.all_bits & capa.hw_ciphers.all_bits) == 0); + + if (auth_alg == ODP_AUTH_ALG_AES_GCM && + !(capa.auths.bit.aes_gcm)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_AES_GMAC && + !(capa.auths.bit.aes_gmac)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_MD5_HMAC && + !(capa.auths.bit.md5_hmac)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_NULL && + !(capa.auths.bit.null)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_SHA1_HMAC && + !(capa.auths.bit.sha1_hmac)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC && + !(capa.auths.bit.sha256_hmac)) + rc = -1; + if (auth_alg == ODP_AUTH_ALG_SHA512_HMAC && + !(capa.auths.bit.sha512_hmac)) + rc = -1; + + CU_ASSERT(!rc); + CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0); + + cipher_num = odp_crypto_cipher_capability(cipher_alg, cipher_capa, + MAX_ALG_CAPA); + + CU_ASSERT(cipher_num > 0); + CU_ASSERT(cipher_num <= MAX_ALG_CAPA); + if (cipher_num > MAX_ALG_CAPA) + cipher_num = MAX_ALG_CAPA; + + auth_num = odp_crypto_auth_capability(auth_alg, auth_capa, + MAX_ALG_CAPA); + + CU_ASSERT(auth_num > 0); + CU_ASSERT(auth_num <= MAX_ALG_CAPA); + if (auth_num > MAX_ALG_CAPA) + auth_num = MAX_ALG_CAPA; + + memset(cipher_tested, 0, sizeof(cipher_tested)); + memset(auth_tested, 0, sizeof(auth_tested)); + + for (idx = 0; idx < count; idx++) { + int cipher_idx = -1, auth_idx = -1; + + for (i = 0; i < cipher_num; i++) { + if (cipher_capa[i].key_len == + ref[idx].cipher_key_length && + cipher_capa[i].iv_len == + ref[idx].cipher_iv_length) { + cipher_idx = i; + break; + } + } + + if (cipher_idx < 0) { + printf("\n Unsupported: alg=%s, key_len=%" PRIu32 + ", iv_len=%" PRIu32 "\n", + cipher_alg_name(cipher_alg), + ref[idx].cipher_key_length, + ref[idx].cipher_iv_length); + continue; + } + + for (i = 0; i < auth_num; i++) { + if (auth_capa[i].digest_len == + ref[idx].digest_length && + auth_capa[i].iv_len == + ref[idx].auth_iv_length && + auth_capa[i].key_len == + ref[idx].auth_key_length) { + auth_idx = i; + break; + } + } + + if (auth_idx < 0) { + printf("\n Unsupported: alg=%s, key_len=%" PRIu32 + ", iv_len=%" PRIu32 ", digest_len=%" PRIu32 "\n", + auth_alg_name(auth_alg), + ref[idx].auth_key_length, + ref[idx].auth_iv_length, + ref[idx].digest_length); + continue; + } + + alg_test(op, cipher_alg, auth_alg, &ref[idx], ovr_iv); + + cipher_tested[cipher_idx] = true; + auth_tested[auth_idx] = true; + } + + for (i = 0; i < cipher_num; i++) { + cipher_ok |= cipher_tested[i]; + if (!cipher_tested[i]) { + /* GMAC-related hacks */ + if (cipher_alg == ODP_CIPHER_ALG_NULL) + continue; + printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " + "iv_len=%" PRIu32 "\n", + cipher_alg_name(cipher_alg), + cipher_capa[i].key_len, + cipher_capa[i].iv_len); + } + } + + for (i = 0; i < auth_num; i++) { + auth_ok |= auth_tested[i]; + if (!auth_tested[i]) + printf("\n Untested: alg=%s, key_len=%" PRIu32 ", " + "digest_len=%" PRIu32 "\n", + auth_alg_name(auth_alg), + auth_capa[i].key_len, + auth_capa[i].digest_len); + } + + /* Verify that we were able to run at least several tests */ + CU_ASSERT(cipher_ok); + CU_ASSERT(auth_ok); +} + +/** + * Check if given cipher and authentication algorithms are supported + * + * @param cipher Cipher algorithm + * @param auth Authentication algorithm + * + * @retval ODP_TEST_ACTIVE when both algorithms are supported + * @retval ODP_TEST_INACTIVE when either algorithm is not supported + */ +static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) +{ + odp_crypto_capability_t capability; + + if (odp_crypto_capability(&capability)) + return ODP_TEST_INACTIVE; + + if (suite_context.packet) { + if (suite_context.op_mode == ODP_CRYPTO_SYNC && + capability.sync_mode == ODP_SUPPORT_NO) + return ODP_TEST_INACTIVE; + if (suite_context.op_mode == ODP_CRYPTO_ASYNC && + capability.async_mode == ODP_SUPPORT_NO) + return ODP_TEST_INACTIVE; + } + + /* Cipher algorithms */ + switch (cipher) { + case ODP_CIPHER_ALG_NULL: + if (!capability.ciphers.bit.null) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_DES: + if (!capability.ciphers.bit.des) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_3DES_CBC: + if (!capability.ciphers.bit.trides_cbc) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_AES_CBC: + if (!capability.ciphers.bit.aes_cbc) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_AES_CTR: + if (!capability.ciphers.bit.aes_ctr) + return ODP_TEST_INACTIVE; + break; + case ODP_CIPHER_ALG_AES_GCM: + if (!capability.ciphers.bit.aes_gcm) + return ODP_TEST_INACTIVE; + break; + default: + fprintf(stderr, "Unsupported cipher algorithm\n"); + return ODP_TEST_INACTIVE; + } + + /* Authentication algorithms */ + switch (auth) { + case ODP_AUTH_ALG_NULL: + if (!capability.auths.bit.null) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_MD5_HMAC: + if (!capability.auths.bit.md5_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA1_HMAC: + if (!capability.auths.bit.sha1_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA256_HMAC: + if (!capability.auths.bit.sha256_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_SHA512_HMAC: + if (!capability.auths.bit.sha512_hmac) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_AES_GCM: + if (!capability.auths.bit.aes_gcm) + return ODP_TEST_INACTIVE; + break; + case ODP_AUTH_ALG_AES_GMAC: + if (!capability.auths.bit.aes_gmac) + return ODP_TEST_INACTIVE; + break; + default: + fprintf(stderr, "Unsupported authentication algorithm\n"); + return ODP_TEST_INACTIVE; + } + + return ODP_TEST_ACTIVE; +} + +static int check_alg_null(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL); +} + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +static void crypto_test_enc_alg_null(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_NULL, + null_reference, + ARRAY_SIZE(null_reference), + false); +} + +static void crypto_test_dec_alg_null(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_NULL, + null_reference, + ARRAY_SIZE(null_reference), + false); +} + +static int check_alg_3des_cbc(void) +{ + return check_alg_support(ODP_CIPHER_ALG_3DES_CBC, ODP_AUTH_ALG_NULL); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +static void crypto_test_enc_alg_3des_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_3DES_CBC, + ODP_AUTH_ALG_NULL, + tdes_cbc_reference, + ARRAY_SIZE(tdes_cbc_reference), + false); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for 3DES_CBC algorithm. IV for the operation is the operation IV. + * */ +static void crypto_test_enc_alg_3des_cbc_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_3DES_CBC, + ODP_AUTH_ALG_NULL, + tdes_cbc_reference, + ARRAY_SIZE(tdes_cbc_reference), + true); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_3des_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_3DES_CBC, + ODP_AUTH_ALG_NULL, + tdes_cbc_reference, + ARRAY_SIZE(tdes_cbc_reference), + false); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_3des_cbc_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_3DES_CBC, + ODP_AUTH_ALG_NULL, + tdes_cbc_reference, + ARRAY_SIZE(tdes_cbc_reference), + true); +} + +static int check_alg_aes_gcm(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_GCM, ODP_AUTH_ALG_AES_GCM); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_GCM algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +static void crypto_test_enc_alg_aes_gcm(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_GCM, + ODP_AUTH_ALG_AES_GCM, + aes_gcm_reference, + ARRAY_SIZE(aes_gcm_reference), + false); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_GCM algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +static void crypto_test_enc_alg_aes_gcm_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_GCM, + ODP_AUTH_ALG_AES_GCM, + aes_gcm_reference, + ARRAY_SIZE(aes_gcm_reference), + true); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_gcm(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_GCM, + ODP_AUTH_ALG_AES_GCM, + aes_gcm_reference, + ARRAY_SIZE(aes_gcm_reference), + false); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for 3DES_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_gcm_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_GCM, + ODP_AUTH_ALG_AES_GCM, + aes_gcm_reference, + ARRAY_SIZE(aes_gcm_reference), + true); +} + +static int check_alg_aes_cbc(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CBC, ODP_AUTH_ALG_NULL); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_CBC algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +static void crypto_test_enc_alg_aes_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CBC, + ODP_AUTH_ALG_NULL, + aes_cbc_reference, + ARRAY_SIZE(aes_cbc_reference), + false); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_CBC algorithm. IV for the operation is the operation IV. + * */ +static void crypto_test_enc_alg_aes_cbc_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CBC, + ODP_AUTH_ALG_NULL, + aes_cbc_reference, + ARRAY_SIZE(aes_cbc_reference), + true); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for AES128_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_cbc(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CBC, + ODP_AUTH_ALG_NULL, + aes_cbc_reference, + ARRAY_SIZE(aes_cbc_reference), + false); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for AES128_CBC algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_cbc_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CBC, + ODP_AUTH_ALG_NULL, + aes_cbc_reference, + ARRAY_SIZE(aes_cbc_reference), + true); +} + +static int check_alg_aes_ctr(void) +{ + return check_alg_support(ODP_CIPHER_ALG_AES_CTR, ODP_AUTH_ALG_NULL); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_CTR algorithm. IV for the operation is the session IV. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer.*/ +static void crypto_test_enc_alg_aes_ctr(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CTR, + ODP_AUTH_ALG_NULL, + aes_ctr_reference, + ARRAY_SIZE(aes_ctr_reference), + false); +} + +/* This test verifies the correctness of encode (plaintext -> ciphertext) + * operation for AES128_CTR algorithm. IV for the operation is the operation IV. + * */ +static void crypto_test_enc_alg_aes_ctr_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_AES_CTR, + ODP_AUTH_ALG_NULL, + aes_ctr_reference, + ARRAY_SIZE(aes_ctr_reference), + true); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for AES128_CTR algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_ctr(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CTR, + ODP_AUTH_ALG_NULL, + aes_ctr_reference, + ARRAY_SIZE(aes_ctr_reference), + false); +} + +/* This test verifies the correctness of decode (ciphertext -> plaintext) + * operation for AES128_CTR algorithm. IV for the operation is the session IV + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_dec_alg_aes_ctr_ovr_iv(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_AES_CTR, + ODP_AUTH_ALG_NULL, + aes_ctr_reference, + ARRAY_SIZE(aes_ctr_reference), + true); +} + +static int check_alg_hmac_md5(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_MD5_HMAC); +} + +/* This test verifies the correctness of HMAC_MD5 digest operation. + * The output check length is truncated to 12 bytes (96 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_gen_alg_hmac_md5(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_MD5_HMAC, + hmac_md5_reference, + ARRAY_SIZE(hmac_md5_reference), + false); +} + +static void crypto_test_check_alg_hmac_md5(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_MD5_HMAC, + hmac_md5_reference, + ARRAY_SIZE(hmac_md5_reference), + false); +} + +static int check_alg_hmac_sha1(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); +} + +/* This test verifies the correctness of HMAC_SHA1 digest operation. + * The output check length is truncated to 12 bytes (96 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_gen_alg_hmac_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA1_HMAC, + hmac_sha1_reference, + ARRAY_SIZE(hmac_sha1_reference), + false); +} + +static void crypto_test_check_alg_hmac_sha1(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA1_HMAC, + hmac_sha1_reference, + ARRAY_SIZE(hmac_sha1_reference), + false); +} + +static int check_alg_hmac_sha256(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC); +} + +/* This test verifies the correctness of HMAC_SHA256 digest operation. + * The output check length is truncated to 16 bytes (128 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_gen_alg_hmac_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA256_HMAC, + hmac_sha256_reference, + ARRAY_SIZE(hmac_sha256_reference), + false); +} + +static void crypto_test_check_alg_hmac_sha256(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA256_HMAC, + hmac_sha256_reference, + ARRAY_SIZE(hmac_sha256_reference), + false); +} + +static int check_alg_hmac_sha512(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); +} + +/* This test verifies the correctness of HMAC_SHA512 digest operation. + * The output check length is truncated to 32 bytes (256 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +static void crypto_test_gen_alg_hmac_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA512_HMAC, + hmac_sha512_reference, + ARRAY_SIZE(hmac_sha512_reference), + false); +} + +static void crypto_test_check_alg_hmac_sha512(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_SHA512_HMAC, + hmac_sha512_reference, + ARRAY_SIZE(hmac_sha512_reference), + false); +} + +static int check_alg_aes_gmac(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_AES_GMAC); +} + +static void crypto_test_gen_alg_aes_gmac(void) +{ + unsigned int test_vec_num = (sizeof(aes_gmac_reference) / + sizeof(aes_gmac_reference[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) + check_alg(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_GMAC, + aes_gmac_reference, + ARRAY_SIZE(aes_gmac_reference), + false); +} + +static void crypto_test_gen_alg_aes_gmac_ovr_iv(void) +{ + unsigned int test_vec_num = (sizeof(aes_gmac_reference) / + sizeof(aes_gmac_reference[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) + alg_test(ODP_CRYPTO_OP_ENCODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_GMAC, + &aes_gmac_reference[i], + true); +} + +static void crypto_test_check_alg_aes_gmac(void) +{ + check_alg(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_GMAC, + aes_gmac_reference, + ARRAY_SIZE(aes_gmac_reference), + false); +} + +static void crypto_test_check_alg_aes_gmac_ovr_iv(void) +{ + unsigned int test_vec_num = (sizeof(aes_gmac_reference) / + sizeof(aes_gmac_reference[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) + alg_test(ODP_CRYPTO_OP_DECODE, + ODP_CIPHER_ALG_NULL, + ODP_AUTH_ALG_AES_GMAC, + &aes_gmac_reference[i], + true); +} + +int crypto_suite_sync_init(void) +{ + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + suite_context.queue = ODP_QUEUE_INVALID; + suite_context.pref_mode = ODP_CRYPTO_SYNC; + return 0; +} + +int crypto_suite_async_init(void) +{ + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + suite_context.queue = odp_queue_lookup("crypto-out"); + if (suite_context.queue == ODP_QUEUE_INVALID) + return -1; + + suite_context.pref_mode = ODP_CRYPTO_ASYNC; + return 0; +} + +int crypto_suite_packet_sync_init(void) +{ + suite_context.packet = true; + suite_context.op_mode = ODP_CRYPTO_SYNC; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + suite_context.queue = ODP_QUEUE_INVALID; + return 0; +} + +int crypto_suite_packet_async_init(void) +{ + suite_context.packet = true; + suite_context.op_mode = ODP_CRYPTO_ASYNC; + + suite_context.pool = odp_pool_lookup("packet_pool"); + if (suite_context.pool == ODP_POOL_INVALID) + return -1; + + suite_context.queue = odp_queue_lookup("crypto-out"); + if (suite_context.queue == ODP_QUEUE_INVALID) + return -1; + return 0; +} + +odp_testinfo_t crypto_suite[] = { + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_null, + check_alg_null), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_null, + check_alg_null), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc_ovr_iv, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc_ovr_iv, + check_alg_3des_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cbc, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cbc, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_cbc_ovr_iv, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_cbc_ovr_iv, + check_alg_aes_cbc), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ctr, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ctr, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_ctr_ovr_iv, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_ctr_ovr_iv, + check_alg_aes_ctr), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_gcm, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_aes_gcm_ovr_iv, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes_gcm_ovr_iv, + check_alg_aes_gcm), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5, + check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, + check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha1, + check_alg_hmac_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha1, + check_alg_hmac_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, + check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, + check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha512, + check_alg_hmac_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha512, + check_alg_hmac_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_gmac, + check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_aes_gmac_ovr_iv, + check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac, + check_alg_aes_gmac), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_aes_gmac_ovr_iv, + check_alg_aes_gmac), + ODP_TEST_INFO_NULL, +}; + +int crypto_suite_term(void) +{ + int i; + int first = 1; + + for (i = 0; crypto_suite[i].pName; i++) { + if (crypto_suite[i].check_active && + crypto_suite[i].check_active() == ODP_TEST_INACTIVE) { + if (first) { + first = 0; + printf("\n\n Inactive tests:\n"); + } + printf(" %s\n", crypto_suite[i].pName); + } + } + return 0; +}
commit 5f4692a06e9241411ccba088142782638f1f9f96 Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Wed Jan 24 08:02:26 2018 +0300
api: crypto: add ChaCha20-Poly1305 support
ChaCha20-Poly1305 is a promising AEAD algorithm. Add decarations to support it.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 421080c2..b7ab5362 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -101,6 +101,15 @@ typedef enum { */ ODP_CIPHER_ALG_AES_CCM,
+ /** ChaCha20-Poly1305 + * + * ChaCha20 with Poly1305 provide both authentication and ciphering of + * data (authenticated encryption) in the same operation. Hence this + * algorithm must be paired always with ODP_AUTH_ALG_CHACHA20_POLY1305 + * authentication. + */ + ODP_CIPHER_ALG_CHACHA20_POLY1305, + /** @deprecated Use ODP_CIPHER_ALG_AES_CBC instead */ ODP_DEPRECATE(ODP_CIPHER_ALG_AES128_CBC),
@@ -183,6 +192,15 @@ typedef enum { */ ODP_AUTH_ALG_AES_CMAC,
+ /** ChaCha20-Poly1305 AEAD + * + * ChaCha20 with Poly1305 provide both authentication and ciphering of + * data (authenticated encryption) in the same operation. Hence this + * algorithm must be paired always with + * ODP_CIPHER_ALG_CHACHA20_POLY1305 cipher. + */ + ODP_AUTH_ALG_CHACHA20_POLY1305, + /** @deprecated Use ODP_AUTH_ALG_MD5_HMAC instead */ ODP_DEPRECATE(ODP_AUTH_ALG_MD5_96),
@@ -221,6 +239,9 @@ typedef union odp_crypto_cipher_algos_t { /** ODP_CIPHER_ALG_AES_CCM */ uint32_t aes_ccm : 1;
+ /** ODP_CIPHER_ALG_CHACHA20_POLY1305 */ + uint32_t chacha20_poly1305 : 1; + /** @deprecated Use aes_cbc instead */ uint32_t ODP_DEPRECATE(aes128_cbc) : 1;
@@ -269,6 +290,9 @@ typedef union odp_crypto_auth_algos_t { /** ODP_AUTH_ALG_AES_CMAC*/ uint32_t aes_cmac : 1;
+ /** ODP_AUTH_ALG_CHACHA20_POLY1305 */ + uint32_t chacha20_poly1305 : 1; + /** @deprecated Use md5_hmac instead */ uint32_t ODP_DEPRECATE(md5_96) : 1;
commit 1b2c9fb5cb2a64a6ca0c623173dea966f45c5e4a Author: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Date: Sat Jan 27 03:57:16 2018 +0300
api: crypto: add enumeration for AES-CMAC
Add enumeration for AES CMAC authentication algorithm.
Signed-off-by: Dmitry Eremin-Solenikov dmitry.ereminsolenikov@linaro.org Reviewed-by: Bill Fischofer bill.fischofer@linaro.org Reviewed-by: Petri Savolainen petri.savolainen@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index b8c7b9d8..421080c2 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -175,6 +175,14 @@ typedef enum { */ ODP_AUTH_ALG_AES_CCM,
+ /** AES-CMAC + * + * AES Cipher-based Message Authentication Code (CMAC) algorithm. CMAC + * is a keyed hash function that is based on a symmetric key block + * cipher, such as the AES. + */ + ODP_AUTH_ALG_AES_CMAC, + /** @deprecated Use ODP_AUTH_ALG_MD5_HMAC instead */ ODP_DEPRECATE(ODP_AUTH_ALG_MD5_96),
@@ -258,6 +266,9 @@ typedef union odp_crypto_auth_algos_t { /** ODP_AUTH_ALG_AES_CCM */ uint32_t aes_ccm : 1;
+ /** ODP_AUTH_ALG_AES_CMAC*/ + uint32_t aes_cmac : 1; + /** @deprecated Use md5_hmac instead */ uint32_t ODP_DEPRECATE(md5_96) : 1;
-----------------------------------------------------------------------
Summary of changes: include/odp/api/abi-default/packet.h | 28 + include/odp/api/spec/crypto.h | 35 + include/odp/api/spec/ipsec.h | 152 +- include/odp/api/spec/packet.h | 95 + .../linux-generic/include-abi/odp/api/abi/packet.h | 28 + platform/linux-generic/odp_crypto.c | 449 +++- platform/linux-generic/odp_ipsec.c | 3 +- platform/linux-generic/odp_ipsec_sad.c | 12 + test/validation/api/crypto/odp_crypto_test_inp.c | 2775 +++++++++++--------- test/validation/api/crypto/test_vectors.h | 395 ++- test/validation/api/crypto/test_vectors_len.h | 44 +- test/validation/api/ipsec/ipsec.c | 14 + test/validation/api/ipsec/ipsec.h | 1 + test/validation/api/ipsec/ipsec_test_in.c | 33 + test/validation/api/ipsec/ipsec_test_out.c | 48 +- test/validation/api/ipsec/test_vectors.h | 66 + 16 files changed, 2774 insertions(+), 1404 deletions(-)
hooks/post-receive