Hello community,

here is the log from the commit of package openssl-ibmca for openSUSE:Factory 
checked in at 2019-10-16 09:18:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openssl-ibmca (Old)
 and      /work/SRC/openSUSE:Factory/.openssl-ibmca.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openssl-ibmca"

Wed Oct 16 09:18:46 2019 rev:34 rq:738689 version:2.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/openssl-ibmca/openssl-ibmca.changes      
2019-09-07 11:55:43.630254614 +0200
+++ /work/SRC/openSUSE:Factory/.openssl-ibmca.new.2352/openssl-ibmca.changes    
2019-10-16 09:18:46.810927138 +0200
@@ -1,0 +2,6 @@
+Tue Sep 10 22:22:49 UTC 2019 - Mark Post <[email protected]>
+
+- Upgrade to version 2.1.0 (jsc#SLE-7852, jsc#SLE-7882)
+  Add MSA9 CPACF support for X25519, X448, Ed25519 and Ed448
+
+-------------------------------------------------------------------

Old:
----
  openssl-ibmca-2.0.3.tar.gz

New:
----
  openssl-ibmca-2.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openssl-ibmca.spec ++++++
--- /var/tmp/diff_new_pack.ebe2Op/_old  2019-10-16 09:18:47.190926159 +0200
+++ /var/tmp/diff_new_pack.ebe2Op/_new  2019-10-16 09:18:47.194926148 +0200
@@ -17,10 +17,10 @@
 
 
 Name:           openssl-ibmca
-Version:        2.0.3
+Version:        2.1.0
 Release:        0
 Summary:        The IBMCA OpenSSL dynamic engine
-License:        IPL-1.0
+License:        Apache-2.0
 Group:          Hardware/Other
 URL:            https://github.com/opencryptoki/openssl-ibmca
 Source:         
https://github.com/opencryptoki/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz

++++++ openssl-ibmca-2.0.3.tar.gz -> openssl-ibmca-2.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/ChangeLog 
new/openssl-ibmca-2.1.0/ChangeLog
--- old/openssl-ibmca-2.0.3/ChangeLog   2019-04-23 18:15:44.000000000 +0200
+++ new/openssl-ibmca-2.1.0/ChangeLog   2019-09-09 02:07:21.000000000 +0200
@@ -1,3 +1,6 @@
+* openssl-ibmca 2.1.0
+- Add MSA9 CPACF support for X25519, X448, Ed25519 and Ed448
+
 * openssl-ibmca 2.0.3
 - Add MSA9 CPACF support for ECDSA sign/verify
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/configure.ac 
new/openssl-ibmca-2.1.0/configure.ac
--- old/openssl-ibmca-2.0.3/configure.ac        2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/configure.ac        2019-09-09 02:07:21.000000000 
+0200
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 # See autoconf and autoscan online documentation for details.
 
-AC_INIT([openssl-ibmca], [2.0.3], [[email protected]])
+AC_INIT([openssl-ibmca], [2.1.0], [[email protected]])
 AC_CONFIG_SRCDIR([src/e_ibmca.c]) # sanity check
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_AUX_DIR([build-aux])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/openssl-ibmca.spec 
new/openssl-ibmca-2.1.0/openssl-ibmca.spec
--- old/openssl-ibmca-2.0.3/openssl-ibmca.spec  2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/openssl-ibmca.spec  2019-09-09 02:07:21.000000000 
+0200
@@ -1,7 +1,7 @@
 %global enginesdir %(pkg-config --variable=enginesdir libcrypto)
 
 Name:       openssl-ibmca
-Version:    2.0.3
+Version:    2.1.0
 Release:    1%{?dist}
 Summary:    An IBMCA OpenSSL dynamic engine
 
@@ -44,6 +44,9 @@
 %{_mandir}/man5/ibmca.5*
 
 %changelog
+* Mon Sep 09 2019 Patrick Steuer <[email protected]> 2.1.0
+- Update Version
+
 * Tue Apr 23 2019 Patrick Steuer <[email protected]> 2.0.3
 - Update Version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/Makefile.am 
new/openssl-ibmca-2.1.0/src/Makefile.am
--- old/openssl-ibmca-2.0.3/src/Makefile.am     2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/src/Makefile.am     2019-09-09 02:07:21.000000000 
+0200
@@ -1,4 +1,4 @@
-VERSION = 2:0:3
+VERSION = 2:1:0
 
 lib_LTLIBRARIES=ibmca.la
 
@@ -9,7 +9,8 @@
                                 ibmca_rsa.c \
                                 ibmca_dsa.c \
                                 ibmca_dh.c \
-                                ibmca_ec.c
+                                ibmca_ec.c \
+                                ibmca_pkey.c
 
 ibmca_la_LIBADD=-ldl
 ibmca_la_LDFLAGS=-module -version-number ${VERSION} -shared -no-undefined \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/e_ibmca.c 
new/openssl-ibmca-2.1.0/src/e_ibmca.c
--- old/openssl-ibmca-2.0.3/src/e_ibmca.c       2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/src/e_ibmca.c       2019-09-09 02:07:21.000000000 
+0200
@@ -140,6 +140,16 @@
     EC_DSA_SIGN,
     EC_DSA_VERIFY,
     EC_DH,
+    ED25519_KEYGEN,
+    ED25519_SIGN,
+    ED25519_VERIFY,
+    ED448_KEYGEN,
+    ED448_SIGN,
+    ED448_VERIFY,
+    X25519_KEYGEN,
+    X25519_DERIVE,
+    X448_KEYGEN,
+    X448_DERIVE,
     0
 };
 
@@ -163,9 +173,11 @@
  */
 static size_t size_cipher_list = 0;
 static size_t size_digest_list = 0;
+static size_t size_pkey_meths_list = 0;
 
 static struct crypto_pair ibmca_cipher_lists;
 static struct crypto_pair ibmca_digest_lists;
