Asymmetric crypto algorithms are essential in protocols such as SSL/TLS.
As the current ODP crypto library lacks support for asymmetric crypto
algorithms, this RFC is an attempt to address it and add support for the
same.

The asymmetric algorithms featured 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.



Signed-off-by: Umesh Kartha <umesh.kar...@caviumnetworks.com>
---
 include/odp/api/spec/crypto.h | 570 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 569 insertions(+), 1 deletion(-)

diff --git include/odp/api/spec/crypto.h include/odp/api/spec/crypto.h
index d30f050..4cd5a3d 100644
--- include/odp/api/spec/crypto.h
+++ include/odp/api/spec/crypto.h
@@ -57,6 +57,14 @@ typedef enum {
        ODP_CRYPTO_OP_ENCODE,
        /** Decrypt and/or verify authentication ICV */
        ODP_CRYPTO_OP_DECODE,
+       /** Perform asymmetric crypto RSA  operation */
+       ODP_CRYPTO_OP_RSA,
+       /** Perform asymmetric crypto modex operation */
+       ODP_CRYPTO_OP_MODEX,
+       /** Perform asymmetric crypto ECDSA operation */
+       ODP_CRYPTO_OP_ECDSA,
+       /** Perform asymmetric crypto ECC point operation */
+       ODP_CRYPTO_OP_FECC,
 } odp_crypto_op_t;
 
 /**
@@ -213,6 +221,202 @@ typedef union odp_crypto_auth_algos_t {
 } odp_crypto_auth_algos_t;
 
 /**
+ * Asymmetric crypto algorithms
+ */
+typedef enum {
+       /** RSA asymmetric key algorithm */
+       ODP_ASYM_ALG_RSA,
+
+       /** Modular exponentiation algorithm */
+       ODP_ASYM_ALG_MODEXP,
+
+       /** ECDSA authentication algorithm */
+       ODP_ASYM_ALG_ECDSA,
+
+       /** Fundamental ECC algorithm */
+       ODP_ASYM_ALG_FECC
+} odp_asym_alg_t;
+
+/**
+ *  Asymmetric algorithms in a bit field structure
+ */
+typedef union odp_crypto_asym_algos_t {
+       /** Asymmetric algorithms */
+       struct {
+               /** ODP_ASYM_ALG_RSA_PKCS   */
+               uint16_t alg_rsa_pkcs       :1;
+
+               /** ODP_ASYM_ALG_MODEXP */
+               uint16_t alg_modexp         :1;
+
+               /** ODP_ASYM_ALG_ECDSA  */
+               uint16_t alg_ecdsa          :1;
+
+               /** ODP_ASYM_FECC       */
+               uint16_t alg_fecc           :1;
+       } bit;
+       /** All bits of the bit field structure
+        *
+        * This field can be used to set/clear all flags, or bitwise
+        * operations over the entire structure.
+        */
+       uint16_t all_bits;
+} odp_crypto_asym_algos_t;
+
+/**
+ * Asymmetric Crypto RSA PKCS operation type
+ */
+typedef enum {
+       /** Encrypt with PKCS RSA public key */
+       ODP_CRYPTO_RSA_OP_PUBLIC_ENCRYPT,
+
+       /** Decrypt with PKCS RSA private key */
+       ODP_CRYPTO_RSA_OP_PRIVATE_DECRYPT,
+
+       /** Sign with RSA private key*/
+       ODP_CRYPTO_RSA_OP_SIGN,
+
+       /** Verify with RSA public key */
+       ODP_CRYPTO_RSA_OP_VERIFY,
+
+} odp_crypto_rsa_op_t;
+
+/**
+ * Asymmetric Crypto RSA PKCS padding type
+ */
+typedef enum {
+       /** RSA padding type none */
+       ODP_CRYPTO_RSA_PADDING_NONE,
+
+       /** RSA padding type PKCS#1 BT1*/
+       ODP_CRYPTO_RSA_PADDING_BT1,
+
+       /** RSA padding type PKCS#1 BT2*/
+       ODP_CRYPTO_RSA_PADDING_BT2,
+
+       /** RSA padding type PKCS#1OAEP */
+       ODP_CRYPTO_RSA_PADDING_OAEP,
+
+       /** RSA padding type PKCS#1 PSS */
+       ODP_CRYPTO_RSA_PADDING_PSS,
+
+} odp_crypto_rsa_padding_t;
+
+/**
+ *  RSA padding types in a bitfield structure.
+ */
+typedef union odp_crypto_rsa_pad_bits_t {
+       /** RSA padding type */
+       struct {
+               /** ODP_CRYPTO_RSA_PADDING_NONE */
+               uint16_t rsa_pad_none       :1;
+
+               /** ODP_CRYPTO_RSA_PADDING_BT1*/
+               uint16_t rsa_pad_bt1        :1;
+
+               /** ODP_CRYPTO_RSA_PADDING_BT2*/
+               uint16_t rsa_pad_bt2        :1;
+
+               /** ODP_CRYPTO_RSA_PADDING_OAEP*/
+               uint16_t rsa_pad_oaep       :1;
+
+               /** ODP_CRYPTO_RSA_PADDING_PSS */
+               uint16_t rsa_pad_pss        :1;
+       } bit;
+       /** All bits of the bit field structure
+        *
+        * This field can be used to set/clear all flags, or bitwise
+        * operations over the entire structure.
+        */
+       uint16_t all_bits;
+} odp_crypto_rsa_pad_bits_t;
+
+typedef enum {
+       /** MODEX operation not specified */
+       ODP_CRYPTO_MODEX_OP_NULL,
+
+       /** MODEX operation modular exponentation */
+       ODP_CRYPTO_MODEX_OP_MODEX,
+
+} odp_crypto_modex_op_t;
+
+/**
+ * Asymmetric Crypto ECDSA operation type
+ */
+typedef enum {
+       /** Compute ECDSA signature with ECDSA private key */
+       ODP_CRYPTO_ECDSA_OP_SIGN,
+
+       /** Verify ECDSA signature with ECDSA public key */
+       ODP_CRYPTO_ECDSA_OP_VERIFY,
+
+} odp_crypto_ecdsa_op_t;
+
+/**
+ * Asymmetric Crypto FECC operation type
+ */
+typedef enum {
+       /** Perform ECC point addition operation */
+       ODP_CRYPTO_FECC_OP_P_ADD,
+
+       /** Perform ECC point doubling operation */
+       ODP_CRYPTO_FECC_OP_P_DBL,
+
+       /** Perform ECC point multiplication */
+       ODP_CRYPTO_FECC_OP_P_MUL,
+
+} odp_crypto_fecc_op_t;
+
+/**
+ * Asymmetric Crypto ECC curves with h/w acceleration
+ */
+typedef enum {
+       /** NIST/X9.62/SECG curve over a 192 bit prime field */
+       ODP_CRYPTO_CURVE_P192,
+
+       /** NIST/SECG curve over a 224 bit prime field */
+       ODP_CRYPTO_CURVE_P224,
+
+       /** X9.62/SECG curve over a 256 bit prime field */
+       ODP_CRYPTO_CURVE_P256,
+
+       /** NIST/SECG curve over a 384 bit prime field */
+       ODP_CRYPTO_CURVE_P384,
+
+       /** NIST/SECG curve over a 521 bit prime field */
+       ODP_CRYPTO_CURVE_P521,
+} odp_crypto_ecc_curves_t;
+
+/**
+ *  ECC curves in a bitfield structure.
+ */
+typedef union odp_crypto_ecc_bits_t {
+       /** ECC curves  */
+       struct {
+               /** ODP_CRYPTO_CURVE_P192*/
+               uint32_t ecc_curve_p192     :1;
+
+               /** ODP_CRYPTO_CURVE_P224*/
+               uint32_t ecc_curve_p224     :1;
+
+               /** ODP_CRYPTO_CURVE_P256*/
+               uint32_t ecc_curve_p256     :1;
+
+               /** ODP_CRYPTO_CURVE_P384*/
+               uint32_t ecc_curve_p384     :1;
+
+               /** ODP_CRYPTO_CURVE_P521*/
+               uint32_t ecc_curve_p521     :1;
+       } bit;
+       /** All bits of the bit field structure
+        *
+        * This field can be used to set/clear all flags, or bitwise
+        * operations over the entire structure.
+        */
+       uint32_t all_bits;
+} odp_crypto_ecc_bits_t;
+
+/**
  * Crypto API key structure
  */
 typedef struct odp_crypto_key {
@@ -236,6 +440,118 @@ typedef struct odp_crypto_iv {
 
 } odp_crypto_iv_t;
 
+typedef struct odp_crypto_asym_key {
+       union {
+               struct {
+                       /**< PKCS RSA operation parameters*/
+
+                       /** RSA prime modulus (n) */
+                       odp_crypto_key_t n;
+
+                       /** RSA public key component (e) */
+                       odp_crypto_key_t e;
+
+                       /** RSA private key component (d)*/
+                       odp_crypto_key_t d;
+
+                       /** RSA private key CRT component (p)*/
+                       odp_crypto_key_t p;
+
+                       /** RSA private key CRT component (q)*/
+                       odp_crypto_key_t q;
+
+                       /** RSA private key CRT component (dmp1 = d%(p-1))*/
+                       odp_crypto_key_t dmp1;
+
+                       /** RSA private key CRT component (dmq1 = d%(q-1))*/
+                       odp_crypto_key_t dmq1;
+
+                       /** RSA private key CRT component
+                        * (iqmp = q^(-1 mod p))
+                        */
+                       odp_crypto_key_t iqmp;
+
+                       /** RSA modulus length */
+                       int rsa_modlen;
+
+               } rsa;
+               struct {
+                       /**< Modular Exponentation parameters */
+
+                       /** ModEx prime modulus (n) */
+                       odp_crypto_key_t n;
+
+                       /** ModEx exponent component (e) */
+                       odp_crypto_key_t e;
+
+                       /** Exponent CRT component  (p)*/
+                       odp_crypto_key_t p;
+
+                       /** Exponent CRT component (q)*/
+                       odp_crypto_key_t q;
+
+                       /** Exponent CRT component (Ep = e%(p-1))*/
+                       odp_crypto_key_t Ep;
+
+                       /** Exponent CRT component (Eq = e%(q-1))*/
+                       odp_crypto_key_t Eq;
+
+                       /** Exponent CRT component (iqmp = q^(-1 mod p))*/
+                       odp_crypto_key_t iqmp;
+
+                       /**  ModEx modulus length */
+                       int modex_modlen;
+
+               } modex;
+
+               struct {
+                       /**< ECDSA operation parameters */
+
+                       /** ECDSA curve order */
+                       odp_crypto_key_t order;
+
+                       /** ECDSA prime modulus */
+                       odp_crypto_key_t prime;
+
+                       /** ECDSA private key */
+                       odp_crypto_key_t priv_key;
+
+                       /** ECDSA curve generator X co-ordinate */
+                       odp_crypto_key_t Gx;
+
+                       /** ECDSA curve generator Y co-ordinate */
+                       odp_crypto_key_t Gy;
+
+                       /** ECDSA public key :X co-ordinate of ECPOINT */
+                       odp_crypto_key_t qx;
+
+                       /** ECDSA public key :Y co-ordinate of ECPOINT */
+                       odp_crypto_key_t qy;
+
+                       /** ECDSA curve ID */
+                       odp_crypto_ecc_curves_t curve_id;
+
+               } ecdsa;
+               struct {
+                       /** ECDSA curve order */
+                       odp_crypto_key_t order;
+
+                       /** ECDSA curve generator X co-ordinate */
+                       odp_crypto_key_t Gx;
+
+                       /** ECDSA curve generator Y co-ordinate */
+                       odp_crypto_key_t Gy;
+
+                       /** F-ECC prime modulus */
+                       odp_crypto_key_t prime;
+
+                       /** F-ECC curve ID */
+                       odp_crypto_ecc_curves_t curve_id;
+
+               } fecc;
+       };
+} odp_crypto_asym_key_t;
+
 /**
  * Crypto API data range specifier
  */
@@ -252,7 +568,7 @@ typedef struct odp_crypto_data_range {
  * Crypto API session creation parameters
  */
 typedef struct odp_crypto_session_param_t {
-       /** Encode vs. decode operation */
+       /** Type of operation */
        odp_crypto_op_t op;
 
        /** Authenticate cipher vs. plain text
@@ -298,6 +614,15 @@ typedef struct odp_crypto_session_param_t {
         */
        odp_crypto_key_t auth_key;
 
+       /** Asymmetric crypto operation keys
+        *   When the cryptographic operation to be performed is any of the
+        *   asymmetric crypto algorithms: cipher_alg, cipher_key, iv, and
+        *   auth alg are invalid or inconsequential. All immutable parameters
+        *   for the asymmetric crypto operation is expected in the asym_key
+        *   structure.
+        */
+       odp_crypto_asym_key_t asym_key;
+
        /** Async mode completion event queue
         *
         *  When odp_crypto_operation() is asynchronous, the completion queue is
@@ -320,6 +645,145 @@ typedef struct odp_crypto_session_param_t {
 typedef odp_crypto_session_param_t odp_crypto_session_params_t;
 
 /**
+ * Asymmetric crypto API per packet operation parameters.
+ */
+typedef struct asym_param_offset {
+       union {
+               struct {
+                       /** Data range of RSA signature
+                        * When asymmetric crypto operation to be performed
+                        * is @c ODP_CRYPTO_RSA_OP_SIGN, the signature
+                        * generated will be written at specified offset in
+                        * the output pkt buffer. If operation type is @c
+                        * ODP_CRYPTO_RSA_OP_VERIFY, signature to be verified
+                        * is expected at the specified offset in the input pkt
+                        * buffer.
+                        */
+                       odp_crypto_data_range_t signature;
+
+                       /** RSA operation type */
+                       odp_crypto_rsa_op_t  op;
+
+                       /** RSA sign padding type
+                        * RSA padding type to be used for RSA signature
+                        * generation or signature verification @c
+                        * odp_crypto_rsa_padding_t.
+                        */
+                       odp_crypto_rsa_padding_t padding;
+
+                       /** RSA data hash type for OAEP/PSS padding */
+                       odp_auth_alg_t md;
+
+                       /**  mask generating function for PSS padding*/
+                       odp_auth_alg_t mgf1md;
+
+               } rsa;
+               struct {
+                       /** MODEX operation type */
+                       odp_crypto_modex_op_t   op;
+               } modex;
+               struct {
+                       /** r-component of ECDSA sign
+                        * When asymmetric crypto operation to be performed is
+                        * @c ODP_CRYPTO_ECDSA_OP_SIGN, the 'r' component of
+                        * ECDSA signature to be generated is written at
+                        * specified offset in the output pkt. When asymmetric
+                        * crypto operation to be performed is @c
+                        * ODP_CRYPTO_ECDSA_OP_VERIFY, the 'r' component of
+                        * signature to be verfied is read from the specified
+                        * offset in input pkt buffer.
+                        */
+                       odp_crypto_data_range_t sign_r;
+
+                       /** s-component of ECDSA sign
+                        * When asymmetric crypto operation to be performed
+                        * is @c ODP_CRYPTO_ECDSA_OP_SIGN, the 's' component of
+                        * ECDSA signature to be generated is written at
+                        * specified offset in the output pkt. When asymmetric
+                        * crypto operation to be performed is @c
+                        * ODP_CRYPTO_ECDSA_OP_VERIFY, the 's' component of
+                        * signature to be verfied is read from the specified
+                        * offset in input pkt buffer.
+                        */
+                       odp_crypto_data_range_t sign_s;
+
+                       /** Scalar multiplicant for ECDSA sign
+                        * When asymmetric crypto operation is @c
+                        * ODP_CRYPTO_ECDSA_OP_SIGN, the scalar multiplicant
+                        * used to generate signature is read from the
+                        * specified offset from input pkt buffer.
+                        */
+                       odp_crypto_data_range_t k;
+
+                       /** ECDSA operation type */
+                       odp_crypto_ecdsa_op_t   ecdsa_op;
+
+               } ecdsa;
+               struct {
+                       /** X co-ord of point operand I
+                        * X co-ordinate of primary ECC curve point is read
+                        * from the specified offset from input pkt buffer
+                        * when crypto operation to be performed is @c
+                        * ODP_CRYPTO_OP_FECC.
+                        */
+                       odp_crypto_data_range_t px;
+
+                       /** Y co-ord of point operand I
+                        * Y co-ordinate of primary ECC curve point is read
+                        * from the specified offset from input pkt buffer
+                        * when crypto operation to be performed is @c
+                        * ODP_CRYPTO_OP_FECC.
+                        */
+                       odp_crypto_data_range_t py;
+
+                       /** X co-ord of point operand II
+                        * X co-ordinate of secondary ECC curve point is read
+                        * from the specified offset from input pkt buffer when
+                        * crypto operation to be performed is point addition
+                        * @c ODP_CRYPTO_FECC_OP_P_ADD.
+                        */
+                       odp_crypto_data_range_t qx;
+
+                       /** Y co-ord of point operand II
+                        * Y co-ordinate of secondary ECC curve point is read
+                        * from the specified offset from input pkt buffer when
+                        * crypto operation to be performed is point addition
+                        * @c ODP_CRYPTO_FECC_OP_P_ADD.
+                        */
+                       odp_crypto_data_range_t qy;
+
+                       /** X co-ord of result point
+                        * X co-ordinate of result ECC curve point is written
+                        * at the specified offset in output packet buffer when
+                        * crypto operation to be performed is @c
+                        * ODP_CRYPTO_OP_FECC.
+                        */
+                       odp_crypto_data_range_t rx;
+
+                       /** Y co-ord of result point
+                        * Y co-ordinate of result ECC curve point is written
+                        * at the specified offset in output packet buffer
+                        * when crypto operation to be performed is @c
+                        * ODP_CRYPTO_OP_FECC.
+                        */
+                       odp_crypto_data_range_t ry;
+
+                       /** Scalar multiplicant
+                        * When crypto operation to be performed is @c
+                        * ODP_CRYPTO_FECC_OP_P_MUL, the scalar multiplicant
+                        * for point multiplication is read from specified
+                        * offset in input packet buffer.
+                        */
+                       odp_crypto_data_range_t k;
+
+                       /** F-ECC operation type */
+                       odp_crypto_fecc_op_t     fecc_op;
+
+               } fecc;
+       };
+} asym_param_offset_t;
+
+/**
  * Crypto API per packet operation parameters
  */
 typedef struct odp_crypto_op_param_t {
@@ -364,12 +828,36 @@ typedef struct odp_crypto_op_param_t {
         */
        uint32_t hash_result_offset;
 
+       struct asym_param_offset asym_offset;
+
        /** Data range to apply cipher */
        odp_crypto_data_range_t cipher_range;
 
        /** Data range to authenticate */
        odp_crypto_data_range_t auth_range;
 
+       /** Data range for asymmetric operation
+        *
+        * If asymmetric operation is any of RSA public encrypt or private
+        * decrypt, asym_data_range specifies the length and offset of data to
+        * be encrypted or decrypted respectively. Length of data cannot exceed
+        * modulus length prime modulus length for encryption and should be
+        * equal to prime modulus length for decryption.
+        *
+        * If asymmetric operation is any of RSA sign, RSA verify, ECDSA
+        * sign or ECDSA verify, asym_data_range specifies the data for which
+        * signature is to be generated or verified. Length of data for RSA
+        * sign or verify depends on the type of RSA padding to be used and
+        * less than prime modulus length. Only leftmost prime modulus length
+        * bytes of data are used for ECDSA sign generation or verification.
+        *
+        * If asymmetric operation is modexp, asym_data_range specifies the
+        * base for  modular exponentiation. Length of data is expected to be
+        * than prime modulus length.
+        *
+        */
+       odp_crypto_data_range_t asym_data_range;
+
 } odp_crypto_op_param_t;
 
 /** @deprecated  Use odp_crypto_op_param_t instead */
@@ -403,6 +891,20 @@ typedef enum {
        ODP_CRYPTO_ALG_ERR_ICV_CHECK,
        /** IV value not specified */
        ODP_CRYPTO_ALG_ERR_IV_INVALID,
+       /** Invalid parameter length */
+       ODP_CRYPTO_ALG_ERR_INVALID_PARAM_LEN,
+       /** Data too large for RSA encrypt */
+       ODP_CRYPTO_ALG_RSA_DATA_TOO_LARGE,
+       /** Invalid PKCS padding */
+       ODP_CRYPTO_ALG_RSA_ERR_DECRYPT,
+       /** RSA signature verification failed */
+       ODP_CRYPTO_ALG_RSA_SIGN_MISMATCH,
+       /** Invalid ECDSA signature */
+       ODP_CRYPTO_ALG_ECDSA_ERR_INVALID_SIGN,
+       /** ECDSA signature verify failure */
+       ODP_CRYPTO_ALG_ECDSA_ERR_SIGN_MISMATCH,
+       /** Fundamental ECC error Point at Infinity */
+       ODP_CRYPTO_ALG_FECC_POINT_AT_INFINITY,
 } odp_crypto_alg_err_t;
 
 /**
@@ -448,6 +950,9 @@ typedef struct odp_crypto_op_result {
        /** Authentication status */
        odp_crypto_compl_status_t auth_status;
 
+       /** Asymmetric operation status */
+       odp_crypto_compl_status_t asym_status;
+
 } odp_crypto_op_result_t;
 
 /**
@@ -469,6 +974,12 @@ typedef struct odp_crypto_capability_t {
        /** Authentication algorithms implemented with HW offload */
        odp_crypto_auth_algos_t   hw_auths;
 
+       /** Supported Asymmetric algorithms */
+       odp_crypto_asym_algos_t   asym_algs;
+
+       /** Asymmetric algorithms implemented with HW offload */
+       odp_crypto_asym_algos_t   hw_asym_algs;
+
 } odp_crypto_capability_t;
 
 /**
@@ -509,6 +1020,46 @@ typedef struct odp_crypto_auth_capability_t {
 } odp_crypto_auth_capability_t;
 
 /**
+ * Asymmetric algorithm capabilities
+ */
+typedef struct odp_crypto_asym_capability_t {
+       union {
+               struct {
+                       /** Maximum prime modulus length for RSA */
+                       uint32_t max_modlen;
+
+                       /** Minimum prime modulus length for RSA */
+                       uint32_t min_modlen;
+
+                       /** Supported RSA padding schemes */
+                       odp_crypto_rsa_pad_bits_t padding;
+               } rsa;
+
+               struct {
+                       /** Maximum prime modulus length for modular
+                        * exponentiation
+                        */
+                       uint32_t max_modlen;
+
+                       /** Minimum prime modulus length for modular
+                        * exponentiation
+                        */
+                       uint32_t min_modlen;
+               } modex;
+
+               struct {
+                       /** Support ECC curves for ECDSA Operation */
+                       odp_crypto_ecc_bits_t curve_list;
+               } ecdsa;
+
+               struct {
+                       /** Support ECC curves for Fundamental ECC Operation */
+                       odp_crypto_ecc_bits_t curve_list;
+               } fecc;
+       };
+} odp_crypto_asym_capability_t;
+
+/**
  * Query crypto capabilities
  *
  * Outputs crypto capabilities on success.
@@ -560,6 +1111,23 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth,
                               odp_crypto_auth_capability_t capa[], int num);
 
 /**
+ * Query supported asymmetric  algorithm capabilities
+ *
+ * Outputs all supported configuration options for asymmetric algorithm.
+ *
+ * @param      asym         Asymmetric algorithm
+ * @param[out] capa         Array of capability structures for output
+ * @param      num          Maximum number of capability structures to output
+ *
+ * @return Number of capability structures for the algorithm. If this is larger
+ *         than 'num', only 'num' first structures were output and application
+ *         may call the function again with a larger value of 'num'.
+ * @retval <0 on failure
+ */
+int odp_crypto_asym_capability(odp_asym_alg_t asym,
+                              odp_crypto_asym_capability_t capa[], int num);
+
+/**
  * Crypto session creation
  *
  * Create a crypto session according to the session parameters. Use
-- 
1.8.3.1

Reply via email to