[dpdk-dev] [RFC] specifications for asymmetric crypto algorithms

Umesh Kartha Umesh.Kartha at caviumnetworks.com
Wed Mar 22 11:16:42 CET 2017


This RFC contains specifications for asymmetric crypto algorithms.
Asymmetric crypto algorithms are essential part of protocols such as
SSL/TLS. As the current DPDK crypto library lacks support for asymmetric
crypto algorithms, this RFC is an attempt to address it.

Cavium offers  PCI hardware accelerators that supports symmetric and
asymmetric crypto algorithms, of which a few are  addressed in this RFC.
Once specifications are agreed upon, I can submit a patch for the same.
We will develop a poll mode driver which can offload to OpenSSL crypto
library and to Cavium crypto accelerator.

The asymmetric crypto algorithms supported in this version are:

1 RSA
  - RSA Sign
  - RSA Verify
  - RSA Public Encrypt
  - RSA Private Decrypt

  Padding schemes supported for RSA operations are
    * RSA PKCS#1 BT1
    * RSA PKCS#1 BT2
    * RSA PKCS#1 OAEP
    * RSA PKCS#1 PSS

2  ECDSA
  - ECDSA Sign
  - ECDSA Verify

  Curves supported for ECDSA operations are
    * Prime192v1
    * Secp224k1
    * Prime256v1
    * Secp384r1
    * Secp521r1

3  MODEXP

4  FUNDAMENTAL ECC
  - Point Addition
  - Point Multiplication
  - Point Doubling

   Curves supported for fundamental ECC operations are same as that of
   ECDSA operations.

 Asymmetric crypto transform operations support both session oriented
mode (WIP) and session less mode. If the operation is sessionless, an
asymmetric crypto transform structure, containing immutable parameters,
is passed along with per-operation mutable parameters in the structure.
Specific structures were written to contain immutable parameters
depending on algorithm used for crypto transform operation. The
parameters and type of transform is distinguished by the algorithm for
which the transform structure is filled. For a particular asymmetric
algorithm, not all parameters will be used and hence not required to be
filled.

 Unlike symmetric operations, asymmetric operations can have more than
one resultant component for a single transform. Hence, only for select
operation types do we use destination mbuf structure passed along with
other operation parameters. The lengths of input and output parameters
are fixed and short. Depending on the algorithm, the number of inputs to
crypto transform operation, both mutable and immutable parameters,
vary. Depending on the algorithm, the type of data expected at source
mbuf varies and has been described.

---
 lib/librte_cryptodev/rte_crypto.h      | 135 ++++-
 lib/librte_cryptodev/rte_crypto_asym.h | 881 +++++++++++++++++++++++++++++++++
 2 files changed, 1013 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_cryptodev/rte_crypto_asym.h

diff --git lib/librte_cryptodev/rte_crypto.h lib/librte_cryptodev/rte_crypto.h
index 9019518..a8720bf 100644
--- lib/librte_cryptodev/rte_crypto.h
+++ lib/librte_cryptodev/rte_crypto.h
@@ -51,6 +51,7 @@
 #include <rte_common.h>
 
 #include "rte_crypto_sym.h"