+static struct crypto_pair ibmca_pkey_meths_lists;
 
 static int ibmca_usable_ciphers(const int **nids);
 static int ibmca_engine_ciphers(ENGINE * e, const EVP_CIPHER ** cipher,
@@ -173,6 +185,9 @@
 static int ibmca_usable_digests(const int **nids);
 static int ibmca_engine_digests(ENGINE * e, const EVP_MD ** digest,
                                 const int **nids, int nid);
+static int ibmca_engine_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+                                   const int **nids, int nid);
+static int ibmca_usable_pkey_meths(const int **nids);
 
 /* RAND stuff */
 static int ibmca_rand_bytes(unsigned char *buf, int num);
@@ -264,65 +279,6 @@
     return 1;
 }
 
-int is_crypto_card_loaded()
-{
-    DIR *sysDir;
-    FILE *file;
-    char dev[PATH_MAX] = AP_PATH;
-    struct dirent *direntp;
-    char *type = NULL;
-    size_t size;
-    char c;
-
-    if ((sysDir = opendir(dev)) == NULL)
-        return 0;
-
-    while ((direntp = readdir(sysDir)) != NULL) {
-        if (strstr(direntp->d_name, "card") != 0) {
-            snprintf(dev, PATH_MAX, "%s/%s/type", AP_PATH, direntp->d_name);
-
-            if ((file = fopen(dev, "r")) == NULL) {
-                closedir(sysDir);
-                return 0;
-            }
-
-            if (getline(&type, &size, file) == -1) {
-                fclose(file);
-                closedir(sysDir);
-                return 0;
-            }
-
-            /* ignore \n
-             * looking for CEX??A and CEX??C
-             * Skip type CEX??P cards
-             */
-            if (type[strlen(type) - 2] == 'P') {
-                free(type);
-                type = NULL;
-                fclose(file);
-                continue;
-            }
-            free(type);
-            type = NULL;
-            fclose(file);
-
-            snprintf(dev, PATH_MAX, "%s/%s/online", AP_PATH, direntp->d_name);
-            if ((file = fopen(dev, "r")) == NULL) {
-                closedir(sysDir);
-                return 0;
-            }
-            if ((c = fgetc(file)) == '1') {
-                fclose(file);
-                return 1;
-            }
-            fclose(file);
-        }
-    }
-    closedir(sysDir);
-
-    return 0;
-}
-
 inline static int set_RSA_prop(ENGINE *e)
 {
     static int rsa_enabled = 0;
@@ -349,7 +305,7 @@
 }
 
 #ifndef OPENSSL_NO_EC
-inline static int set_EC_prop(ENGINE *e)
+static int set_EC_prop(ENGINE *e)
 {
     static int ec_enabled = 0;
 
@@ -410,10 +366,15 @@
  * feasible
  */
 inline static int set_engine_prop(ENGINE *e, int algo_id, int *dig_nid_cnt,
-                                  int *ciph_nid_cnt)
+                                  int *ciph_nid_cnt, int *pkey_nid_cnt)
 {
     static int ec_kgen_switch, ec_dh_switch, ec_dsa_sign_switch,
-               ec_dsa_verify_switch;
+               ec_dsa_verify_switch, x25519_keygen_switch,
+               x25519_derive_switch, x448_keygen_switch, x448_derive_switch,
+               ed25519_keygen_switch, ed25519_sign_switch,
+               ed25519_verify_switch, ed448_keygen_switch, ed448_sign_switch,
+               ed448_verify_switch, x25519_switch, x448_switch,
+               ed25519_switch, ed448_switch;
 
     switch (algo_id) {
     case P_RNG:
@@ -551,6 +512,36 @@
         ec_dsa_verify_switch = 1;
         break;
 #endif
+    case ED25519_KEYGEN:
+        ed25519_keygen_switch = 1;
+        break;
+    case ED25519_SIGN:
+        ed25519_sign_switch = 1;
+        break;
+    case ED25519_VERIFY:
+        ed25519_verify_switch = 1;
+        break;
+    case ED448_KEYGEN:
+        ed448_keygen_switch = 1;
+        break;
+    case ED448_SIGN:
+        ed448_sign_switch = 1;
+        break;
+    case ED448_VERIFY:
+        ed448_verify_switch = 1;
+        break;
+    case X25519_KEYGEN:
+        x25519_keygen_switch = 1;
+        break;
+    case X25519_DERIVE:
+        x25519_derive_switch = 1;
+        break;
+    case X448_KEYGEN:
+        x448_keygen_switch = 1;
+        break;
+    case X448_DERIVE:
+        x448_derive_switch = 1;
+        break;
     default:
         break;                  /* do nothing */
     }
@@ -563,9 +554,36 @@
     }
 #endif
 
+    if (x25519_keygen_switch && x25519_derive_switch && !x25519_switch) {
+        x25519_switch = 1;
+        ibmca_pkey_meths_lists.nids[*pkey_nid_cnt] = NID_X25519;
+        ibmca_pkey_meths_lists.crypto_meths[(*pkey_nid_cnt)++]
+          = ibmca_x25519();
+    }
+    if (x448_keygen_switch && x448_derive_switch && !x448_switch) {
+        x448_switch = 1;
+        ibmca_pkey_meths_lists.nids[*pkey_nid_cnt] = NID_X448;
+        ibmca_pkey_meths_lists.crypto_meths[(*pkey_nid_cnt)++]
+          = ibmca_x448();
+    }
+    if (ed25519_keygen_switch && ed25519_sign_switch
+        && ed25519_verify_switch && !ed25519_switch) {
+        ed25519_switch = 1;
+        ibmca_pkey_meths_lists.nids[*pkey_nid_cnt] = NID_ED25519;
+        ibmca_pkey_meths_lists.crypto_meths[(*pkey_nid_cnt)++]
+          = ibmca_ed25519();
+    }
+    if (ed448_keygen_switch && ed448_sign_switch
+        && ed448_verify_switch && !ed448_switch) {
+        ed448_switch = 1;
+        ibmca_pkey_meths_lists.nids[*pkey_nid_cnt] = NID_ED448;
+        ibmca_pkey_meths_lists.crypto_meths[(*pkey_nid_cnt)++]
+          = ibmca_ed448();
+    }
+
     size_cipher_list = *ciph_nid_cnt;
     size_digest_list = *dig_nid_cnt;
-
+    size_pkey_meths_list = *pkey_nid_cnt;
     return 1;
 }
 
@@ -577,7 +595,7 @@
     int rc = 0;
     int dig_nid_cnt = 0;
     int ciph_nid_cnt = 0;
-    int card_loaded;
+    int pkey_nid_cnt = 0;
 
     if (p_ica_get_functionlist(NULL, &mech_len))
         return 0;
@@ -589,20 +607,14 @@
     if (p_ica_get_functionlist(pmech_list, &mech_len))
         goto out;
 
-    card_loaded = is_crypto_card_loaded();
-
     for (i = 0; i < mech_len; i++) {
+
         libica_func_list_element *f = &pmech_list[i];
+
         /* Disable crypto algorithm if not supported in hardware */
         if (!(f->flags & (ICA_FLAG_SHW | ICA_FLAG_DHW)))
             continue;
-        /*
-         * If no crypto card is available, disable crypto algos that can
-         * only operate on HW on card
-         */
-        if ((f->flags & ICA_FLAG_DHW) && !card_loaded
-           && !(f->flags & ICA_FLAG_SHW))
-            continue;
+
         /* Check if this crypto algorithm is supported by ibmca */
         for (j = 0; ibmca_crypto_algos[j]; j++)
             if (ibmca_crypto_algos[j] == f->mech_mode_id)
@@ -614,7 +626,7 @@
          * Set NID, ibmca struct and the info for the ENGINE struct
          */
         if (!set_engine_prop(e, ibmca_crypto_algos[j],
-                             &dig_nid_cnt, &ciph_nid_cnt))
+                             &dig_nid_cnt, &ciph_nid_cnt, &pkey_nid_cnt))
             goto out;
     }
 
@@ -626,6 +638,10 @@
         if (!ENGINE_set_ciphers(e, ibmca_engine_ciphers))
             goto out;
 
+    if (pkey_nid_cnt > 0)
+        if (!ENGINE_set_pkey_meths(e, ibmca_engine_pkey_meths))
+            goto out;
+
     rc = 1;
 out:
     free(pmech_list);
@@ -912,6 +928,33 @@
     return size_digest_list;
 }
 
+static int ibmca_engine_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+                                   const int **nids, int nid)
+{
+    int i;
+
+    if (!pmeth)
+        return (ibmca_usable_pkey_meths(nids));
+
+    *pmeth = NULL;
+    for (i = 0; i < size_pkey_meths_list; i++) {
+        if (nid == ibmca_pkey_meths_lists.nids[i]) {
+            *pmeth = (EVP_PKEY_METHOD *)ibmca_pkey_meths_lists.crypto_meths[i];
+            break;
+        }
+    }
+
+    return (*pmeth != NULL);
+}
+
+static int ibmca_usable_pkey_meths(const int **nids)
+{
+    if (nids)
+        *nids = ibmca_pkey_meths_lists.nids;
+
+    return size_pkey_meths_list;
+}
+
 /* Random bytes are good */
 static int ibmca_rand_bytes(unsigned char *buf, int num)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/e_ibmca_err.c 
new/openssl-ibmca-2.1.0/src/e_ibmca_err.c
--- old/openssl-ibmca-2.0.3/src/e_ibmca_err.c   2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/src/e_ibmca_err.c   2019-09-09 02:07:21.000000000 
+0200
@@ -55,6 +55,8 @@
     {ERR_PACK(0, IBMCA_F_ICA_ECDH_DERIVE_SECRET, 0), "ICA_ECDH_DERIVE_SECRET"},
     {ERR_PACK(0, IBMCA_F_ICA_ECDSA_SIGN, 0), "ICA_ECDSA_SIGN"},
     {ERR_PACK(0, IBMCA_F_ICA_ECDSA_VERIFY, 0), "ICA_ECDSA_VERIFY"},
+    {ERR_PACK(0, IBMCA_F_ICA_ECDSA_VERIFY, 0), "IBMCA_X25519_KEYGEN"},
+    {ERR_PACK(0, IBMCA_F_ICA_ECDSA_VERIFY, 0), "IBMCA_X25519_DERIVE"},
     {0, NULL}
 };
 