+#include "rte_crypto_asym.h"
 
 /** Crypto operation types */
 enum rte_crypto_op_type {
@@ -58,6 +59,8 @@ enum rte_crypto_op_type {
 	/**< Undefined operation type */
 	RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 	/**< Symmetric operation */
+	RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+	/**< Asymmetric operation */
 };
 
 /** Status of crypto operation */
@@ -75,6 +78,29 @@ enum rte_crypto_op_status {
 	 * Symmetric operation failed due to invalid session arguments, or if
 	 * in session-less mode, failed to allocate private operation material.
 	 */
+	RTE_CRYPTO_OP_STATUS_RSA_DATA_TOO_LARGE,
+	/**< Length of data to be encrypted/signed is too large */
+	RTE_CRYPTO_OP_STATUS_PKCS_DECRYPT_FAILED,
+	/**<
+	 * PKCS decrypt operation failed due to bad padding.
+	 */
+	RTE_CRYPTO_OP_STATUS_RSA_VERIFY_FAILED,
+	/**<
+	 * PKCS RSA signature verification failed.
+	 */
+	RTE_CRYPTO_OP_STATUS_ECDSA_INVALID_SIGNATURE,
+	/**<
+	 * ECDSA signature generation failed due to either ECDSA_SIGN->r or
+	 * ECDSA_SIGN->s component being invalid.
+	 */
+	RTE_CRYPTO_OP_STATUS_ECDSA_VERIFY_FAILED,
+	/**<
+	 * ECDSA signature verification failed.
+	 */
+	RTE_CRYPTO_OP_STATUS_ECC_POINT_AT_INFINITY,
+	/**<
+	 * ECC Operation failed due to point at infinity
+	 */
 	RTE_CRYPTO_OP_STATUS_INVALID_ARGS,
 	/**< Operation failed due to invalid arguments in request */
 	RTE_CRYPTO_OP_STATUS_ERROR,
@@ -116,6 +142,8 @@ struct rte_crypto_op {
 	union {
 		struct rte_crypto_sym_op *sym;
 		/**< Symmetric operation parameters */
+		struct rte_crypto_asym_op *asym;
+		/**< Asymmetric operation parameters */
 	}; /**< operation specific parameters */
 } __rte_cache_aligned;
 
@@ -141,6 +169,14 @@ struct rte_crypto_op {
 
 		__rte_crypto_sym_op_reset(op->sym);
 		break;
+	case RTE_CRYPTO_OP_TYPE_ASYMMETRIC:
+		/** Asymmetric operation structure starts after the end of the
+		 * rte_crypto_op strucutre.
+		 */
+		op->asym = (struct rte_crypto_asym_op *)(op + 1);
+		op->type = type;
+
+		__rte_crypto_asym_op_reset(op->asym);
 	default:
 		break;
 	}
@@ -303,13 +339,25 @@ struct rte_crypto_op_pool_private {
 __rte_crypto_op_get_priv_data(struct rte_crypto_op *op, uint32_t size)
 {
 	uint32_t priv_size;
+	int type = op->type;
 
 	if (likely(op->mempool != NULL)) {
 		priv_size = __rte_crypto_op_get_priv_data_size(op->mempool);
 
-		if (likely(priv_size >= size))
-			return (void *)((uint8_t *)(op + 1) +
+		if (likely(priv_size >= size)) {
+			switch (type) {
+			case RTE_CRYPTO_OP_TYPE_SYMMETRIC:
+				return (void *)((uint8_t *)(op + 1) +
 					sizeof(struct rte_crypto_sym_op));
+				break;
+			case RTE_CRYPTO_OP_TYPE_ASYMMETRIC:
+				return (void *)((uint8_t *)(op + 1) +
+					sizeof(struct rte_crypto_asym_op));
+				break;
+			default:
+				break;
+			}
+		}
 	}
 
 	return NULL;
@@ -320,7 +368,7 @@ struct rte_crypto_op_pool_private {
  * If operation has been allocate from a rte_mempool, then the operation will
  * be returned to the mempool.
  *
- * @param	op	symmetric crypto operation
+ * @param	op	 crypto operation
  */
 static inline void
 rte_crypto_op_free(struct rte_crypto_op *op)
@@ -410,6 +458,87 @@ struct rte_crypto_op_pool_private {
 	return __rte_crypto_sym_op_attach_sym_session(op->sym, sess);
 }
 
+/**
+ * Allocate an asymmetric crypto operation in the private data of an mbuf.
+ *
+ * @param	m	mbuf which is associated with the crypto operation, the
+ *			operation will be allocated in the private data of that
+ *			mbuf.
+ *
+ * @returns
+ * - On success returns a pointer to the crypto operation.
+ * - On failure returns NULL.
+ */
+static inline struct rte_crypto_op *
+rte_crypto_asym_op_alloc_from_mbuf_priv_data(struct rte_mbuf *m)
+{
+	if (unlikely(m == NULL))
+		return NULL;
+
+	/*
+	 * check that the mbuf's private data size is sufficient to contain a
+	 * crypto operation
+	 */
+	if (unlikely(m->priv_size < (sizeof(struct rte_crypto_op) +
+			sizeof(struct rte_crypto_asym_op))))
+		return NULL;
+
+	/* private data starts immediately after the mbuf header in the mbuf. */
+	struct rte_crypto_op *op = (struct rte_crypto_op *)(m + 1);
+
+	__rte_crypto_op_reset(op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	op->mempool = NULL;
+	op->asym->m_src = m;
+
+	return op;
+}
+
+/**
+ * Allocate space for asymmetric crypto xforms in the private data space of the
+ * crypto operation. This also defaults the crypto xform type and configures
+ * the chaining of the xforms in the crypto operation
+ *
+ * @return
+ * - On success returns pointer to first crypto xform in crypto operations chain
+ * - On failure returns NULL
+ */
+static inline struct rte_crypto_asym_xform *
+rte_crypto_op_asym_xforms_alloc(struct rte_crypto_op *op, uint8_t nb_xforms)
+{
+	void *priv_data;
+	uint32_t size;
+
+	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC))
+		return NULL;
+
+	size = sizeof(struct rte_crypto_asym_xform) * nb_xforms;
+
+	priv_data = __rte_crypto_op_get_priv_data(op, size);
+	if (priv_data == NULL)
+		return NULL;
+
+	return __rte_crypto_asym_op_asym_xforms_alloc(op->asym, priv_data,
+			nb_xforms);
+}
+
+
+/**
+ * Attach a session to a crypto operation
+ *
+ * @param	op	crypto operation, must be of type asymmetric
+ * @param	sess	cryptodev session
+ */
+static inline int
+rte_crypto_op_attach_asym_session(struct rte_crypto_op *op,
+		struct rte_cryptodev_asym_session *sess)
+{
+	if (unlikely(op->type != RTE_CRYPTO_OP_TYPE_ASYMMETRIC))
+		return -1;
+
+	return __rte_crypto_asym_op_attach_asym_session(op->asym, sess);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git lib/librte_cryptodev/rte_crypto_asym.h lib/librte_cryptodev/rte_crypto_asym.h
new file mode 100644
index 0000000..9dfd579
--- /dev/null
+++ lib/librte_cryptodev/rte_crypto_asym.h
@@ -0,0 +1,881 @@
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright (C) Cavium Networks Ltd. 2017.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Cavium Networks nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_CRYPTO_ASYM_H_
+#define _RTE_CRYPTO_ASYM_H_
+
+/**
+ * @file rte_crypto_asym.h
+ *
+ * RTE Definitions for Asymmetric Cryptography
+ *
+ * Defines asymmetric algorithms and modes, as well as supported
+ * asymmetric crypto operations.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+#include <stdint.h>
+#include <rte_mbuf.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_common.h>
+#include "rte_crypto_sym.h"
+
+/** Asymmetric crypto transformation types */
+enum rte_crypto_asym_xform_type {
+	RTE_CRYPTO_ASYM_XFORM_NOT_SPECIFIED = 0,
+	RTE_CRYPTO_ASYM_XFORM_RSA,
+	RTE_CRYPTO_ASYM_XFORM_MODEX,
+	RTE_CRYPTO_ASYM_XFORM_ECDSA,
+	RTE_CRYPTO_ASYM_XFORM_FECC,
+	RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+};
+
+/**
+ * RSA operation type variants
+ */
+enum rte_crypto_rsa_optype {
+	RTE_CRYPTO_RSA_OP_NOT_SPECIFIED = 1,
+	/**< RSA operation unspecified */
+	RTE_CRYPTO_RSA_OP_PUBLIC_ENCRYPT,
+	/**< RSA public encrypt operation */
+	RTE_CRYPTO_RSA_OP_PRIVATE_DECRYPT,
+	/**< RSA private decrypt operation */
+	RTE_CRYPTO_RSA_OP_SIGN,
+	/**< RSA private key signature operation */
+	RTE_CRYPTO_RSA_OP_VERIFY,
+	/**< RSA public key verification operation */
+	RTE_CRYPTO_RSA_OP_LIST_END
+};
+
+/**
+ * Modular exponentiaion operation type variants
+ */
+enum rte_crypto_modex_optype {
+	RTE_CRYPTO_MODEX_OP_NOT_SPECIFIED = 1,
+	/**< ModEx operation type unspecified */
+	RTE_CRYPTO_MODEX_OP_MODEX,
+	/**< Modex operation modular exponentiation */
+	RTE_CRYPTO_MODEX_OP_LIST_END
+};
+
+/**
+ * ECDSA operation type variants
+ */
+enum rte_crypto_ecdsa_optype {
+	RTE_CRYPTO_ECDSA_OP_NOT_SPECIFIED = 1,
+	/**< ECDSA operation unspecified */
+	RTE_CRYPTO_ECDSA_OP_SIGN,
+	/**< ECDSA private key signature operation */
+	RTE_CRYPTO_ECDSA_OP_VERIFY,
+	/**< ECDSA public key verification operation */
+	RTE_CRYPTO_ECDSA_OP_LIST_END
+};
+
+/**
+ * Fundamental ECC operation type variants.
+ */
+enum rte_crypto_fecc_optype {
+	RTE_CRYPTO_FECC_OP_NOT_SPECIFIED = 1,
+	/**< FECC operation type unspecified */
+	RTE_CRYPTO_FECC_OP_POINT_ADD,
+	/**< Fundamental ECC point addition operation */
+	RTE_CRYPTO_FECC_OP_POINT_DBL,
+	/**< Fundamental ECC point doubling operation */
+	RTE_CRYPTO_FECC_OP_POINT_MULTIPLY,
+	/**< Fundamental ECC point multiplication operation */
+	RTE_CRYPTO_FECC_OP_LIST_END
+};
+
+/**
+ * ECC list of curves.
+ */
+enum rte_crypto_fecc_curves {
+	RTE_CRYPTO_FECC_CURVE_NOT_SPECIFIED = 1,
+	/**< Unspecified or empty curve id */
+	RTE_CRYPTO_FECC_CURVE_P192,
+	/**< NIST/X9.62/SECG curve over a 192 bit prime field */
+	RTE_CRYPTO_FECC_CURVE_P224,
+	/**< NIST/SECG curve over a 224 bit prime field */
+	RTE_CRYPTO_FECC_CURVE_P256,
+	/**<  X9.62/SECG curve over a 256 bit prime field */
+	RTE_CRYPTO_FECC_CURVE_P384,
+	/**< NIST/SECG curve over a 384 bit prime field */
+	RTE_CRYPTO_FECC_CURVE_P521,
+	/**< NIST/SECG curve over a 521 bit prime field */
+	RTE_CRYPTO_FECC_CURVE_LIST_END
+};
+
+
+/**
+ * Padding types for RSA signature.
+ */
+enum rte_crypto_rsa_padding_type {
+	RTE_CRYPTO_RSA_PADDING_NOT_SPECIFIED = 1,
+	/**< RSA no padding scheme */
+	RTE_CRYPTO_RSA_PADDING_BT1,
+	/**< RSA PKCS#1 padding BT1 scheme */
+	RTE_CRYPTO_RSA_PADDING_BT2,
+	/**< RSA PKCS#1 padding BT2 scheme */
+	RTE_CRYPTO_RSA_PADDING_OAEP,
+	/**< RSA PKCS#1 OAEP padding scheme */
+	RTE_CRYPTO_RSA_PADDING_PSS,
+	/**< RSA PKCS#1 PSS padding scheme */
+	RTE_CRYPTO_RSA_PADDING_TYPE_LIST_END
+};
+
+/**
+ * Asymmetric RSA transform data
+ *
+ * This structure contains data required to perform RSA crypto
+ * transform. If all CRT components are filled, RSA private key
+ * operations @ref RTE_CRYPTO_RSA_OP_SIGN and @ref
+ * RTE_CRYPTO_RSA_OP_PRIVATE_DECRYPT uses CRT method for crypto
+ * transform.
+ */
+struct rte_crypto_rsa_xform {
+
+	int modlen;
+	/**< Length of RSA prime modulus */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to prime modulus data */
+		size_t length;
+		/**< Length of prime modulus */
+	} n;
+	/**< n - Prime modulus
+	 * n is the prime modulus of RSA parameters.
+	 */
+
+	struct {
+		uint8_t *data;
+		/** Pointer to public key exponent data */
+		size_t length;
+		/** Length of public key exponent */
+	} e;
+	/**< e - Public key exponent
+	 * e is the public key exponent used for RSA public key
+	 * operations.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private key exponent data */
+		size_t length;
+		/**< Pointer to public key exponent data */
+	} d;
+	/**< d - Private key exponent
+	 * d is the private key exponent used for RSA private key
+	 * operations.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private key component P data */
+		size_t length;
+		/**< Length of private key component P */
+	} p;
+
+	/**< p - Private key component P
+	 * p is the private key component of RSA parameter  required
+	 * for CRT method of private key operations.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private key component Q data */
+		size_t length;
+		/**< Length of private key component Q */
+	} q;
+	/**< q - Private key component Q
+	 * q is the private key component of RSA parameter  required
+	 * for CRT method of private key operations.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private CRT component, dP, data */
+		size_t length;
+		/**< Length of private key component dmp */
+	} dP;
+	/**< dP - Private CRT component
+	 * dP is the private CRT component of RSA parameter  required for
+	 * RSA private key operation in CRT method.
+	 * dP = d mod ( p - 1 )
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private CRT component, dQ, data */
+		size_t length;
+		/**< Length of private key component dQ */
+	} dQ;
+	/**< dQ - Private CRT component
+	 * dQ is the private CRT component of RSA parameter  required for
+	 * RSA private key operation in CRT method.
+	 * dQ = d mod ( q - 1 )
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to private CRT component, qInv, data */
+		size_t length;
+		/**< Length of private key component qInv */
+	} qInv;
+	/**< qInv - Private CRT component
+	 * qInv is the private CRT component of RSA parameter  required for
+	 * RSA private key operation in CRT method.
+	 * qInv = inv q mod p
+	 */
+};
+
+/** Asymmetric Modular exponentiation transform data
+ *
+ * This structure contains data required to perform modular exponentation
+ * crypto transform. If all CRT components are valid, crypto transform
+ * operation follows CRT method.
+ */
+struct rte_crypto_modex_xform {
+
+	int modlen;
+	/**< Length of prime modulus */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to prime modulus data */
+		size_t length;
+		/**< Length of prime modulus */
+	} modulus;
+	/**< modulus
+	 * modulus is the prime modulus of the modexp transform
+	 * operation.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to exponent data */
+		size_t length;
+		/**< Length of exponent */
+	} exponent;
+	/**< exponent
+	 * Private exponent of the modexp transform operation.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to CRT component of exponent data */
+		size_t length;
+		/**< Length of CRT component P */
+	} p;
+	/**< P
+	 * p is CRT component of private exponent.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to CRT component of exponent data */
+		size_t length;
+		/**< Length of CRT component Q */
+	} q;
+	/**< q
+	 * q is the CRT component of private exponent.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to CRT component Ep data */
+		size_t length;
+		/**< Length of CRT component Ep */
+	} Ep;
+	/**< Ep CRT component
+	 * Ep is the CRT component of private exponent.
+	 * Ep = exponent mod ( p - 1 )
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to CRT component Eq data */
+		size_t length;
+		/**< Length of CRT component Eq */
+	} Eq;
+	/**< Eq CRT component
+	 * Eq is the CRT component of private exponent.
+	 * Eq = exponent mod ( q - 1 )
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to CRT component of exponent, qInv, data */
+		size_t length;
+		/**< Length of private key component qInv */
+	} qInv;
+	/**< qInv - Private CRT component
+	 * qInv is the CRT component of private exponent.
+	 * qInv = inv q mod p
+	 */
+};
+
+/** Asymmetric ECDSA transform data
+ *
+ * This structure contains data required to perform ECDSA crypto
+ * transform.
+ */
+struct rte_crypto_ecdsa_xform {
+
+	enum rte_crypto_fecc_curves curve_id;
+	/**< ECC prime field curve */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve order data */
+		size_t length;
+		/**< Length of curve order */
+	} order;
+	/**< ECC curve order data */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC prime modulus data */
+		size_t length;
+		/**< Length of prime */
+	} prime;
+	/**< ECC Curve prime modulus data */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve generator data X */
+		size_t length;
+		/**< Length of curve generator x-coord*/
+	} Gx;
+	/**< X co-ordinate of the ECC curve generator point */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve generator data Y */
+		size_t length;
+		/**< Length of curve generator y-coord*/
+	} Gy;
+	/**< Y co-ordinate of the ECC curve generator point */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC private key data */
+		size_t length;
+		/**< Length of private key */
+	} pkey;
+	/**< Private key of the signer, is only valid for signature
+	 * generation and not verification operation.
+	 */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to public key data (x co-ordinate) */
+		size_t length;
+		/**< Length of public key X */
+	} qx;
+	/**< X co-ordinate of the public key point */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to public key data (y co-ordinate) */
+		size_t length;
+		/**< Length of public key Y*/
+	} qy;
+	/**< Y co-ordinate of the public key point */
+};
+
+/** Asymmetric Fundamental ECC transform operation
+ *
+ * This structure contains data required to perform asymmetric
+ * fundamental ECC crypto transform.
+ */
+struct rte_crypto_fecc_xform {
+
+	enum rte_crypto_fecc_curves curve_id;
+	/**< ECC prime field curve */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve order data */
+		size_t length;
+		/**< Length of curve order */
+	} order;
+	/**< ECC curve order data */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC prime modulus data */
+		size_t length;
+		/**< Length of prime */
+	} prime;
+	/**< ECC Curve prime modulus data */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve generator data X */
+		size_t length;
+		/**< Length of curve generator x-coord*/
+	} Gx;
+	/**< X co-ordinate of the ECC curve generator point */
+
+	struct {
+		uint8_t *data;
+		/**< Pointer to ECC curve generator data Y */
+		size_t length;
+		/**< Length of curve generator y-coord*/
+	} Gy;
+	/**< Y co-ordinate of the ECC curve generator point */
+
+};
+
+/**
+ * Asymmetric crypto transform data
+ *
+ * This structure contains the data required to perform the
+ * asymmetric crypto transformation operation. The field op
+ * determines the asymmetric algorithm for transformation.
+ */
+struct rte_crypto_asym_xform {
+	struct rte_crypto_asym_xform *next;
+	enum rte_crypto_asym_xform_type type;
+	/**< Asymmetric algorithm for crypto transform */
+
+	RTE_STD_C11
+	union {
+		struct rte_crypto_rsa_xform rsa;
+		struct rte_crypto_fecc_xform fecc;
+		struct rte_crypto_modex_xform modex;
+		struct rte_crypto_ecdsa_xform ecdsa;
+	};
+};
+
+struct rte_cryptodev_asym_session;
+
+/**
+ * Crypto operation session type. This is used to specify whether a crypto
+ * operation has session structure attached for immutable parameters or if all
+ * operation information is included in the operation data structure.
+ */
+enum rte_crypto_asym_op_sess_type {
+	RTE_CRYPTO_ASYM_OP_WITH_SESSION,
+	/**< Session based crypto operation */
+	RTE_CRYPTO_ASYM_OP_SESSIONLESS
+	/**< Session-less crypto operation */
+};
+
+/**
+ * Asymmetric Cryptographic Operation.
+ *
+ * This structure contains data relating to performing asymmetric cryptographic
+ * processing on a referenced mbuf data buffer.
+ *
+ * When an asymmetric crypto operation is enqueued with device for processing
+ * it must have a valid *rte_mbuf* structure attached, via m_src parameter,
+ * which contains the source data which the crypto operation is to be performed
+ * on.
+ * While the mbuf is in use by a crypto operation no part of the mbuf should be
+ * changed by the application as the device may read or write to any part of the
+ * mbuf. In the case of hardware crypto devices some or all of the mbuf
+ * may be DMAed in and out of the device, so writing over the original data.
+ * Asymmetric operation, in more than most cases, works in Out-of-place mode. ie
+ * source mbuf and destination mbuf will be different. Data will be copied from
+ * m_src to m_dst after transformation.
+ */
+struct rte_crypto_asym_op {
+	struct rte_mbuf *m_src;	/**< source mbuf */
+	struct rte_mbuf *m_dst;	/**< destination mbuf */
+
+	enum rte_crypto_asym_op_sess_type sess_type;
+
+	RTE_STD_C11
+	union {
+		enum rte_crypto_rsa_optype rsa_op;
+		/**< Type of RSA operation for transform */;
+		enum rte_crypto_modex_optype modex_op;
+		/**< Type of modular exponentiation operation */
+		enum rte_crypto_ecdsa_optype ecdsa_op;
+		/**< ECDSA crypto xform operation type */
+		enum rte_crypto_fecc_optype fecc_op;
+		/**< ECDSA crypto xform operation type */
+	};
+
+	RTE_STD_C11
+	union {
+		struct rte_cryptodev_asym_session *session;
+		/**< Handle for the initialised session context */
+		struct rte_crypto_asym_xform *xform;
+		/**< Session-less API crypto operation parameters */
+	};
+
+	struct {
+		uint32_t offset;
+		/**< Starting point for crypto processing, specified
+		 * as number of bytes from start of data in the source
+		 * buffer.
+		 *
+		 * @note
+		 * When the crypto transform is either RSA public encryt @ref
+		 * RTE_CRYPTO_RSA_OP_PUBLIC_ENCRYPT or RSA private decrypt
+		 * @ref RTE_CRYPTO_RSA_OP_PRIVATE_DECRYPT, offset specifies the
+		 * data  which is to be encrypted or decrypted respectively.
+		 *
+		 * @note
+		 * When the crypto transform is RSA sign @ref
+		 * RTE_CRYPTO_RSA_OP_SIGN, offset specifies the data for
+		 * which the RSA signature is to be generated.
+		 *
+		 * @note
+		 * When the crypto transform is RSA verify @ref
+		 * RTE_CRYPTO_RSA_OP_VERIFY, offset specifies the data for
+		 * which the signature is to be verified
+		 *
+		 * @note
+		 * When the crypto transform is ECDSA sign @ref
+		 * RTE_CRYPTO_ECDSA_OP_SIGN, offset specifies the data for
+		 * which ECDSA signature is to be generated.
+		 *
+		 * @note
+		 * When the crypto trasnform is ECDSA verify @ref
+		 * RTE_CRYPTO_ECDSA_OP_VERIFY, offset specifies the data for
+		 * which ECDSA signature is to be verified.
+		 *
+		 * @note
+		 * When the crypto trasnform is MODEXP @ref
+		 * RTE_CRYPTO_MODEX_OP_MODEX, offset specifies the data for
+		 * which modular exponentiation is be performed.
+		 *
+		 * @note
+		 * When the crypto trasnform is any of the fundamental ECC
+		 * operations @ref RTE_CRYPTO_ASYM_XFORM_FECC, source and
+		 * desitnation mbufs are unused.
+		 */
+
+		uint32_t length;
+		/**<
+		 * The message length, in bytes, in the source buffer
+		 * on which the cryptographic transform will be
+		 * performed.
+		 *
+		 * @note
+		 * If the operation type involes RSA encrypt
+		 * @ref RTE_CRYPTO_RSA_OP_PUBLIC_ENCRYPT, the length
+		 * of data should be less than the prime modulus of RSA.
+		 *
+		 * @note
+		 * If the operation type involves RSA decrypt
+		 * @ref RTE_CRYPTO_RSA_OP_PRIVATE_DECRYPT, the length of
+		 * data will be equal to RSA prime modulus length.
+		 *
+		 * @note
+		 * If the operation type is RSA signature generation
+		 * @ref RTE_CRYPTO_RSA_OP_SIGN, or verification
+		 * @ref RTE_CRYPTO_RSA_OP_VERIFY, the length of data should be
+		 * less than prime modulus length in bytes. The maximum length
+		 * is dependent on the padding scheme selected.
+		 *
+		 * @note
+		 * If the operation type is modular exponentiation,
+		 * @ref RTE_CRYPTO_MODEX_OP_MODEX, the length of data
+		 * should be less than the prime modulus of the modex
+		 * operation.
+		 *
+		 * @note
+		 * For ECDSA sign operation @ref RTE_CRYPTO_ECDSA_OP_SIGN,
+		 * only the leftmost prime_modulus length of data in bytes
+		 * is considered for signature.
+		 *
+		 * @note
+		 * For ECDSA verify operation @ref RTE_CRYPTO_ECDSA_OP_VERIFY,
+		 * only the leftmost prime_modulus length of data in bytes is
+		 * considered for signature verification.
+		 */
+	} data;
+
+	RTE_STD_C11
+	union {
+
+		struct {
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} sign;
+			/**<
+			 * Pointer to RSA signature data. If operation is RSA
+			 * sign @ref RTE_CRYPTO_RSA_OP_SIGN, buffer will be
+			 * over-written with generated signature.
+			 *
+			 * Length of the signature data will be equal to the
+			 * RSA prime modulus length.
+			 */
+
+			enum rte_crypto_rsa_padding_type pad;
+			/**< RSA padding scheme to be used for transform */
+
+			enum rte_crypto_auth_algorithm md;
+			/**< Hash algorithm to be used for data hash if padding
+			 * scheme is either OAEP or PSS. Valid hash algorithms
+			 * are:
+			 * MD5, SHA1, SHA224, SHA256, SHA384, SHA512
+			 */
+
+			enum rte_crypto_auth_algorithm mgf1md;
+			/**<
+			 * Hash algorithm to be used for mask generation if
+			 * padding scheme is either OAEP or PSS. If padding
+			 * scheme is unspecified data hash algorithm is used
+			 * for mask generation. Valid hash algorithms are:
+			 * MD5, SHA1, SHA224, SHA256, SHA384, SHA512
+			 */
+		} rsa;
+
+		struct {
+			struct {
+				uint8_t *data;
+
+				phys_addr_t phys_addr;
+
+				size_t length;
+			} sign_r;
+			/**<
+			 * Pointer to r-component of ECDSA signature. If
+			 * operation type is @ref RTE_CRYPTO_ECDSA_OP_SIGN
+			 * this buffer will be over-written with the signature
+			 * component.
+			 *
+			 * Length of r-component will be less than the prime
+			 * modulus of the ECC curve.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} sign_s;
+			/**<
+			 * Pointer to s-component of ECDSA signature. If
+			 * operation type is @ref RTE_CRYPTO_ECDSA_OP_VERIFY
+			 * this buffer will be over-written with the signature
+			 * component.
+			 *
+			 * Length of s-component will be less than the prime
+			 * modulus of the ECC curve.
+			 */
+
+			struct {
+				uint8_t *data;
+
+				phys_addr_t phys_addr;
+
+				size_t length;
+			} k;
+			/**<
+			 * Pointer to random scalar to be used for generation
+			 * of ECDSA signature @ref RTE_CRYPTO_ECDSA_OP_VERIFY.
+			 * It is invalid if operation is ECDSA verify.
+			 *
+			 * Length of scalar K should be less than the prime
+			 * modulus of the curve
+			 */
+		} ecdsa;
+
+		struct {
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} px;
+			/**<
+			 * Pointer to the X co-ordinate of the primary curve
+			 * point for fundamental ECC operation.
+			 *
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} py;
+			/**<
+			 * Pointer to the Y co-ordinate of the primary curve
+			 * point for fundamental ECC operation.
+			 *
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} qx;
+			/**<
+			 * Pointer to the X co-ordinate of the primary curve
+			 * point for fundamental ECC operation.
+			 *
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve. This data valid only for
+			 * point addition @ref RTE_CRYPTO_FECC_OP_POINT_ADD
+			 * crypto transform.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} qy;
+			/**<
+			 * Pointer to the X co-ordinate of the primary curve
+			 * point for fundamental ECC operation.
+			 *
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve. This data valid only for
+			 * point addition @ref RTE_CRYPTO_FECC_OP_POINT_ADD
+			 * crypto transform.
+			 */
+
+			struct {
+				uint8_t *data;
+
+				phys_addr_t phys_addr;
+
+				size_t length;
+			} k;
+			/**<
+			 * Pointer to scalar data to be used only for point
+			 * multiplication @ref RTE_CRYPTO_FECC_OP_POINT_MULTIPLY
+			 * crypto transform.
+			 *
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} rx;
+			/**<
+			 * Pointer to the X co-ordinate of resultant point on
+			 * the curve after fundamental ECC crypto transform.
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve.
+			 */
+
+			struct {
+				uint8_t *data;
+				phys_addr_t phys_addr;
+				size_t length;
+			} ry;
+			/**<
+			 * Pointer to the Y co-ordinate of resultant point on
+			 * the curve after fundamental ECC crypto transform.
+			 * Length of data in bytes cannot exceed the prime
+			 * modulus length of the curve.
+			 */
+		} fecc;
+	};
+
+} __rte_cache_aligned;
+
+
+
+/**
+ * Reset the fields of an asymmetric operation to their default values.
+ *
+ * @param	op	The crypto operation to be reset.
+ */
+static inline void
+__rte_crypto_asym_op_reset(struct rte_crypto_asym_op *op)
+{
+	memset(op, 0, sizeof(*op));
+
+	op->sess_type = RTE_CRYPTO_ASYM_OP_SESSIONLESS;
+}
+
+
+/**
+ * Allocate space for asymmetric crypto xforms in the private data space of the
+ * crypto operation. This also defaults the crypto xform type to
+ * RTE_CRYPTO_ASYM_XFORM_NOT_SPECIFIED and configures the chaining of the xforms
+ * in the crypto operation
+ *
+ * @return
+ * - On success returns pointer to first crypto xform in crypto operations chain
+ * - On failure returns NULL
+ */
+static inline struct rte_crypto_asym_xform *
+__rte_crypto_asym_op_asym_xforms_alloc(struct rte_crypto_asym_op *asym_op,
+		void *priv_data, uint8_t nb_xforms)
+{
+	struct rte_crypto_asym_xform *xform;
+
+	asym_op->xform = xform = (struct rte_crypto_asym_xform *)priv_data;
+
+	do {
+		xform->type = RTE_CRYPTO_ASYM_XFORM_NOT_SPECIFIED;
+		xform = xform->next = --nb_xforms > 0 ? xform + 1 : NULL;
+	} while (xform);
+
+	return asym_op->xform;
+}
+
+
+/**
+ * Attach a session to an asymmetric crypto operation
+ *
+ * @param	asym_op	crypto operation
+ * @param	sess	cryptodev session
+ */
+static inline int
+__rte_crypto_asym_op_attach_asym_session(struct rte_crypto_asym_op *asym_op,
+		struct rte_cryptodev_asym_session *sess)
+{
+	asym_op->session = sess;
+	asym_op->sess_type = RTE_CRYPTO_ASYM_OP_WITH_SESSION;
+
+	return 0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_CRYPTO_ASYM_H_ */
-- 
1.8.3.1



More information about the dev mailing list