@@ -80,6 +82,9 @@
     {IBMCA_R_EC_INTERNAL_ERROR, "ec internal error"},
     {IBMCA_R_EC_ICA_EC_KEY_INIT, "ec ica ec key init"},
     {IBMCA_R_EC_CURVE_DOES_NOT_SUPPORT_SIGNING, "ec curve does not support 
signing"},
+    {IBMCA_R_PKEY_INTERNAL_ERROR, "internal error"},
+    {IBMCA_R_PKEY_KEYGEN_FAILED, "keygen failed"},
+    {IBMCA_R_PKEY_KEYS_NOT_SET, "keys not set"},
     {0, NULL}
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/e_ibmca_err.h 
new/openssl-ibmca-2.1.0/src/e_ibmca_err.h
--- old/openssl-ibmca-2.0.3/src/e_ibmca_err.h   2019-04-23 18:15:44.000000000 
+0200
+++ new/openssl-ibmca-2.1.0/src/e_ibmca_err.h   2019-09-09 02:07:21.000000000 
+0200
@@ -60,6 +60,16 @@
 #define IBMCA_F_ICA_ECDH_DERIVE_SECRET 132
 #define IBMCA_F_ICA_ECDSA_SIGN         133
 #define IBMCA_F_ICA_ECDSA_VERIFY       134
+#define IBMCA_F_IBMCA_X25519_KEYGEN    140
+#define IBMCA_F_IBMCA_X25519_DERIVE    141
+#define IBMCA_F_IBMCA_X448_KEYGEN      142
+#define IBMCA_F_IBMCA_X448_DERIVE      143
+#define IBMCA_F_IBMCA_ED25519_KEYGEN   144
+#define IBMCA_F_IBMCA_ED448_KEYGEN     145
+#define IBMCA_F_IBMCA_ED25519_SIGN     146
+#define IBMCA_F_IBMCA_ED448_SIGN       147
+#define IBMCA_F_IBMCA_ED25519_VERIFY   148
+#define IBMCA_F_IBMCA_ED448_VERIFY     149
 
 /* Reason codes. */
 #define IBMCA_R_ALREADY_LOADED                  100
@@ -83,5 +93,8 @@
 #define IBMCA_R_EC_INTERNAL_ERROR              122
 #define IBMCA_R_EC_ICA_EC_KEY_INIT             123
 #define IBMCA_R_EC_CURVE_DOES_NOT_SUPPORT_SIGNING      159
+#define IBMCA_R_PKEY_INTERNAL_ERROR            160
+#define IBMCA_R_PKEY_KEYGEN_FAILED             161
+#define IBMCA_R_PKEY_KEYS_NOT_SET              162
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/ibmca.h 
new/openssl-ibmca-2.1.0/src/ibmca.h
--- old/openssl-ibmca-2.0.3/src/ibmca.h 2019-04-23 18:15:44.000000000 +0200
+++ new/openssl-ibmca-2.1.0/src/ibmca.h 2019-09-09 02:07:21.000000000 +0200
@@ -376,6 +376,15 @@
  #endif
 #endif
 
+const EVP_PKEY_METHOD *ibmca_x25519(void);
+const EVP_PKEY_METHOD *ibmca_x448(void);
+const EVP_PKEY_METHOD *ibmca_ed25519(void);
+const EVP_PKEY_METHOD *ibmca_ed448(void);
+void ibmca_x25519_destroy(void);
+void ibmca_x448_destroy(void);
+void ibmca_ed25519_destroy(void);
+void ibmca_ed448_destroy(void);
+
 /******************************* Libica stuff 
*********************************/
 /*
  * These are the function pointers that are (un)set when the library has
@@ -538,6 +547,75 @@
 typedef void (*ica_ec_key_free_t)(ICA_EC_KEY *key);
 #endif
 
+typedef
+int (*ica_x25519_ctx_new_t)(ICA_X25519_CTX **ctx);
+typedef
+int (*ica_x448_ctx_new_t)(ICA_X448_CTX **ctx);
+typedef
+int (*ica_ed25519_ctx_new_t)(ICA_ED25519_CTX **ctx);
+typedef
+int (*ica_ed448_ctx_new_t)(ICA_ED448_CTX **ctx);
+typedef
+int (*ica_x25519_key_set_t)(ICA_X25519_CTX *ctx, const unsigned char priv[32],
+                      const unsigned char pub[32]);
+typedef
+int (*ica_x448_key_set_t)(ICA_X448_CTX *ctx, const unsigned char priv[56],
+                    const unsigned char pub[56]);
+typedef
+int (*ica_ed25519_key_set_t)(ICA_ED25519_CTX *ctx, const unsigned char 
priv[32],
+                       const unsigned char pub[32]);
+typedef
+int (*ica_ed448_key_set_t)(ICA_ED448_CTX *ctx, const unsigned char priv[56],
+                     const unsigned char pub[56]);
+typedef
+int (*ica_x25519_key_get_t)(ICA_X25519_CTX *ctx, unsigned char priv[32],
+                      unsigned char pub[32]);
+typedef
+int (*ica_x448_key_get_t)(ICA_X448_CTX *ctx, unsigned char priv[56],
+                    unsigned char pub[56]);
+typedef
+int (*ica_ed25519_key_get_t)(ICA_ED25519_CTX *ctx, unsigned char priv[32],
+                       unsigned char pub[32]);
+typedef
+int (*ica_ed448_key_get_t)(ICA_ED448_CTX *ctx, unsigned char priv[57],
+                     unsigned char pub[57]);
+typedef
+int (*ica_x25519_key_gen_t)(ICA_X25519_CTX *ctx);
+typedef
+int (*ica_x448_key_gen_t)(ICA_X448_CTX *ctx);
+typedef
+int (*ica_ed25519_key_gen_t)(ICA_ED25519_CTX *ctx);
+typedef
+int (*ica_ed448_key_gen_t)(ICA_ED448_CTX *ctx);
+typedef
+int (*ica_x25519_derive_t)(ICA_X25519_CTX *ctx,
+                     unsigned char shared_secret[32],
+                     const unsigned char peer_pub[32]);
+typedef
+int (*ica_x448_derive_t)(ICA_X448_CTX *ctx,
+                   unsigned char shared_secret[56],
+                   const unsigned char peer_pub[56]);
+typedef
+int (*ica_ed25519_sign_t)(ICA_ED25519_CTX *ctx, unsigned char sig[64],
+                    const unsigned char *msg, size_t msglen);
+typedef
+int (*ica_ed448_sign_t)(ICA_ED448_CTX *ctx, unsigned char sig[114],
+                  const unsigned char *msg, size_t msglen);
+typedef
+int (*ica_ed25519_verify_t)(ICA_ED25519_CTX *ctx, const unsigned char sig[64],
+                      const unsigned char *msg, size_t msglen);
+typedef
+int (*ica_ed448_verify_t)(ICA_ED448_CTX *ctx, const unsigned char sig[114],
+                    const unsigned char *msg, size_t msglen);
+typedef
+int (*ica_x25519_ctx_del_t)(ICA_X25519_CTX **ctx);
+typedef
+int (*ica_x448_ctx_del_t)(ICA_X448_CTX **ctx);
+typedef
+int (*ica_ed25519_ctx_del_t)(ICA_ED25519_CTX **ctx);
+typedef
+int (*ica_ed448_ctx_del_t)(ICA_ED448_CTX **ctx);
+
 /* entry points into libica, filled out at DSO load time */
 extern ica_get_functionlist_t           p_ica_get_functionlist;
 extern ica_set_fallback_mode_t          p_ica_set_fallback_mode;
@@ -577,3 +655,29 @@
 extern ica_ec_key_get_private_key_t    p_ica_ec_key_get_private_key;
 extern ica_ec_key_free_t               p_ica_ec_key_free;
 #endif
+extern ica_x25519_ctx_new_t            p_ica_x25519_ctx_new;
+extern ica_x448_ctx_new_t              p_ica_x448_ctx_new;
+extern ica_ed25519_ctx_new_t           p_ica_ed25519_ctx_new;
+extern ica_ed448_ctx_new_t             p_ica_ed448_ctx_new;
+extern ica_x25519_key_set_t            p_ica_x25519_key_set;
+extern ica_x448_key_set_t              p_ica_x448_key_set;
+extern ica_ed25519_key_set_t           p_ica_ed25519_key_set;
+extern ica_ed448_key_set_t             p_ica_ed448_key_set;
+extern ica_x25519_key_get_t            p_ica_x25519_key_get;
+extern ica_x448_key_get_t              p_ica_x448_key_get;
+extern ica_ed25519_key_get_t           p_ica_ed25519_key_get;
+extern ica_ed448_key_get_t             p_ica_ed448_key_get;
+extern ica_x25519_key_gen_t            p_ica_x25519_key_gen;
+extern ica_x448_key_gen_t              p_ica_x448_key_gen;
+extern ica_ed25519_key_gen_t           p_ica_ed25519_key_gen;
+extern ica_ed448_key_gen_t             p_ica_ed448_key_gen;
+extern ica_x25519_derive_t             p_ica_x25519_derive;
+extern ica_x448_derive_t               p_ica_x448_derive;
+extern ica_ed25519_sign_t              p_ica_ed25519_sign;
+extern ica_ed448_sign_t                        p_ica_ed448_sign;
+extern ica_ed25519_verify_t            p_ica_ed25519_verify;
+extern ica_ed448_verify_t              p_ica_ed448_verify;
+extern ica_x25519_ctx_del_t            p_ica_x25519_ctx_del;
+extern ica_x448_ctx_del_t              p_ica_x448_ctx_del;
+extern ica_ed25519_ctx_del_t           p_ica_ed25519_ctx_del;
+extern ica_ed448_ctx_del_t             p_ica_ed448_ctx_del;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/ibmca_pkey.c 
new/openssl-ibmca-2.1.0/src/ibmca_pkey.c
--- old/openssl-ibmca-2.0.3/src/ibmca_pkey.c    1970-01-01 01:00:00.000000000 
+0100
+++ new/openssl-ibmca-2.1.0/src/ibmca_pkey.c    2019-09-09 02:07:21.000000000 
+0200
@@ -0,0 +1,724 @@
+/*
+ * Copyright [2019] International Business Machines Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/engine.h>
+#include <openssl/obj_mac.h>
+
+#include "ibmca.h"
+#include "e_ibmca_err.h"
+
+/*
+ * copied from evp_int.h:
+ * missing set/get methods for opaque types.
+ */
+
+typedef struct {
+    unsigned char pub[57];
+    unsigned char *priv;
+} ECX_KEY;
+
+typedef struct evp_pkey_method_st {
+    int pkey_id;
+    int flags;
+    int (*init) (EVP_PKEY_CTX *ctx);
+    int (*copy) (EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src);
+    void (*cleanup) (EVP_PKEY_CTX *ctx);
+    int (*paramgen_init) (EVP_PKEY_CTX *ctx);
+    int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+    int (*keygen_init) (EVP_PKEY_CTX *ctx);
+    int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+    int (*sign_init) (EVP_PKEY_CTX *ctx);
+    int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                 const unsigned char *tbs, size_t tbslen);
+    int (*verify_init) (EVP_PKEY_CTX *ctx);
+    int (*verify) (EVP_PKEY_CTX *ctx,
+                   const unsigned char *sig, size_t siglen,
+                   const unsigned char *tbs, size_t tbslen);
+    int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
+    int (*verify_recover) (EVP_PKEY_CTX *ctx,
+                           unsigned char *rout, size_t *routlen,
+                           const unsigned char *sig, size_t siglen);
+    int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+    int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                    EVP_MD_CTX *mctx);
+    int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+    int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
+                      EVP_MD_CTX *mctx);
+    int (*encrypt_init) (EVP_PKEY_CTX *ctx);
+    int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+                    const unsigned char *in, size_t inlen);
+    int (*decrypt_init) (EVP_PKEY_CTX *ctx);                                   
                
+    int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,     
                
+                    const unsigned char *in, size_t inlen);                    
                
+    int (*derive_init) (EVP_PKEY_CTX *ctx);                                    
                
+    int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);     
                
+    int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);               
                
+    int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);  
                
+    int (*digestsign) (EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,    
                
+                       const unsigned char *tbs, size_t tbslen);
+    int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, 
+                         size_t siglen, const unsigned char *tbs,              
                
+                         size_t tbslen);                                       
                
+    int (*check) (EVP_PKEY *pkey);
+    int (*public_check) (EVP_PKEY *pkey);                                      
                
+    int (*param_check) (EVP_PKEY *pkey);                                       
                
+
+    int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+} EVP_PKEY_METHOD;
+
+
+ica_x25519_ctx_new_t           p_ica_x25519_ctx_new;
+ica_x448_ctx_new_t             p_ica_x448_ctx_new;
+ica_ed25519_ctx_new_t          p_ica_ed25519_ctx_new;
+ica_ed448_ctx_new_t            p_ica_ed448_ctx_new;
+ica_x25519_key_set_t           p_ica_x25519_key_set;
+ica_x448_key_set_t             p_ica_x448_key_set;
+ica_ed25519_key_set_t          p_ica_ed25519_key_set;
+ica_ed448_key_set_t            p_ica_ed448_key_set;
+ica_x25519_key_get_t           p_ica_x25519_key_get;
+ica_x448_key_get_t             p_ica_x448_key_get;
+ica_ed25519_key_get_t          p_ica_ed25519_key_get;
+ica_ed448_key_get_t            p_ica_ed448_key_get;
+ica_x25519_key_gen_t           p_ica_x25519_key_gen;
+ica_x448_key_gen_t             p_ica_x448_key_gen;
+ica_ed25519_key_gen_t          p_ica_ed25519_key_gen;
+ica_ed448_key_gen_t            p_ica_ed448_key_gen;
+ica_x25519_derive_t            p_ica_x25519_derive;
+ica_x448_derive_t              p_ica_x448_derive;
+ica_ed25519_sign_t             p_ica_ed25519_sign;
+ica_ed448_sign_t               p_ica_ed448_sign;
+ica_ed25519_verify_t           p_ica_ed25519_verify;
+ica_ed448_verify_t             p_ica_ed448_verify;
+ica_x25519_ctx_del_t           p_ica_x25519_ctx_del;
+ica_x448_ctx_del_t             p_ica_x448_ctx_del;
+ica_ed25519_ctx_del_t          p_ica_ed25519_ctx_del;
+ica_ed448_ctx_del_t            p_ica_ed448_ctx_del;
+
+static EVP_PKEY_METHOD *ibmca_x25519_pmeth = NULL;
+static EVP_PKEY_METHOD *ibmca_x448_pmeth = NULL;
+static EVP_PKEY_METHOD *ibmca_ed25519_pmeth = NULL;
+static EVP_PKEY_METHOD *ibmca_ed448_pmeth = NULL;
+
+/* X25519 */
+
+static int ibmca_x25519_keygen(EVP_PKEY_CTX *c, EVP_PKEY *pkey)
+{
+    unsigned char priv[32], pub[32], *private = NULL;
+    ECX_KEY *key = NULL;
+    ICA_X25519_CTX *ctx = NULL;
+    int rc = 0;
+
+    if (ica_x25519_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_KEYGEN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+    if (ica_x25519_key_gen(ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+    if (ica_x25519_key_get(ctx, priv, pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    key = calloc(1, sizeof(ECX_KEY));
+    private = calloc(1, sizeof(priv));
+    if (key == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    memcpy(private, priv, sizeof(priv));
+    memcpy(key, pub, sizeof(pub));
+    key->priv = private;
+
+    EVP_PKEY_assign(pkey, NID_X25519, key);
+    rc = 1;
+ret:
+    if (rc == 0) {
+        free(key);
+        free(private);
+    }
+    if (ctx != NULL)
+        ica_x25519_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    if (type == EVP_PKEY_CTRL_PEER_KEY)
+        return 1;
+
+    return -2;
+}
+
+static int ibmca_x25519_derive(EVP_PKEY_CTX *pkey_ctx, unsigned char *key, 
size_t *keylen)
+{
+    ICA_X25519_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL, *peerkey_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL, *peerkey_pkey = NULL;
+    int rc = 0;
+
+    *keylen = 32;
+    if (key == NULL) {
+        rc = 1;
+        goto ret;
+    }
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx);
+    peerkey_pkey = EVP_PKEY_CTX_get0_peerkey(pkey_ctx);
+    if (key_pkey == NULL || peerkey_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    peerkey_ecx = EVP_PKEY_get0(peerkey_pkey);
+    if (key_ecx == NULL || peerkey_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_x25519_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_DERIVE, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_x25519_key_set(ctx, key_ecx->priv, NULL) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X25519_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;;
+    }
+
+    if (ica_x25519_derive(ctx, key, peerkey_ecx->pub) != 0)
+        goto ret;
+
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_x25519_ctx_del(&ctx);
+    return rc;
+}
+
+/* X448 */
+
+static int ibmca_x448_keygen(EVP_PKEY_CTX *c, EVP_PKEY *pkey)
+{
+    unsigned char priv[56], pub[56], *private = NULL;
+    ECX_KEY *key = NULL;
+    ICA_X448_CTX *ctx = NULL;
+    int rc = 0;
+
+    if (ica_x448_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_KEYGEN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+    if (ica_x448_key_gen(ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+    if (ica_x448_key_get(ctx, priv, pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    key = calloc(1, sizeof(ECX_KEY));
+    private = calloc(1, sizeof(priv));
+    if (key == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    memcpy(private, priv, sizeof(priv));
+    memcpy(key, pub, sizeof(pub));
+    key->priv = private;
+
+    EVP_PKEY_assign(pkey, NID_X448, key);
+    rc = 1;
+ret:
+    if (rc == 0) {
+        free(key);
+        free(private);
+    }
+    if (ctx != NULL)
+        ica_x448_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_x448_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    if (type == EVP_PKEY_CTRL_PEER_KEY)
+        return 1;
+
+    return -2;
+}
+
+static int ibmca_x448_derive(EVP_PKEY_CTX *pkey_ctx, unsigned char *key, 
size_t *keylen)
+{
+    ICA_X448_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL, *peerkey_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL, *peerkey_pkey = NULL;
+    int rc = 0;
+
+    *keylen = 56;
+    if (key == NULL) {
+        rc = 1;
+        goto ret;
+    }
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx);
+    peerkey_pkey = EVP_PKEY_CTX_get0_peerkey(pkey_ctx);
+    if (key_pkey == NULL || peerkey_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    peerkey_ecx = EVP_PKEY_get0(peerkey_pkey);
+    if (key_ecx == NULL || peerkey_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_x448_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_DERIVE, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_x448_key_set(ctx, key_ecx->priv, NULL) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_X448_DERIVE, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;;
+    }
+
+    if (ica_x448_derive(ctx, key, peerkey_ecx->pub) != 0)
+        goto ret;
+
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_x448_ctx_del(&ctx);
+    return rc;
+}
+
+/* ED25519 */
+
+static int ibmca_ed25519_copy(EVP_PKEY_CTX *to, EVP_PKEY_CTX *from)
+{
+    return 1;
+}
+
+static int ibmca_ed25519_keygen(EVP_PKEY_CTX *c, EVP_PKEY *pkey)
+{
+    unsigned char priv[32], pub[32], *private = NULL;
+    ECX_KEY *key = NULL;
+    ICA_ED25519_CTX *ctx = NULL;
+    int rc = 0;
+
+    if (ica_ed25519_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_KEYGEN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+    if (ica_ed25519_key_gen(ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+    if (ica_ed25519_key_get(ctx, priv, pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    key = calloc(1, sizeof(ECX_KEY));
+    private = calloc(1, sizeof(priv));
+    if (key == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    memcpy(private, priv, sizeof(priv));
+    memcpy(key, pub, sizeof(pub));
+    key->priv = private;
+
+    EVP_PKEY_assign(pkey, NID_ED25519, key);
+    rc = 1;
+ret:
+    if (rc == 0) {
+        free(key);
+        free(private);
+    }
+    if (ctx != NULL)
+        ica_ed25519_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_ed25519_sign(EVP_MD_CTX *md_ctx, unsigned char *sig,
+                              size_t *siglen, const unsigned char *tbs,
+                              size_t tbslen)
+{
+    ICA_ED25519_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL;
+    int rc = 0;
+
+    if (sig == NULL) {
+        *siglen = 2 * 32;
+        return 1;
+    }
+
+    if (*siglen < 2 * 32)
+        goto ret;
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(md_ctx));
+    if (key_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    if (key_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed25519_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_SIGN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_ed25519_key_set(ctx, key_ecx->priv, NULL) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;;
+    }
+
+    if (ica_ed25519_sign(ctx, sig, tbs, tbslen) != 0)
+        goto ret;
+
+    *siglen = 2 * 32;
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_ed25519_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_ed25519_verify(EVP_MD_CTX *md_ctx, const unsigned char *sig,
+                                size_t siglen, const unsigned char *tbv,
+                                size_t tbvlen)
+{
+    ICA_ED25519_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL;
+    int rc = 0;
+
+    if (sig == NULL || siglen != 2 * 32)
+        goto ret;
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(md_ctx));
+    if (key_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    if (key_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed25519_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_VERIFY, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_ed25519_key_set(ctx, NULL, key_ecx->pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED25519_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed25519_verify(ctx, sig, tbv, tbvlen) != 0)
+        goto ret;
+
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_ed25519_ctx_del(&ctx);
+    return rc;
+}
+
+/* ED448 */
+
+static int ibmca_ed448_copy(EVP_PKEY_CTX *to, EVP_PKEY_CTX *from)
+{
+    return 1;
+}
+
+static int ibmca_ed448_keygen(EVP_PKEY_CTX *c, EVP_PKEY *pkey)
+{
+    unsigned char priv[57], pub[57], *private = NULL;
+    ECX_KEY *key = NULL;
+    ICA_ED448_CTX *ctx = NULL;
+    int rc = 0;
+
+    if (ica_ed448_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_KEYGEN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+    if (ica_ed448_key_gen(ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+    if (ica_ed448_key_get(ctx, priv, pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    key = calloc(1, sizeof(ECX_KEY));
+    private = calloc(1, sizeof(priv));
+    if (key == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_KEYGEN, IBMCA_R_PKEY_KEYGEN_FAILED);
+        goto ret;
+    }
+
+    memcpy(private, priv, sizeof(priv));
+    memcpy(key, pub, sizeof(pub));
+    key->priv = private;
+
+    EVP_PKEY_assign(pkey, NID_ED448, key);
+    rc = 1;
+ret:
+    if (rc == 0) {
+        free(key);
+        free(private);
+    }
+    if (ctx != NULL)
+        ica_ed448_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_ed448_sign(EVP_MD_CTX *md_ctx, unsigned char *sig,
+                              size_t *siglen, const unsigned char *tbs,
+                              size_t tbslen)
+{
+    ICA_ED448_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL;
+    int rc = 0;
+
+    if (sig == NULL) {
+        *siglen = 2 * 57;
+        return 1;
+    }
+
+    if (*siglen < 2 * 57)
+        goto ret;
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(md_ctx));
+    if (key_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    if (key_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed448_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_SIGN, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_ed448_key_set(ctx, key_ecx->priv, NULL) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_SIGN, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;;
+    }
+
+    if (ica_ed448_sign(ctx, sig, tbs, tbslen) != 0)
+        goto ret;
+
+    *siglen = 2 * 57;
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_ed448_ctx_del(&ctx);
+    return rc;
+}
+
+static int ibmca_ed448_verify(EVP_MD_CTX *md_ctx, const unsigned char *sig,
+                                size_t siglen, const unsigned char *tbv,
+                                size_t tbvlen)
+{
+    ICA_ED448_CTX *ctx = NULL;
+    ECX_KEY *key_ecx = NULL;
+    EVP_PKEY *key_pkey = NULL;
+    int rc = 0;
+
+    if (sig == NULL || siglen != 2 * 57)
+        goto ret;
+
+    key_pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(md_ctx));
+    if (key_pkey == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    key_ecx = EVP_PKEY_get0(key_pkey);
+    if (key_ecx == NULL) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed448_ctx_new(&ctx) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_VERIFY, IBMCA_R_PKEY_INTERNAL_ERROR);
+        goto ret;
+    }
+
+    if (ica_ed448_key_set(ctx, NULL, key_ecx->pub) != 0) {
+        IBMCAerr(IBMCA_F_IBMCA_ED448_VERIFY, IBMCA_R_PKEY_KEYS_NOT_SET);
+        goto ret;
+    }
+
+    if (ica_ed448_verify(ctx, sig, tbv, tbvlen) != 0)
+        goto ret;
+
+    rc = 1;
+ret:
+    if (ctx != NULL)
+        ica_ed448_ctx_del(&ctx);
+    return rc;
+}
+
+/* Methods */
+
+static int ibmca_ed_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    switch (type) {
+    case EVP_PKEY_CTRL_MD:
+        /* Only NULL allowed as digest */
+        if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
+            return 1;
+        return 0;
+
+    case EVP_PKEY_CTRL_DIGESTINIT:
+        return 1;
+    }
+    return -2;
+}
+
+const EVP_PKEY_METHOD *ibmca_x25519(void)
+{
+    if (ibmca_x25519_pmeth != NULL)
+        goto ret;
+
+    ibmca_x25519_pmeth = EVP_PKEY_meth_new(NID_X25519, 0);
+    if (ibmca_x25519_pmeth == NULL)
+        goto ret;
+
+    EVP_PKEY_meth_set_ctrl(ibmca_x25519_pmeth, ibmca_x25519_ctrl, NULL);
+    EVP_PKEY_meth_set_keygen(ibmca_x25519_pmeth, NULL, ibmca_x25519_keygen);
+    EVP_PKEY_meth_set_derive(ibmca_x25519_pmeth, NULL, ibmca_x25519_derive);
+
+ret:
+    return ibmca_x25519_pmeth;
+}
+
+const EVP_PKEY_METHOD *ibmca_x448(void)
+{
+    if (ibmca_x448_pmeth != NULL)
+        goto ret;
+
+    ibmca_x448_pmeth = EVP_PKEY_meth_new(NID_X448, 0);
+    if (ibmca_x448_pmeth == NULL)
+        goto ret;
+
+    EVP_PKEY_meth_set_ctrl(ibmca_x448_pmeth, ibmca_x448_ctrl, NULL);
+    EVP_PKEY_meth_set_keygen(ibmca_x448_pmeth, NULL, ibmca_x448_keygen);
+    EVP_PKEY_meth_set_derive(ibmca_x448_pmeth, NULL, ibmca_x448_derive);
+
+ret:
+    return ibmca_x448_pmeth;
+}
+
+const EVP_PKEY_METHOD *ibmca_ed25519(void)
+{
+    if (ibmca_ed25519_pmeth != NULL)
+        goto ret;
+
+    ibmca_ed25519_pmeth = EVP_PKEY_meth_new(NID_ED25519, 
EVP_PKEY_FLAG_SIGCTX_CUSTOM);
+    if (ibmca_ed25519_pmeth == NULL)
+        goto ret;
+
+    EVP_PKEY_meth_set_ctrl(ibmca_ed25519_pmeth, ibmca_ed_ctrl, NULL);
+    EVP_PKEY_meth_set_copy(ibmca_ed25519_pmeth, ibmca_ed25519_copy);
+    EVP_PKEY_meth_set_keygen(ibmca_ed25519_pmeth, NULL, ibmca_ed25519_keygen);
+    ibmca_ed25519_pmeth->digestsign = ibmca_ed25519_sign;
+    ibmca_ed25519_pmeth->digestverify = ibmca_ed25519_verify;
+
+ret:
+    return ibmca_ed25519_pmeth;
+}
+
+const EVP_PKEY_METHOD *ibmca_ed448(void)
+{
+    if (ibmca_ed448_pmeth != NULL)
+        goto ret;
+
+    ibmca_ed448_pmeth = EVP_PKEY_meth_new(NID_ED448, 
EVP_PKEY_FLAG_SIGCTX_CUSTOM);
+    if (ibmca_ed448_pmeth == NULL)
+        goto ret;
+
+    EVP_PKEY_meth_set_ctrl(ibmca_ed448_pmeth, ibmca_ed_ctrl, NULL);
+    EVP_PKEY_meth_set_copy(ibmca_ed448_pmeth, ibmca_ed448_copy);
+    EVP_PKEY_meth_set_keygen(ibmca_ed448_pmeth, NULL, ibmca_ed448_keygen);
+    ibmca_ed448_pmeth->digestsign = ibmca_ed448_sign;
+    ibmca_ed448_pmeth->digestverify = ibmca_ed448_verify;
+
+ret:
+    return ibmca_ed448_pmeth;
+}
+
+void ibmca_x25519_destroy(void)
+{
+    if (ibmca_x25519_pmeth != NULL) {
+        EVP_PKEY_meth_free(ibmca_x25519_pmeth);
+        ibmca_x25519_pmeth = NULL;
+    }
+}
+
+void ibmca_x448_destroy(void)
+{
+    if (ibmca_x448_pmeth != NULL) {
+        EVP_PKEY_meth_free(ibmca_x448_pmeth);
+        ibmca_x448_pmeth = NULL;
+    }
+}
+
+void ibmca_ed25519_destroy(void)
+{
+    if (ibmca_ed25519_pmeth != NULL) {
+        EVP_PKEY_meth_free(ibmca_ed25519_pmeth);
+        ibmca_ed25519_pmeth = NULL;
+    }
+}
+
+void ibmca_ed448_destroy(void)
+{
+    if (ibmca_ed448_pmeth != NULL) {
+        EVP_PKEY_meth_free(ibmca_ed448_pmeth);
+        ibmca_ed448_pmeth = NULL;
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/openssl.cnf.sample 
new/openssl-ibmca-2.1.0/src/openssl.cnf.sample
--- old/openssl-ibmca-2.0.3/src/openssl.cnf.sample      2019-04-23 
18:15:44.000000000 +0200
+++ new/openssl-ibmca-2.1.0/src/openssl.cnf.sample      2019-09-09 
02:07:21.000000000 +0200
@@ -13,13 +13,10 @@
 [openssl_def]
 engines = engine_section
 
-
 [engine_section]
 ibmca = ibmca_section
 
-
 [ibmca_section]
-
 # The openssl engine path for ibmca.so.
 # Set the dynamic_path to where the ibmca.so engine
 # resides on the system.
@@ -64,5 +61,7 @@
 # DIGESTS
 # - SHA1, SHA256, SHA512 digests
 #
+# PKEY_CRYPTO
+# - X25519, X448, ED25519, ED448
 default_algorithms = ALL
-#default_algorithms = RAND,RSA,DH,DSA,CIPHERS,DIGESTS
+#default_algorithms = PKEY_CRYPTO,RAND,RSA,DH,DSA,CIPHERS,DIGESTS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openssl-ibmca-2.0.3/src/test/Makefile.linux 
new/openssl-ibmca-2.1.0/src/test/Makefile.linux
--- old/openssl-ibmca-2.0.3/src/test/Makefile.linux     2019-04-23 
18:15:44.000000000 +0200
+++ new/openssl-ibmca-2.1.0/src/test/Makefile.linux     2019-09-09 
02:07:21.000000000 +0200
@@ -8,7 +8,7 @@
 
 # Every target is created from a single .c file.
 %: %.c
-       gcc $(OPTS) -lica -lcrypto -o $@ $^
+       gcc $(OPTS) -o $@ $^ -lica -lcrypto
 
 clean:
        rm -f $(TARGETS)


Reply via email to