Download raw body.
openssh: refactor PKCS#11 and add support for Ed25519
Hi,
This refactor's OpenSSH's PKCS#11 code to remove its use of libcrypto
methods (RSA_set_method / EC_KEY_set_method) in favour of supporting
these keys in a way similar to how we hook in support for FIDO keys.
On top of the refactor, it adds support for Ed25519 keys held in
PKCS#11 tokens. Yubikeys with recent firmware and softhsm2 are known
to work at least.
FWIW I used this sequence of commands to generate a Ed25519 key on
my Yubikey:
ykman piv keys generate -a ED25519 --pin-policy=ONCE \
--touch-policy=CACHED 83 yubikey-piv-ed25519.pub
ykman piv certificates generate -s "djm usbc" -d 35600 \
83 yubikey-piv-ed25519.pub
It will prompt your for your management key, so have that at hand.
After generation, I can load the key into the agent with:
ssh-add -s /usr/local/lib/libykcs11.so.1.1
You'll need the yubico-piv-tool and yubikey-manager ports installed
for this.
-d
diff --git a/Makefile.inc b/Makefile.inc
index adf3c25..21b27d5 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -123,13 +123,12 @@ SRCS_PROT+= monitor_fdpass.c
SRCS_PROT+= nchan.c
SRCS_PROT+= ttymodes.c
-.if (${OPENSSL:L} == "yes")
SRCS_PKCS11+= ssh-pkcs11.c
SRCS_PKCS11_CLIENT+= ssh-pkcs11-client.c
+
+.if (${OPENSSL:L} == "yes")
SRCS_MODULI+= moduli.c
.else
-SRCS_PKCS11+=
-SRCS_PKCS11_CLIENT+=
SRCS_MODULI+=
.endif
diff --git a/ssh-add/Makefile b/ssh-add/Makefile
index 69b50f6..80bdf7b 100644
--- a/ssh-add/Makefile
+++ b/ssh-add/Makefile
@@ -5,7 +5,7 @@
SRCS= ssh-add.c
SRCS+= authfd.c cleanup.c fatal.c readpass.c utf8.c hostfile.c hmac.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_UTL}
-SRCS+= ${SRCS_SK_CLIENT}
+SRCS+= ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT}
PROG= ssh-add
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index aa59b33..e9da78d 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -318,8 +318,7 @@ ssh_ecdsa_sign(struct sshkey *key,
const BIGNUM *sig_r, *sig_s;
int hash_alg;
size_t slen = 0;
- struct sshbuf *b = NULL, *bb = NULL;
- int len = 0, ret = SSH_ERR_INTERNAL_ERROR;
+ int ret = SSH_ERR_INTERNAL_ERROR;
if (lenp != NULL)
*lenp = 0;
@@ -342,11 +341,37 @@ ssh_ecdsa_sign(struct sshkey *key,
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
- if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
- ret = SSH_ERR_ALLOC_FAIL;
- goto out;
- }
ECDSA_SIG_get0(esig, &sig_r, &sig_s);
+
+ if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s,
+ sigp, lenp)) != 0)
+ goto out;
+ /* success */
+ ret = 0;
+ out:
+ freezero(sigb, slen);
+ ECDSA_SIG_free(esig);
+ return ret;
+}
+
+int
+ssh_ecdsa_encode_store_sig(const struct sshkey *key,
+ const BIGNUM *sig_r, const BIGNUM *sig_s,
+ u_char **sigp, size_t *lenp)
+{
+ struct sshbuf *b = NULL, *bb = NULL;
+ int ret;
+ size_t len;
+
+ if (lenp != NULL)
+ *lenp = 0;
+ if (sigp != NULL)
+ *sigp = NULL;
+
+ if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) {
+ ret = SSH_ERR_ALLOC_FAIL;
+ goto out;
+ }
if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
(ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
goto out;
@@ -365,10 +390,8 @@ ssh_ecdsa_sign(struct sshkey *key,
*lenp = len;
ret = 0;
out:
- freezero(sigb, slen);
sshbuf_free(b);
sshbuf_free(bb);
- ECDSA_SIG_free(esig);
return ret;
}
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 06c6a04..561d657 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -146,10 +146,9 @@ ssh_ed25519_sign(struct sshkey *key,
const char *alg, const char *sk_provider, const char *sk_pin, u_int compat)
{
u_char *sig = NULL;
- size_t slen = 0, len;
+ size_t slen = 0;
unsigned long long smlen;
int r, ret;
- struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
@@ -170,13 +169,40 @@ ssh_ed25519_sign(struct sshkey *key,
r = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */
goto out;
}
+ if ((r = ssh_ed25519_encode_store_sig(sig, smlen - datalen,
+ sigp, lenp)) != 0)
+ goto out;
+
+ /* success */
+ r = 0;
+ out:
+ freezero(sig, slen);
+ return r;
+}
+
+int
+ssh_ed25519_encode_store_sig(const u_char *sig, size_t slen,
+ u_char **sigp, size_t *lenp)
+{
+ struct sshbuf *b = NULL;
+ int r = -1;
+ size_t len;
+
+ if (lenp != NULL)
+ *lenp = 0;
+ if (sigp != NULL)
+ *sigp = NULL;
+
+ if (slen != crypto_sign_ed25519_BYTES)
+ return SSH_ERR_INVALID_ARGUMENT;
+
/* encode signature */
if ((b = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_put_cstring(b, "ssh-ed25519")) != 0 ||
- (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0)
+ (r = sshbuf_put_string(b, sig, slen)) != 0)
goto out;
len = sshbuf_len(b);
if (sigp != NULL) {
@@ -192,9 +218,6 @@ ssh_ed25519_sign(struct sshkey *key,
r = 0;
out:
sshbuf_free(b);
- if (sig != NULL)
- freezero(sig, slen);
-
return r;
}
diff --git a/ssh-keyscan/Makefile b/ssh-keyscan/Makefile
index 49981aa..0542a07 100644
--- a/ssh-keyscan/Makefile
+++ b/ssh-keyscan/Makefile
@@ -5,7 +5,7 @@
SRCS= ssh-keyscan.c
SRCS+= atomicio.c cleanup.c compat.c hostfile.c ssh_api.c dns.c fatal.c
SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXC} ${SRCS_KEXS} ${SRCS_KEY} \
- ${SRCS_PKT} ${SRCS_UTL} ${SRCS_SK_CLIENT}
+ ${SRCS_PKT} ${SRCS_UTL} ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT}
PROG= ssh-keyscan
BINDIR= /usr/bin
diff --git a/ssh-keysign/Makefile b/ssh-keysign/Makefile
index 90ef21b..4712dd4 100644
--- a/ssh-keysign/Makefile
+++ b/ssh-keysign/Makefile
@@ -6,7 +6,7 @@ SRCS= ssh-keysign.c readconf.c compat.c
SRCS+= cleanup.c fatal.c
SRCS+= uidswap.c utf8.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} ${SRCS_PKT} \
- ${SRCS_UTL} ${SRCS_SK_CLIENT}
+ ${SRCS_UTL} ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT}
PROG= ssh-keysign
BINOWN= root
BINMODE=4555
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index 205139f..eca1504 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -44,17 +44,14 @@
/*
* Maintain a list of ssh-pkcs11-helper subprocesses. These may be looked up
- * by provider path or their unique EC/RSA METHOD pointers.
+ * by provider path or their unique keyblobs.
*/
struct helper {
char *path;
pid_t pid;
int fd;
- RSA_METHOD *rsa_meth;
- EC_KEY_METHOD *ec_meth;
- int (*rsa_finish)(RSA *rsa);
- void (*ec_finish)(EC_KEY *key);
- size_t nrsa, nec; /* number of active keys of each type */
+ size_t nkeyblobs;
+ struct sshbuf **keyblobs; /* XXX use a tree or something faster */
};
static struct helper **helpers;
static size_t nhelpers;
@@ -75,56 +72,75 @@ helper_by_provider(const char *path)
}
static struct helper *
-helper_by_rsa(const RSA *rsa)
+helper_by_key(const struct sshkey *key)
{
- size_t i;
- const RSA_METHOD *meth;
+ size_t i, j;
+ struct sshbuf *keyblob = NULL;
+ int r;
+
+ if ((keyblob = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(key, keyblob)) != 0)
+ fatal_fr(r, "serialise key");
- if ((meth = RSA_get_method(rsa)) == NULL)
- return NULL;
for (i = 0; i < nhelpers; i++) {
- if (helpers[i] != NULL && helpers[i]->rsa_meth == meth)
- return helpers[i];
+ if (helpers[i] == NULL)
+ continue;
+ for (j = 0; j < helpers[i]->nkeyblobs; j++) {
+ if (sshbuf_equals(keyblob,
+ helpers[i]->keyblobs[j]) == 0) {
+ sshbuf_free(keyblob);
+ return helpers[i];
+ }
+ }
}
+ sshbuf_free(keyblob);
return NULL;
}
-static struct helper *
-helper_by_ec(const EC_KEY *ec)
+static void
+helper_add_key(struct helper *helper, struct sshkey *key)
{
- size_t i;
- const EC_KEY_METHOD *meth;
-
- if ((meth = EC_KEY_get_method(ec)) == NULL)
- return NULL;
- for (i = 0; i < nhelpers; i++) {
- if (helpers[i] != NULL && helpers[i]->ec_meth == meth)
- return helpers[i];
- }
- return NULL;
+ int r;
+ helper->keyblobs = xrecallocarray(helper->keyblobs, helper->nkeyblobs,
+ helper->nkeyblobs + 1, sizeof(*helper->keyblobs));
+ if ((helper->keyblobs[helper->nkeyblobs] = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(key, helper->keyblobs[helper->nkeyblobs])) != 0)
+ fatal_fr(r, "shkey_putb failed");
+ helper->nkeyblobs++;
+ debug3_f("added %s key for provider %s, now has %zu keys",
+ sshkey_type(key), helper->path, helper->nkeyblobs);
}
static void
-helper_free(struct helper *helper)
+helper_terminate(struct helper *helper)
{
size_t i;
int found = 0;
if (helper == NULL)
return;
- if (helper->path == NULL || helper->ec_meth == NULL ||
- helper->rsa_meth == NULL)
+ if (helper->path == NULL)
fatal_f("inconsistent helper");
- debug3_f("free helper for provider %s", helper->path);
+
+ debug3_f("terminating helper for %s; remaining %zu keys",
+ helper->path, helper->nkeyblobs);
+
+ close(helper->fd);
+ /* XXX waitpid() */
+ helper->fd = -1;
+ helper->pid = -1;
+
+ /* repack helpers */
for (i = 0; i < nhelpers; i++) {
if (helpers[i] == helper) {
if (found)
fatal_f("helper recorded more than once");
found = 1;
- }
- else if (found)
+ } else if (found)
helpers[i - 1] = helpers[i];
}
if (found) {
@@ -132,37 +148,12 @@ helper_free(struct helper *helper)
nhelpers - 1, sizeof(*helpers));
nhelpers--;
}
+ for (i = 0; i < helper->nkeyblobs; i++)
+ sshbuf_free(helper->keyblobs[i]);
free(helper->path);
- EC_KEY_METHOD_free(helper->ec_meth);
- RSA_meth_free(helper->rsa_meth);
free(helper);
}
-static void
-helper_terminate(struct helper *helper)
-{
- if (helper == NULL) {
- return;
- } else if (helper->fd == -1) {
- debug3_f("already terminated");
- } else {
- debug3_f("terminating helper for %s; "
- "remaining %zu RSA %zu ECDSA",
- helper->path, helper->nrsa, helper->nec);
- close(helper->fd);
- /* XXX waitpid() */
- helper->fd = -1;
- helper->pid = -1;
- }
- /*
- * Don't delete the helper entry until there are no remaining keys
- * that reference it. Otherwise, any signing operation would call
- * a free'd METHOD pointer and that would be bad.
- */
- if (helper->nrsa == 0 && helper->nec == 0)
- helper_free(helper);
-}
-
static void
send_msg(int fd, struct sshbuf *m)
{
@@ -232,196 +223,61 @@ pkcs11_terminate(void)
helper_terminate(helpers[i]);
}
-static int
-rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
+int
+pkcs11_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
{
- struct sshkey *key = NULL;
struct sshbuf *msg = NULL;
- u_char *blob = NULL, *signature = NULL;
- size_t blen, slen = 0;
- int r, ret = -1;
struct helper *helper;
+ int status, r;
+ u_char *signature = NULL;
+ size_t signature_len = 0;
+ int ret = SSH_ERR_INTERNAL_ERROR;
- if ((helper = helper_by_rsa(rsa)) == NULL || helper->fd == -1)
- fatal_f("no helper for PKCS11 key");
- debug3_f("signing with PKCS11 provider %s", helper->path);
- if (padding != RSA_PKCS1_PADDING)
- goto fail;
- if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
- error_f("sshkey_new failed");
- goto fail;
- }
- if ((key->pkey = EVP_PKEY_new()) == NULL ||
- EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) {
- error_f("pkey setup failed");
- goto fail;
- }
+ if (sigp != NULL)
+ *sigp = NULL;
+ if (lenp != NULL)
+ *lenp = 0;
+
+ if ((helper = helper_by_key(key)) == NULL || helper->fd == -1)
+ fatal_f("no helper for %s key", sshkey_type(key));
- key->type = KEY_RSA;
- if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
- error_fr(r, "encode key");
- goto fail;
- }
if ((msg = sshbuf_new()) == NULL)
- fatal_f("sshbuf_new failed");
+ return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
- (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
- (r = sshbuf_put_string(msg, from, flen)) != 0 ||
- (r = sshbuf_put_u32(msg, 0)) != 0)
+ (r = sshkey_puts_plain(key, msg)) != 0 ||
+ (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
+ (r = sshbuf_put_cstring(msg, alg == NULL ? "" : alg)) != 0 ||
+ (r = sshbuf_put_u32(msg, compat)) != 0)
fatal_fr(r, "compose");
send_msg(helper->fd, msg);
sshbuf_reset(msg);
- if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
- if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
- fatal_fr(r, "parse");
- if (slen <= (size_t)RSA_size(rsa)) {
- memcpy(to, signature, slen);
- ret = slen;
- }
- free(signature);
- }
- fail:
- free(blob);
- sshkey_free(key);
- sshbuf_free(msg);
- return (ret);
-}
-
-static int
-rsa_finish(RSA *rsa)
-{
- struct helper *helper;
-
- if ((helper = helper_by_rsa(rsa)) == NULL)
- fatal_f("no helper for PKCS11 key");
- debug3_f("free PKCS11 RSA key for provider %s", helper->path);
- if (helper->rsa_finish != NULL)
- helper->rsa_finish(rsa);
- if (helper->nrsa == 0)
- fatal_f("RSA refcount error");
- helper->nrsa--;
- debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA",
- helper->path, helper->nrsa, helper->nec);
- if (helper->nrsa == 0 && helper->nec == 0)
- helper_terminate(helper);
- return 1;
-}
-
-static ECDSA_SIG *
-ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
- const BIGNUM *rp, EC_KEY *ec)
-{
- struct sshkey *key = NULL;
- struct sshbuf *msg = NULL;
- ECDSA_SIG *ret = NULL;
- const u_char *cp;
- u_char *blob = NULL, *signature = NULL;
- size_t blen, slen = 0;
- int r, nid;
- struct helper *helper;
-
- if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1)
- fatal_f("no helper for PKCS11 key");
- debug3_f("signing with PKCS11 provider %s", helper->path);
-
- if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
- error_f("sshkey_new failed");
- goto fail;
- }
- if ((key->pkey = EVP_PKEY_new()) == NULL ||
- EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) {
- error("pkey setup failed");
- goto fail;
- }
- if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) {
- error("couldn't get curve nid");
+ if ((status = recv_msg(helper->fd, msg)) != SSH2_AGENT_SIGN_RESPONSE) {
+ /* XXX translate status to something useful */
+ debug_fr(r, "recv_msg");
+ ret = SSH_ERR_AGENT_FAILURE;
goto fail;
}
- key->ecdsa_nid = nid;
- key->type = KEY_ECDSA;
- if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
- error_fr(r, "encode key");
- goto fail;
- }
- if ((msg = sshbuf_new()) == NULL)
- fatal_f("sshbuf_new failed");
- if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
- (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
- (r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 ||
- (r = sshbuf_put_u32(msg, 0)) != 0)
- fatal_fr(r, "compose");
- send_msg(helper->fd, msg);
- sshbuf_reset(msg);
+ if ((r = sshbuf_get_string(msg, &signature, &signature_len)) != 0)
+ fatal_fr(r, "parse");
- if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
- if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
- fatal_fr(r, "parse");
- cp = signature;
- ret = d2i_ECDSA_SIG(NULL, &cp, slen);
- free(signature);
+ /* success */
+ if (sigp != NULL) {
+ *sigp = signature;
+ signature = NULL;
}
+ if (lenp != NULL)
+ *lenp = signature_len;
+ ret = 0;
fail:
- free(blob);
- sshkey_free(key);
sshbuf_free(msg);
- return (ret);
-}
-
-static void
-ecdsa_do_finish(EC_KEY *ec)
-{
- struct helper *helper;
-
- if ((helper = helper_by_ec(ec)) == NULL)
- fatal_f("no helper for PKCS11 key");
- debug3_f("free PKCS11 ECDSA key for provider %s", helper->path);
- if (helper->ec_finish != NULL)
- helper->ec_finish(ec);
- if (helper->nec == 0)
- fatal_f("ECDSA refcount error");
- helper->nec--;
- debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA",
- helper->path, helper->nrsa, helper->nec);
- if (helper->nrsa == 0 && helper->nec == 0)
- helper_terminate(helper);
-}
-
-/* redirect private key crypto operations to the ssh-pkcs11-helper */
-static void
-wrap_key(struct helper *helper, struct sshkey *k)
-{
- RSA *rsa = NULL;
- EC_KEY *ecdsa = NULL;
-
- debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path);
- if (k->type == KEY_RSA) {
- if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL)
- fatal_f("no RSA key");
- if (RSA_set_method(rsa, helper->rsa_meth) != 1)
- fatal_f("RSA_set_method failed");
- if (helper->nrsa++ >= INT_MAX)
- fatal_f("RSA refcount error");
- if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1)
- fatal_f("EVP_PKEY_set1_RSA failed");
- RSA_free(rsa);
- } else if (k->type == KEY_ECDSA) {
- if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL)
- fatal_f("no ECDSA key");
- if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1)
- fatal_f("EC_KEY_set_method failed");
- if (helper->nec++ >= INT_MAX)
- fatal_f("EC refcount error");
- if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1)
- fatal_f("EVP_PKEY_set1_EC_KEY failed");
- EC_KEY_free(ecdsa);
- } else
- fatal_f("unknown key type");
- k->flags |= SSHKEY_FLAG_EXT;
- debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA",
- helper->path, helper->nrsa, helper->nec);
+ return ret;
}
/*
@@ -435,11 +291,13 @@ pkcs11_make_cert(const struct sshkey *priv,
struct helper *helper = NULL;
struct sshkey *ret;
int r;
- RSA *rsa_priv = NULL, *rsa_cert = NULL;
- EC_KEY *ec_priv = NULL, *ec_cert = NULL;
- debug3_f("private key type %s cert type %s", sshkey_type(priv),
- sshkey_type(certpub));
+ if ((helper = helper_by_key(priv)) == NULL || helper->fd == -1)
+ fatal_f("no helper for %s key", sshkey_type(priv));
+
+ debug3_f("private key type %s cert type %s on provider %s",
+ sshkey_type(priv), sshkey_type(certpub), helper->path);
+
*certprivp = NULL;
if (!sshkey_is_cert(certpub) || sshkey_is_cert(priv) ||
!sshkey_equal_public(priv, certpub)) {
@@ -448,91 +306,24 @@ pkcs11_make_cert(const struct sshkey *priv,
return SSH_ERR_INVALID_ARGUMENT;
}
*certprivp = NULL;
- if (priv->type == KEY_RSA) {
- if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL)
- fatal_f("no RSA pkey");
- if ((helper = helper_by_rsa(rsa_priv)) == NULL ||
- helper->fd == -1)
- fatal_f("no helper for PKCS11 RSA key");
- if ((r = sshkey_from_private(priv, &ret)) != 0)
- fatal_fr(r, "copy key");
- if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL)
- fatal_f("no RSA cert pkey");
- if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1)
- fatal_f("RSA_set_method failed");
- if (helper->nrsa++ >= INT_MAX)
- fatal_f("RSA refcount error");
- if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1)
- fatal_f("EVP_PKEY_set1_RSA failed");
- RSA_free(rsa_priv);
- RSA_free(rsa_cert);
- } else if (priv->type == KEY_ECDSA) {
- if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL)
- fatal_f("no EC pkey");
- if ((helper = helper_by_ec(ec_priv)) == NULL ||
- helper->fd == -1)
- fatal_f("no helper for PKCS11 EC key");
- if ((r = sshkey_from_private(priv, &ret)) != 0)
- fatal_fr(r, "copy key");
- if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL)
- fatal_f("no EC cert pkey");
- if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1)
- fatal_f("EC_KEY_set_method failed");
- if (helper->nec++ >= INT_MAX)
- fatal_f("EC refcount error");
- if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1)
- fatal_f("EVP_PKEY_set1_EC_KEY failed");
- EC_KEY_free(ec_priv);
- EC_KEY_free(ec_cert);
- } else
- fatal_f("unknown key type %s", sshkey_type(priv));
+ if ((r = sshkey_from_private(priv, &ret)) != 0)
+ fatal_fr(r, "copy key");
ret->flags |= SSHKEY_FLAG_EXT;
if ((r = sshkey_to_certified(ret)) != 0 ||
(r = sshkey_cert_copy(certpub, ret)) != 0)
fatal_fr(r, "graft certificate");
- debug3_f("provider %s remaining keys: %zu RSA %zu ECDSA",
- helper->path, helper->nrsa, helper->nec);
+
+ helper_add_key(helper, ret);
+
+ debug3_f("provider %s: %zu remaining keys",
+ helper->path, helper->nkeyblobs);
+
/* success */
*certprivp = ret;
return 0;
}
-static int
-pkcs11_start_helper_methods(struct helper *helper)
-{
- int (*ec_init)(EC_KEY *key);
- int (*ec_copy)(EC_KEY *dest, const EC_KEY *src);
- int (*ec_set_group)(EC_KEY *key, const EC_GROUP *grp);
- int (*ec_set_private)(EC_KEY *key, const BIGNUM *priv_key);
- int (*ec_set_public)(EC_KEY *key, const EC_POINT *pub_key);
- int (*ec_sign)(int, const unsigned char *, int, unsigned char *,
- unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
- RSA_METHOD *rsa_meth;
- EC_KEY_METHOD *ec_meth;
-
- if ((ec_meth = EC_KEY_METHOD_new(EC_KEY_OpenSSL())) == NULL)
- return -1;
- EC_KEY_METHOD_get_sign(ec_meth, &ec_sign, NULL, NULL);
- EC_KEY_METHOD_set_sign(ec_meth, ec_sign, NULL, ecdsa_do_sign);
- EC_KEY_METHOD_get_init(ec_meth, &ec_init, &helper->ec_finish,
- &ec_copy, &ec_set_group, &ec_set_private, &ec_set_public);
- EC_KEY_METHOD_set_init(ec_meth, ec_init, ecdsa_do_finish,
- ec_copy, ec_set_group, ec_set_private, ec_set_public);
-
- if ((rsa_meth = RSA_meth_dup(RSA_get_default_method())) == NULL)
- fatal_f("RSA_meth_dup failed");
- helper->rsa_finish = RSA_meth_get_finish(rsa_meth);
- if (!RSA_meth_set1_name(rsa_meth, "ssh-pkcs11-helper") ||
- !RSA_meth_set_priv_enc(rsa_meth, rsa_encrypt) ||
- !RSA_meth_set_finish(rsa_meth, rsa_finish))
- fatal_f("failed to prepare method");
-
- helper->ec_meth = ec_meth;
- helper->rsa_meth = rsa_meth;
- return 0;
-}
-
static struct helper *
pkcs11_start_helper(const char *path)
{
@@ -549,17 +340,10 @@ pkcs11_start_helper(const char *path)
return NULL;
}
helper = xcalloc(1, sizeof(*helper));
- if (pkcs11_start_helper_methods(helper) == -1) {
- error_f("pkcs11_start_helper_methods failed");
- goto fail;
- }
if ((pid = fork()) == -1) {
error_f("fork: %s", strerror(errno));
- fail:
close(pair[0]);
close(pair[1]);
- RSA_meth_free(helper->rsa_meth);
- EC_KEY_METHOD_free(helper->ec_meth);
free(helper);
return NULL;
} else if (pid == 0) {
@@ -599,10 +383,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
{
struct sshkey *k;
int r, type;
- u_char *blob;
char *label;
- size_t blen;
- u_int nkeys, i;
+ u_int ret = -1, nkeys, i;
struct sshbuf *msg;
struct helper *helper;
@@ -610,6 +392,8 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
(helper = pkcs11_start_helper(name)) == NULL)
return -1;
+ debug3_f("add %s", helper->path);
+
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 ||
@@ -620,35 +404,39 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
sshbuf_reset(msg);
type = recv_msg(helper->fd, msg);
+ debug3_f("response %d", type);
if (type == SSH2_AGENT_IDENTITIES_ANSWER) {
if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
fatal_fr(r, "parse nkeys");
+ debug3_f("helper return %u keys", nkeys);
*keysp = xcalloc(nkeys, sizeof(struct sshkey *));
if (labelsp)
*labelsp = xcalloc(nkeys, sizeof(char *));
for (i = 0; i < nkeys; i++) {
/* XXX clean up properly instead of fatal() */
- if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
+ if ((r = sshkey_froms(msg, &k)) != 0 ||
(r = sshbuf_get_cstring(msg, &label, NULL)) != 0)
fatal_fr(r, "parse key");
- if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
- fatal_fr(r, "decode key");
- wrap_key(helper, k);
+ k->flags |= SSHKEY_FLAG_EXT;
+ helper_add_key(helper, k);
(*keysp)[i] = k;
if (labelsp)
(*labelsp)[i] = label;
else
free(label);
- free(blob);
}
+ /* success */
+ ret = 0;
} else if (type == SSH2_AGENT_FAILURE) {
if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
- nkeys = -1;
- } else {
- nkeys = -1;
+ error_fr(r, "failed to parse failure response");
+ }
+ if (ret != 0) {
+ debug_f("no keys; terminate helper");
+ helper_terminate(helper);
}
sshbuf_free(msg);
- return (nkeys);
+ return ret == 0 ? nkeys : -1;
}
int
@@ -665,3 +453,39 @@ pkcs11_del_provider(char *name)
helper_terminate(helper);
return 0;
}
+
+void
+pkcs11_key_free(struct sshkey *key)
+{
+ struct helper *helper;
+ struct sshbuf *keyblob = NULL;
+ size_t i;
+ int r, found = 0;
+
+ debug3_f("free %s key", sshkey_type(key));
+
+ if ((helper = helper_by_key(key)) == NULL || helper->fd == -1)
+ fatal_f("no helper for %s key", sshkey_type(key));
+ if ((keyblob = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(key, keyblob)) != 0)
+ fatal_fr(r, "serialise key");
+
+ /* repack keys */
+ for (i = 0; i < helper->nkeyblobs; i++) {
+ if (sshbuf_equals(keyblob, helper->keyblobs[i]) == 0) {
+ if (found)
+ fatal_f("key recorded more than once");
+ found = 1;
+ } else if (found)
+ helper->keyblobs[i - 1] = helper->keyblobs[i];
+ }
+ if (found) {
+ helper->keyblobs = xrecallocarray(helper->keyblobs,
+ helper->nkeyblobs, helper->nkeyblobs - 1,
+ sizeof(*helper->keyblobs));
+ helper->nkeyblobs--;
+ }
+ if (helper->nkeyblobs == 0)
+ helper_terminate(helper);
+}
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c
index 3f79a00..8d8d34a 100644
--- a/ssh-pkcs11-helper.c
+++ b/ssh-pkcs11-helper.c
@@ -35,19 +35,9 @@
#include "ssh-pkcs11.h"
#include "ssherr.h"
-#ifdef WITH_OPENSSL
-#include <openssl/ec.h>
-#include <openssl/rsa.h>
-
/* borrows code from sftp-server and ssh-agent */
-struct pkcs11_keyinfo {
- struct sshkey *key;
- char *providername, *label;
- TAILQ_ENTRY(pkcs11_keyinfo) next;
-};
-
-TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
+static char *providername; /* Provider for this helper */
#define MAX_MSG_LENGTH 10240 /*XXX*/
@@ -55,50 +45,6 @@ TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
struct sshbuf *iqueue;
struct sshbuf *oqueue;
-static void
-add_key(struct sshkey *k, char *name, char *label)
-{
- struct pkcs11_keyinfo *ki;
-
- ki = xcalloc(1, sizeof(*ki));
- ki->providername = xstrdup(name);
- ki->key = k;
- ki->label = xstrdup(label);
- TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
-}
-
-static void
-del_keys_by_name(char *name)
-{
- struct pkcs11_keyinfo *ki, *nxt;
-
- for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) {
- nxt = TAILQ_NEXT(ki, next);
- if (!strcmp(ki->providername, name)) {
- TAILQ_REMOVE(&pkcs11_keylist, ki, next);
- free(ki->providername);
- free(ki->label);
- sshkey_free(ki->key);
- free(ki);
- }
- }
-}
-
-/* lookup matching 'private' key */
-static struct sshkey *
-lookup_key(struct sshkey *k)
-{
- struct pkcs11_keyinfo *ki;
-
- TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
- debug("check %s %s %s", sshkey_type(ki->key),
- ki->providername, ki->label);
- if (sshkey_equal(k, ki->key))
- return (ki->key);
- }
- return (NULL);
-}
-
static void
send_msg(struct sshbuf *m)
{
@@ -111,34 +57,32 @@ send_msg(struct sshbuf *m)
static void
process_add(void)
{
- char *name, *pin;
+ char *pin;
struct sshkey **keys = NULL;
int r, i, nkeys;
- u_char *blob;
- size_t blen;
struct sshbuf *msg;
char **labels = NULL;
+ if (providername != NULL)
+ fatal_f("provider already set");
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
- if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
+ if ((r = sshbuf_get_cstring(iqueue, &providername, NULL)) != 0 ||
(r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
fatal_fr(r, "parse");
- if ((nkeys = pkcs11_add_provider(name, pin, &keys, &labels)) > 0) {
+ debug3_f("add %s", providername);
+ if ((nkeys = pkcs11_add_provider(providername, pin,
+ &keys, &labels)) > 0) {
if ((r = sshbuf_put_u8(msg,
SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
(r = sshbuf_put_u32(msg, nkeys)) != 0)
fatal_fr(r, "compose");
for (i = 0; i < nkeys; i++) {
- if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) {
- debug_fr(r, "encode key");
- continue;
- }
- if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
+ if ((r = sshkey_puts(keys[i], msg)) != 0 ||
(r = sshbuf_put_cstring(msg, labels[i])) != 0)
fatal_fr(r, "compose key");
- free(blob);
- add_key(keys[i], name, labels[i]);
+ debug3_f("%s: %s \"%s\"", providername,
+ sshkey_type(keys[i]), labels[i]);
free(labels[i]);
}
} else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0 ||
@@ -147,29 +91,6 @@ process_add(void)
free(labels);
free(keys); /* keys themselves are transferred to pkcs11_keylist */
free(pin);
- free(name);
- send_msg(msg);
- sshbuf_free(msg);
-}
-
-static void
-process_del(void)
-{
- char *name, *pin;
- struct sshbuf *msg;
- int r;
-
- if ((msg = sshbuf_new()) == NULL)
- fatal_f("sshbuf_new failed");
- if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
- (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
- fatal_fr(r, "parse");
- del_keys_by_name(name);
- if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ?
- SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
- fatal_fr(r, "compose");
- free(pin);
- free(name);
send_msg(msg);
sshbuf_free(msg);
}
@@ -177,57 +98,32 @@ process_del(void)
static void
process_sign(void)
{
- u_char *blob, *data, *signature = NULL;
- size_t blen, dlen;
- u_int slen = 0;
- int len, r, ok = -1;
- struct sshkey *key = NULL, *found;
+ const u_char *data;
+ u_char *signature = NULL;
+ size_t dlen, slen = 0;
+ u_int compat;
+ int r, ok = -1;
+ struct sshkey *key = NULL;
struct sshbuf *msg;
- RSA *rsa = NULL;
- EC_KEY *ecdsa = NULL;
+ char *alg = NULL;
- /* XXX support SHA2 signature flags */
- if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
- (r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 ||
- (r = sshbuf_get_u32(iqueue, NULL)) != 0)
+ if ((r = sshkey_froms(iqueue, &key)) != 0 ||
+ (r = sshbuf_get_string_direct(iqueue, &data, &dlen)) != 0 ||
+ (r = sshbuf_get_cstring(iqueue, &alg, NULL)) != 0 ||
+ (r = sshbuf_get_u32(iqueue, &compat)) != 0)
fatal_fr(r, "parse");
- if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
- fatal_fr(r, "decode key");
- if ((found = lookup_key(key)) == NULL)
+ if (*alg == '\0') {
+ free(alg);
+ alg = NULL;
+ }
+
+ if ((r = pkcs11_sign(key, &signature, &slen, data, dlen,
+ alg, NULL, NULL, compat)) != 0) {
+ error_fr(r, "sign %s", sshkey_type(key));
goto reply;
-
- /* XXX use pkey API properly for signing */
- switch (key->type) {
- case KEY_RSA:
- if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL)
- fatal_f("no RSA in pkey");
- if ((len = RSA_size(rsa)) < 0)
- fatal_f("bad RSA length");
- signature = xmalloc(len);
- if ((len = RSA_private_encrypt(dlen, data, signature,
- rsa, RSA_PKCS1_PADDING)) < 0) {
- error_f("RSA_private_encrypt failed");
- goto reply;
- }
- slen = (u_int)len;
- break;
- case KEY_ECDSA:
- if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL)
- fatal_f("no ECDSA in pkey");
- if ((len = ECDSA_size(ecdsa)) < 0)
- fatal_f("bad ECDSA length");
- slen = (u_int)len;
- signature = xmalloc(slen);
- /* "The parameter type is ignored." */
- if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) {
- error_f("ECDSA_sign failed");
- goto reply;
- }
- break;
- default:
- fatal_f("unsupported key type %d", key->type);
}
+
/* success */
ok = 0;
reply:
@@ -242,10 +138,7 @@ process_sign(void)
fatal_fr(r, "compose failure response");
}
sshkey_free(key);
- RSA_free(rsa);
- EC_KEY_free(ecdsa);
- free(data);
- free(blob);
+ free(alg);
free(signature);
send_msg(msg);
sshbuf_free(msg);
@@ -281,10 +174,6 @@ process(void)
debug("process_add");
process_add();
break;
- case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
- debug("process_del");
- process_del();
- break;
case SSH2_AGENTC_SIGN_REQUEST:
debug("process_sign");
process_sign();
@@ -316,7 +205,6 @@ cleanup_exit(int i)
_exit(i);
}
-
int
main(int argc, char **argv)
{
@@ -328,8 +216,6 @@ main(int argc, char **argv)
extern char *__progname;
struct pollfd pfd[2];
- TAILQ_INIT(&pkcs11_keylist);
-
log_init(__progname, log_level, log_facility, log_stderr);
while ((ch = getopt(argc, argv, "v")) != -1) {
@@ -417,18 +303,3 @@ main(int argc, char **argv)
fatal_fr(r, "reserve");
}
}
-
-#else /* WITH_OPENSSL */
-void
-cleanup_exit(int i)
-{
- _exit(i);
-}
-
-int
-main(int argc, char **argv)
-{
- fprintf(stderr, "PKCS#11 code is not enabled\n");
- return 1;
-}
-#endif /* WITH_OPENSSL */
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 0174255..6a2682a 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -25,19 +25,25 @@
#include <string.h>
#include <dlfcn.h>
+#ifdef WITH_OPENSSL
#include <openssl/ecdsa.h>
#include <openssl/x509.h>
#include <openssl/err.h>
+#endif
#define CRYPTOKI_COMPAT
#include "pkcs11.h"
+#define SSHKEY_INTERNAL
+#include "sshkey.h"
+
#include "log.h"
#include "misc.h"
-#include "sshkey.h"
+#include "sshbuf.h"
#include "ssh-pkcs11.h"
#include "digest.h"
#include "xmalloc.h"
+#include "crypto_api.h"
struct pkcs11_slotinfo {
CK_TOKEN_INFO token;
@@ -61,15 +67,19 @@ struct pkcs11_provider {
TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
struct pkcs11_key {
+ struct sshbuf *keyblob;
struct pkcs11_provider *provider;
CK_ULONG slotidx;
char *keyid;
int keyid_len;
+ TAILQ_ENTRY(pkcs11_key) next;
};
+TAILQ_HEAD(, pkcs11_key) pkcs11_keys; /* XXX a tree would be better */
+
int pkcs11_interactive = 0;
-#ifdef HAVE_DLOPEN
+#ifdef WITH_OPENSSL
static void
ossl_error(const char *msg)
{
@@ -81,14 +91,6 @@ ossl_error(const char *msg)
}
#endif
-int
-pkcs11_init(int interactive)
-{
- pkcs11_interactive = interactive;
- TAILQ_INIT(&pkcs11_providers);
- return (0);
-}
-
/*
* finalize a provider shared library, it's no longer usable.
* however, there might still be keys referencing this provider,
@@ -138,19 +140,6 @@ pkcs11_provider_unref(struct pkcs11_provider *p)
}
}
-/* unregister all providers, keys might still point to the providers */
-void
-pkcs11_terminate(void)
-{
- struct pkcs11_provider *p;
-
- while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) {
- TAILQ_REMOVE(&pkcs11_providers, p, next);
- pkcs11_provider_finalize(p);
- pkcs11_provider_unref(p);
- }
-}
-
/* lookup provider by name */
static struct pkcs11_provider *
pkcs11_provider_lookup(char *provider_id)
@@ -181,24 +170,17 @@ pkcs11_del_provider(char *provider_id)
}
#ifdef HAVE_DLOPEN
-static RSA_METHOD *rsa_method;
-static int rsa_idx = 0;
-static EC_KEY_METHOD *ec_key_method;
-static int ec_key_idx = 0;
/* release a wrapped object */
static void
-pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
- long argl, void *argp)
+pkcs11_k11_free(struct pkcs11_key *k11)
{
- struct pkcs11_key *k11 = ptr;
-
- debug_f("parent %p ptr %p idx %d", parent, ptr, idx);
if (k11 == NULL)
return;
if (k11->provider)
pkcs11_provider_unref(k11->provider);
free(k11->keyid);
+ sshbuf_free(k11->keyblob);
free(k11);
}
@@ -408,82 +390,42 @@ pkcs11_get_key(struct pkcs11_key *k11, CK_MECHANISM_TYPE mech_type)
return (0);
}
-/* openssl callback doing the actual signing operation */
+/* record the key information later use lookup by keyblob */
static int
-pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
- int padding)
+pkcs11_record_key(struct pkcs11_provider *provider, CK_ULONG slotidx,
+ CK_ATTRIBUTE *keyid_attrib, struct sshkey *key)
{
- struct pkcs11_key *k11;
- struct pkcs11_slotinfo *si;
- CK_FUNCTION_LIST *f;
- CK_ULONG tlen = 0;
- CK_RV rv;
- int rval = -1;
-
- if ((k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) {
- error("RSA_get_ex_data failed");
- return (-1);
- }
-
- if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) {
- error("pkcs11_get_key failed");
- return (-1);
+ struct sshbuf *keyblob;
+ struct pkcs11_key *k11;
+ int r;
+ char *hex;
+
+ hex = tohex(keyid_attrib->pValue, keyid_attrib->ulValueLen);
+ debug_f("%s key: provider %s slot %lu keyid %s",
+ sshkey_type(key), provider->name, (u_long)slotidx, hex);
+ free(hex);
+
+ if ((keyblob = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(key, keyblob)) != 0)
+ fatal_fr(r, "sshkey_putb");
+
+ /* Check if we've already recorded this key in a different slot */
+ TAILQ_FOREACH(k11, &pkcs11_keys, next) {
+ if (sshbuf_equals(k11->keyblob, keyblob) == 0) {
+ hex = tohex(k11->keyid, k11->keyid_len);
+ debug_f("Already seen this key at "
+ "provider %s slot %lu keyid %s",
+ k11->provider->name, k11->slotidx, hex);
+ free(hex);
+ sshbuf_free(keyblob);
+ return -1;
+ }
}
- f = k11->provider->function_list;
- si = &k11->provider->slotinfo[k11->slotidx];
- tlen = RSA_size(rsa);
-
- /* XXX handle CKR_BUFFER_TOO_SMALL */
- rv = f->C_Sign(si->session, (CK_BYTE *)from, flen, to, &tlen);
- if (rv == CKR_OK)
- rval = tlen;
- else
- error("C_Sign failed: %lu", rv);
-
- return (rval);
-}
-
-static int
-pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
- int padding)
-{
- return (-1);
-}
-
-static int
-pkcs11_rsa_start_wrapper(void)
-{
- if (rsa_method != NULL)
- return (0);
- rsa_method = RSA_meth_dup(RSA_get_default_method());
- if (rsa_method == NULL)
- return (-1);
- rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa",
- NULL, NULL, pkcs11_k11_free);
- if (rsa_idx == -1)
- return (-1);
- if (!RSA_meth_set1_name(rsa_method, "pkcs11") ||
- !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) ||
- !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) {
- error_f("setup pkcs11 method failed");
- return (-1);
- }
- return (0);
-}
-
-/* redirect private key operations for rsa key to pkcs11 token */
-static int
-pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
- CK_ATTRIBUTE *keyid_attrib, RSA *rsa)
-{
- struct pkcs11_key *k11;
-
- if (pkcs11_rsa_start_wrapper() == -1)
- return (-1);
-
k11 = xcalloc(1, sizeof(*k11));
k11->provider = provider;
+ k11->keyblob = keyblob;
provider->refcount++; /* provider referenced by RSA key */
k11->slotidx = slotidx;
/* identify key object on smartcard */
@@ -492,127 +434,340 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
}
+ TAILQ_INSERT_TAIL(&pkcs11_keys, k11, next);
- if (RSA_set_method(rsa, rsa_method) != 1)
- fatal_f("RSA_set_method failed");
- if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1)
- fatal_f("RSA_set_ex_data failed");
- return (0);
+ return 0;
}
-/* openssl callback doing the actual signing operation */
-static ECDSA_SIG *
-ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
- const BIGNUM *rp, EC_KEY *ec)
+/* retrieve the key information by keyblob */
+static struct pkcs11_key *
+pkcs11_lookup_key(struct sshkey *key)
+{
+ struct pkcs11_key *k11, *found = NULL;
+ struct sshbuf *keyblob;
+ int r;
+
+ if ((keyblob = sshbuf_new()) == NULL)
+ fatal_f("sshbuf_new failed");
+ if ((r = sshkey_putb(key, keyblob)) != 0)
+ fatal_fr(r, "sshkey_putb");
+ TAILQ_FOREACH(k11, &pkcs11_keys, next) {
+ if (sshbuf_equals(k11->keyblob, keyblob) == 0) {
+ found = k11;
+ break;
+ }
+ }
+ sshbuf_free(keyblob);
+ return found;
+}
+
+#ifdef WITH_OPENSSL
+/*
+ * See:
+ * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
+ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn
+ */
+
+/*
+ * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
+ * oiw(14) secsig(3) algorithms(2) 26 }
+ */
+static const u_char id_sha1[] = {
+ 0x30, 0x21, /* type Sequence, length 0x21 (33) */
+ 0x30, 0x09, /* type Sequence, length 0x09 */
+ 0x06, 0x05, /* type OID, length 0x05 */
+ 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */
+ 0x05, 0x00, /* NULL */
+ 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */
+};
+
+/*
+ * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
+ * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
+ * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
+ * id-sha256(1) }
+ */
+static const u_char id_sha256[] = {
+ 0x30, 0x31, /* type Sequence, length 0x31 (49) */
+ 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
+ 0x06, 0x09, /* type OID, length 0x09 */
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */
+ 0x05, 0x00, /* NULL */
+ 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */
+};
+
+/*
+ * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html
+ * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840)
+ * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2)
+ * id-sha256(3) }
+ */
+static const u_char id_sha512[] = {
+ 0x30, 0x51, /* type Sequence, length 0x51 (81) */
+ 0x30, 0x0d, /* type Sequence, length 0x0d (13) */
+ 0x06, 0x09, /* type OID, length 0x09 */
+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */
+ 0x05, 0x00, /* NULL */
+ 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */
+};
+
+static int
+rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp)
+{
+ switch (hash_alg) {
+ case SSH_DIGEST_SHA1:
+ *oidp = id_sha1;
+ *oidlenp = sizeof(id_sha1);
+ break;
+ case SSH_DIGEST_SHA256:
+ *oidp = id_sha256;
+ *oidlenp = sizeof(id_sha256);
+ break;
+ case SSH_DIGEST_SHA512:
+ *oidp = id_sha512;
+ *oidlenp = sizeof(id_sha512);
+ break;
+ default:
+ return SSH_ERR_INVALID_ARGUMENT;
+ }
+ return 0;
+}
+
+static int
+pkcs11_sign_rsa(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
{
struct pkcs11_key *k11;
struct pkcs11_slotinfo *si;
CK_FUNCTION_LIST *f;
- CK_ULONG siglen = 0, bnlen;
+ CK_ULONG slen = 0;
CK_RV rv;
- ECDSA_SIG *ret = NULL;
- u_char *sig;
- BIGNUM *r = NULL, *s = NULL;
+ int hashalg, r, diff, siglen, ret = -1;
+ u_char *oid_dgst = NULL, *sig = NULL;
+ size_t dgst_len, oid_len, oid_dgst_len = 0;
+ const u_char *oid;
+
+ if (sigp != NULL)
+ *sigp = 0;
+ if (lenp != NULL)
+ *lenp = 0;
+
+ if ((k11 = pkcs11_lookup_key(key)) == NULL) {
+ error_f("no key found");
+ return SSH_ERR_KEY_NOT_FOUND;
+ }
+
+ debug3_f("sign with alg \"%s\" using provider %s slotidx %lu",
+ alg == NULL ? "" : alg, k11->provider->name, (u_long)k11->slotidx);
+
+ if (pkcs11_get_key(k11, CKM_RSA_PKCS) == -1) {
+ error("pkcs11_get_key failed");
+ return SSH_ERR_AGENT_FAILURE;
+ }
+
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+
+ if ((siglen = EVP_PKEY_size(key->pkey)) <= 0)
+ return SSH_ERR_INVALID_ARGUMENT;
+ sig = xmalloc(siglen);
+ slen = (CK_ULONG)siglen;
+
+ /* Determine hash algorithm and OID for signature */
+ if (alg == NULL || *alg == '\0')
+ hashalg = SSH_DIGEST_SHA1;
+ else if ((hashalg = ssh_rsa_hash_id_from_keyname(alg)) == -1)
+ fatal_f("couldn't determine RSA hash alg \"%s\"", alg);
+ if ((r = rsa_hash_alg_oid(hashalg, &oid, &oid_len)) != 0)
+ fatal_fr(r, "rsa_hash_alg_oid failed");
+ if ((dgst_len = ssh_digest_bytes(hashalg)) == 0)
+ fatal_f("bad hash alg %d", hashalg);
+
+ /* Prepare { oid || digest } */
+ oid_dgst_len = oid_len + dgst_len;
+ oid_dgst = xcalloc(1, oid_dgst_len);
+ memcpy(oid_dgst, oid, oid_len);
+ if ((r = ssh_digest_memory(hashalg, data, datalen,
+ oid_dgst + oid_len, dgst_len)) == -1)
+ fatal_fr(r, "hash failed");
+
+ /* XXX handle CKR_BUFFER_TOO_SMALL */
+ if ((rv = f->C_Sign(si->session, (CK_BYTE *)oid_dgst,
+ oid_dgst_len, sig, &slen)) != CKR_OK) {
+ error("C_Sign failed: %lu", rv);
+ goto done;
+ }
+
+ if (slen < (CK_ULONG)siglen) {
+ diff = siglen - slen;
+ debug3_f("repack %lu < %d (diff %d)",
+ (u_long)slen, siglen, diff);
+ memmove(sig + diff, sig, slen);
+ explicit_bzero(sig, diff);
+ } else if (slen > (size_t)siglen)
+ fatal_f("bad C_Sign length");
+
+ if ((ret = ssh_rsa_encode_store_sig(hashalg, sig, siglen,
+ sigp, lenp)) != 0)
+ fatal_fr(ret, "couldn't store signature");
+
+ /* success */
+ ret = 0;
+ done:
+ freezero(oid_dgst, oid_dgst_len);
+ free(sig);
+ return ret;
+}
+
+static int
+pkcs11_sign_ecdsa(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
+{
+ struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_ULONG slen = 0, bnlen;
+ CK_RV rv;
+ BIGNUM *sig_r = NULL, *sig_s = NULL;
+ u_char *sig = NULL, *dgst = NULL;
+ size_t dgst_len = 0;
+ int hashalg, ret = -1, r, siglen;
+
+ if (sigp != NULL)
+ *sigp = 0;
+ if (lenp != NULL)
+ *lenp = 0;
- if ((k11 = EC_KEY_get_ex_data(ec, ec_key_idx)) == NULL) {
- ossl_error("EC_KEY_get_ex_data failed for ec");
- return (NULL);
+ if ((k11 = pkcs11_lookup_key(key)) == NULL) {
+ error_f("no key found");
+ return SSH_ERR_KEY_NOT_FOUND;
}
if (pkcs11_get_key(k11, CKM_ECDSA) == -1) {
error("pkcs11_get_key failed");
- return (NULL);
+ return SSH_ERR_AGENT_FAILURE;
}
+ debug3_f("sign using provider %s slotidx %lu",
+ k11->provider->name, (u_long)k11->slotidx);
+
f = k11->provider->function_list;
si = &k11->provider->slotinfo[k11->slotidx];
- siglen = ECDSA_size(ec);
+ /* Prepare digest to be signed */
+ if ((hashalg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1)
+ fatal_f("couldn't determine ECDSA hash alg");
+ if ((dgst_len = ssh_digest_bytes(hashalg)) == 0)
+ fatal_f("bad hash alg %d", hashalg);
+ dgst = xcalloc(1, dgst_len);
+ if ((r = ssh_digest_memory(hashalg, data, datalen,
+ dgst, dgst_len)) == -1)
+ fatal_fr(r, "hash failed");
+
+ if ((siglen = EVP_PKEY_size(key->pkey)) <= 0)
+ return SSH_ERR_INVALID_ARGUMENT;
sig = xmalloc(siglen);
+ slen = (CK_ULONG)siglen;
/* XXX handle CKR_BUFFER_TOO_SMALL */
- rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &siglen);
+ rv = f->C_Sign(si->session, (CK_BYTE *)dgst, dgst_len, sig, &slen);
if (rv != CKR_OK) {
error("C_Sign failed: %lu", rv);
goto done;
}
- if (siglen < 64 || siglen > 132 || siglen % 2) {
- error_f("bad signature length: %lu", (u_long)siglen);
+ if (slen < 64 || slen > 132 || slen % 2) {
+ error_f("bad signature length: %lu", (u_long)slen);
goto done;
}
- bnlen = siglen/2;
- if ((ret = ECDSA_SIG_new()) == NULL) {
- error("ECDSA_SIG_new failed");
- goto done;
- }
- if ((r = BN_bin2bn(sig, bnlen, NULL)) == NULL ||
- (s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) {
+ bnlen = slen/2;
+ if ((sig_r = BN_bin2bn(sig, bnlen, NULL)) == NULL ||
+ (sig_s = BN_bin2bn(sig+bnlen, bnlen, NULL)) == NULL) {
ossl_error("BN_bin2bn failed");
- ECDSA_SIG_free(ret);
- ret = NULL;
goto done;
}
- if (!ECDSA_SIG_set0(ret, r, s)) {
- error_f("ECDSA_SIG_set0 failed");
- ECDSA_SIG_free(ret);
- ret = NULL;
- goto done;
- }
- r = s = NULL; /* now owned by ret */
+
+ if ((ret = ssh_ecdsa_encode_store_sig(key, sig_r, sig_s,
+ sigp, lenp)) != 0)
+ fatal_fr(ret, "couldn't store signature");
+
/* success */
+ ret = 0;
done:
- BN_free(r);
- BN_free(s);
+ freezero(dgst, dgst_len);
+ BN_free(sig_r);
+ BN_free(sig_s);
free(sig);
-
- return (ret);
-}
-
-static int
-pkcs11_ecdsa_start_wrapper(void)
-{
- int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
- unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
-
- if (ec_key_method != NULL)
- return (0);
- ec_key_idx = EC_KEY_get_ex_new_index(0, "ssh-pkcs11-ecdsa",
- NULL, NULL, pkcs11_k11_free);
- if (ec_key_idx == -1)
- return (-1);
- ec_key_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
- if (ec_key_method == NULL)
- return (-1);
- EC_KEY_METHOD_get_sign(ec_key_method, &orig_sign, NULL, NULL);
- EC_KEY_METHOD_set_sign(ec_key_method, orig_sign, NULL, ecdsa_do_sign);
- return (0);
+ return ret;
}
+#endif /* WITH_OPENSSL */
static int
-pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
- CK_ATTRIBUTE *keyid_attrib, EC_KEY *ec)
+pkcs11_sign_ed25519(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
{
struct pkcs11_key *k11;
+ struct pkcs11_slotinfo *si;
+ CK_FUNCTION_LIST *f;
+ CK_ULONG slen = 0;
+ CK_RV rv;
+ u_char *sig = NULL;
+ CK_BYTE *xdata = NULL;
+ int ret = -1;
- if (pkcs11_ecdsa_start_wrapper() == -1)
- return (-1);
-
- k11 = xcalloc(1, sizeof(*k11));
- k11->provider = provider;
- provider->refcount++; /* provider referenced by ECDSA key */
- k11->slotidx = slotidx;
- /* identify key object on smartcard */
- k11->keyid_len = keyid_attrib->ulValueLen;
- if (k11->keyid_len > 0) {
- k11->keyid = xmalloc(k11->keyid_len);
- memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
+ if (sigp != NULL)
+ *sigp = 0;
+ if (lenp != NULL)
+ *lenp = 0;
+
+ if ((k11 = pkcs11_lookup_key(key)) == NULL) {
+ error_f("no key found");
+ return SSH_ERR_KEY_NOT_FOUND;
+ }
+
+ if (pkcs11_get_key(k11, CKM_EDDSA) == -1) {
+ error("pkcs11_get_key failed");
+ return SSH_ERR_AGENT_FAILURE;
+ }
+
+ debug3_f("sign using provider %s slotidx %lu",
+ k11->provider->name, (u_long)k11->slotidx);
+
+ f = k11->provider->function_list;
+ si = &k11->provider->slotinfo[k11->slotidx];
+
+ xdata = xmalloc(datalen);
+ memcpy(xdata, data, datalen);
+ sig = xmalloc(crypto_sign_ed25519_BYTES);
+ slen = crypto_sign_ed25519_BYTES;
+
+ rv = f->C_Sign(si->session, xdata, datalen, sig, &slen);
+ if (rv != CKR_OK) {
+ error("C_Sign failed: %lu", rv);
+ goto done;
+ }
+ if (slen != crypto_sign_ed25519_BYTES) {
+ error_f("bad signature length: %lu", (u_long)slen);
+ goto done;
}
- if (EC_KEY_set_method(ec, ec_key_method) != 1)
- fatal_f("EC_KEY_set_method failed");
- if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1)
- fatal_f("EC_KEY_set_ex_data failed");
+ if ((ret = ssh_ed25519_encode_store_sig(sig, slen, sigp, lenp)) != 0)
+ fatal_fr(ret, "couldn't store signature");
- return (0);
+ /* success */
+ ret = 0;
+ done:
+ if (xdata != NULL)
+ freezero(xdata, datalen);
+ free(sig);
+ return ret;
}
/* remove trailing spaces */
@@ -691,6 +846,7 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
return (0);
}
+#ifdef WITH_OPENSSL
static struct sshkey *
pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_OBJECT_HANDLE *obj)
@@ -704,8 +860,7 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
EC_GROUP *group = NULL;
struct sshkey *key = NULL;
const unsigned char *attrp = NULL;
- int i;
- int nid;
+ int success = -1, r, i, nid;
memset(&key_attr, 0, sizeof(key_attr));
key_attr[0].type = CKA_ID;
@@ -779,6 +934,11 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
ossl_error("o2i_ECPublicKey failed");
goto fail;
}
+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec),
+ EC_KEY_get0_public_key(ec))) != 0) {
+ error_fr(r, "invalid EC key");
+ goto fail;
+ }
nid = sshkey_ecdsa_key_to_nid(ec);
if (nid < 0) {
@@ -786,9 +946,6 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto fail;
}
- if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec))
- goto fail;
-
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
error("sshkey_new failed");
@@ -803,8 +960,15 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
key->ecdsa_nid = nid;
key->type = KEY_ECDSA;
key->flags |= SSHKEY_FLAG_EXT;
-
+ if (pkcs11_record_key(p, slotidx, &key_attr[0], key))
+ goto fail;
+ /* success */
+ success = 0;
fail:
+ if (success != 0) {
+ sshkey_free(key);
+ key = NULL;
+ }
for (i = 0; i < 3; i++)
free(key_attr[i].pValue);
if (ec)
@@ -828,7 +992,7 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
RSA *rsa = NULL;
BIGNUM *rsa_n, *rsa_e;
struct sshkey *key = NULL;
- int i;
+ int i, success = -1;
memset(&key_attr, 0, sizeof(key_attr));
key_attr[0].type = CKA_ID;
@@ -884,9 +1048,6 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
fatal_f("set key");
rsa_n = rsa_e = NULL; /* transferred */
- if (pkcs11_rsa_wrap(p, slotidx, &key_attr[0], rsa))
- goto fail;
-
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
error("sshkey_new failed");
@@ -900,15 +1061,136 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
fatal("EVP_PKEY_set1_RSA failed");
key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT;
-
+ if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+ error_f("RSA key too small %d < minumum %d",
+ EVP_PKEY_bits(key->pkey), SSH_RSA_MINIMUM_MODULUS_SIZE);
+ goto fail;
+ }
+ if (pkcs11_record_key(p, slotidx, &key_attr[0], key))
+ goto fail;
+ /* success */
+ success = 0;
fail:
for (i = 0; i < 3; i++)
free(key_attr[i].pValue);
RSA_free(rsa);
+ if (success != 0) {
+ sshkey_free(key);
+ key = NULL;
+ }
+ return key;
+}
+#endif /* WITH_OPENSSL */
+
+static struct sshkey *
+pkcs11_fetch_ed25519_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
+ CK_OBJECT_HANDLE *obj)
+{
+ CK_ATTRIBUTE key_attr[3];
+ CK_SESSION_HANDLE session;
+ CK_FUNCTION_LIST *f = NULL;
+ CK_RV rv;
+ struct sshkey *key = NULL;
+ const unsigned char *d = NULL;
+ size_t len;
+ char *hex = NULL;
+ int success = -1, i;
+ const u_char oid1[14] = {
+ 0x13, 0x0c, 0x65, 0x64, 0x77, 0x61, 0x72, 0x64,
+ 0x73, 0x32, 0x35, 0x35, 0x31, 0x39,
+ }; /* PrintableString { "edwards25519" } */
+ const u_char oid2[5] = {
+ 0x06, 0x03, 0x2b, 0x65, 0x70,
+ }; /* OBJECT_IDENTIFIER { 1.3.101.112 } */
+
+ memset(&key_attr, 0, sizeof(key_attr));
+ key_attr[0].type = CKA_ID;
+ key_attr[1].type = CKA_EC_POINT; /* XXX or CKA_VALUE ? */
+ key_attr[2].type = CKA_EC_PARAMS;
+
+ session = p->slotinfo[slotidx].session;
+ f = p->function_list;
+
+ /* figure out size of the attributes */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ return (NULL);
+ }
+
+ /*
+ * Allow CKA_ID (always first attribute) to be empty, but
+ * ensure that none of the others are zero length.
+ * XXX assumes CKA_ID is always first.
+ */
+ if (key_attr[1].ulValueLen == 0 ||
+ key_attr[2].ulValueLen == 0) {
+ error("invalid attribute length");
+ return (NULL);
+ }
+
+ /* allocate buffers for attributes */
+ for (i = 0; i < 3; i++) {
+ if (key_attr[i].ulValueLen > 0)
+ key_attr[i].pValue = xcalloc(1, key_attr[i].ulValueLen);
+ }
+
+ /* retrieve ID, public point and curve parameters of EC key */
+ rv = f->C_GetAttributeValue(session, *obj, key_attr, 3);
+ if (rv != CKR_OK) {
+ error("C_GetAttributeValue failed: %lu", rv);
+ goto fail;
+ }
+
+ /* Expect one of the supported oids in CKA_EC_PARAMS */
+ d = (u_char *)key_attr[2].pValue;
+ len = key_attr[2].ulValueLen;
+ if ((len != sizeof(oid1) || memcmp(d, oid1, sizeof(oid1)) != 0) &&
+ (len != sizeof(oid2) || memcmp(d, oid2, sizeof(oid2)) != 0)) {
+ hex = tohex(d, len);
+ logit_f("unsupported CKA_EC_PARAMS: %s (len %zu)", hex, len);
+ goto fail;
+ }
+
+ /*
+ * Expect an either a raw 32 byte pubkey or an OCTET_STRING with
+ * a 32 byte pubkey in CKA_VALUE
+ */
+ d = (u_char *)key_attr[1].pValue;
+ len = key_attr[1].ulValueLen;
+ if (len != ED25519_PK_SZ + 2 && d[0] == 0x04 && d[1] == ED25519_PK_SZ) {
+ d += 2;
+ len -= 2;
+ }
+ if (len != ED25519_PK_SZ) {
+ hex = tohex(key_attr[1].pValue, key_attr[1].ulValueLen);
+ logit_f("CKA_EC_POINT invalid octet str: %s (len %lu)",
+ hex, (u_long)key_attr[1].ulValueLen);
+ goto fail;
+ }
- return (key);
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
+ fatal_f("sshkey_new failed");
+ key->ed25519_pk = xmalloc(ED25519_PK_SZ);
+ memcpy(key->ed25519_pk, d, ED25519_PK_SZ);
+ key->type = KEY_ED25519;
+ key->flags |= SSHKEY_FLAG_EXT;
+ if (pkcs11_record_key(p, slotidx, &key_attr[0], key))
+ goto fail;
+ /* success */
+ success = 0;
+ fail:
+ if (success != 0) {
+ sshkey_free(key);
+ key = NULL;
+ }
+ free(hex);
+ for (i = 0; i < 3; i++)
+ free(key_attr[i].pValue);
+ return key;
}
+#ifdef WITH_OPENSSL
static int
pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_OBJECT_HANDLE *obj, struct sshkey **keyp, char **labelp)
@@ -923,10 +1205,10 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
RSA *rsa = NULL;
EC_KEY *ec = NULL;
struct sshkey *key = NULL;
- int i;
- int nid;
+ int r, i, nid, success = -1;
const u_char *cp;
char *subject = NULL;
+ size_t len;
*keyp = NULL;
*labelp = NULL;
@@ -998,9 +1280,6 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
goto out;
}
- if (pkcs11_rsa_wrap(p, slotidx, &cert_attr[0], rsa))
- goto out;
-
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
error("sshkey_new failed");
@@ -1014,6 +1293,16 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
fatal("EVP_PKEY_set1_RSA failed");
key->type = KEY_RSA;
key->flags |= SSHKEY_FLAG_EXT;
+ if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+ error_f("RSA key too small %d < minumum %d",
+ EVP_PKEY_bits(key->pkey),
+ SSH_RSA_MINIMUM_MODULUS_SIZE);
+ goto out;
+ }
+ if (pkcs11_record_key(p, slotidx, &cert_attr[0], key))
+ goto out;
+ /* success */
+ success = 0;
} else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
if (EVP_PKEY_get0_EC_KEY(evp) == NULL) {
error("invalid x509; no ec key");
@@ -1023,16 +1312,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
error("EC_KEY_dup failed");
goto out;
}
-
+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ec),
+ EC_KEY_get0_public_key(ec))) != 0) {
+ error_fr(r, "invalid EC key");
+ goto out;
+ }
nid = sshkey_ecdsa_key_to_nid(ec);
if (nid < 0) {
error("couldn't get curve nid");
goto out;
}
- if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec))
- goto out;
-
key = sshkey_new(KEY_UNSPEC);
if (key == NULL) {
error("sshkey_new failed");
@@ -1047,6 +1337,30 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
key->ecdsa_nid = nid;
key->type = KEY_ECDSA;
key->flags |= SSHKEY_FLAG_EXT;
+ if (pkcs11_record_key(p, slotidx, &cert_attr[0], key))
+ goto out;
+ /* success */
+ success = 0;
+ } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_ED25519) {
+ if ((key = sshkey_new(KEY_UNSPEC)) == NULL ||
+ (key->ed25519_pk = calloc(1, ED25519_PK_SZ)) == NULL)
+ fatal_f("allocation failed");
+ len = ED25519_PK_SZ;
+ if (!EVP_PKEY_get_raw_public_key(evp, key->ed25519_pk, &len)) {
+ ossl_error("EVP_PKEY_get_raw_public_key failed");
+ goto out;
+ }
+ if (len != ED25519_PK_SZ) {
+ error_f("incorrect returned public key "
+ "length for ed25519");
+ goto out;
+ }
+ key->type = KEY_ED25519;
+ key->flags |= SSHKEY_FLAG_EXT;
+ if (pkcs11_record_key(p, slotidx, &cert_attr[0], key))
+ goto out;
+ /* success */
+ success = 0;
} else {
error("unknown certificate key type");
goto out;
@@ -1057,7 +1371,8 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
X509_free(x509);
RSA_free(rsa);
EC_KEY_free(ec);
- if (key == NULL) {
+ if (success != 0 || key == NULL) {
+ sshkey_free(key);
free(subject);
return -1;
}
@@ -1066,17 +1381,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
*labelp = subject;
return 0;
}
-
-#if 0
-static int
-have_rsa_key(const RSA *rsa)
-{
- const BIGNUM *rsa_n, *rsa_e;
-
- RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
- return rsa_n != NULL && rsa_e != NULL;
-}
-#endif
+#endif /* WITH_OPENSSL */
static void
note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context,
@@ -1094,6 +1399,7 @@ note_key(struct pkcs11_provider *p, CK_ULONG slotidx, const char *context,
free(fp);
}
+#ifdef WITH_OPENSSL /* libcrypto needed for certificate parsing */
/*
* lookup certificates for token in slot identified by slotidx,
* add 'wrapped' public keys to the 'keysp' array and increment nkeys.
@@ -1198,6 +1504,7 @@ fail:
return (ret);
}
+#endif /* WITH_OPENSSL */
/*
* lookup public keys for token in slot identified by slotidx,
@@ -1265,16 +1572,22 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
label[key_attr[1].ulValueLen] = '\0';
switch (ck_key_type) {
+#ifdef WITH_OPENSSL
case CKK_RSA:
key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
break;
case CKK_ECDSA:
key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
break;
+#endif /* WITH_OPENSSL */
+ case CKK_EC_EDWARDS:
+ key = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj);
+ break;
default:
/* XXX print key type? */
key = NULL;
- error("skipping unsupported key type");
+ error("skipping unsupported key type 0x%lx",
+ (u_long)ck_key_type);
}
if (key == NULL) {
@@ -1627,7 +1940,9 @@ pkcs11_register_provider(char *provider_id, char *pin,
keyp == NULL)
continue;
pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+#ifdef WITH_OPENSSL
pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
+#endif
if (nkeys == 0 && !p->slotinfo[i].logged_in &&
pkcs11_interactive) {
/*
@@ -1640,7 +1955,9 @@ pkcs11_register_provider(char *provider_id, char *pin,
continue;
}
pkcs11_fetch_keys(p, i, keyp, labelsp, &nkeys);
+#ifdef WITH_OPENSSL
pkcs11_fetch_certs(p, i, keyp, labelsp, &nkeys);
+#endif
}
}
@@ -1668,6 +1985,35 @@ fail:
return (ret);
}
+int
+pkcs11_init(int interactive)
+{
+ debug3_f("called, interactive = %d", interactive);
+
+ pkcs11_interactive = interactive;
+ TAILQ_INIT(&pkcs11_providers);
+ TAILQ_INIT(&pkcs11_keys);
+ return (0);
+}
+
+/* unregister all providers, keys might still point to the providers */
+void
+pkcs11_terminate(void)
+{
+ struct pkcs11_provider *p;
+ struct pkcs11_key *k11;
+
+ debug3_f("called");
+
+ while ((k11 = TAILQ_FIRST(&pkcs11_keys)) != NULL)
+ pkcs11_k11_free(k11);
+ while ((p = TAILQ_FIRST(&pkcs11_providers)) != NULL) {
+ TAILQ_REMOVE(&pkcs11_providers, p, next);
+ pkcs11_provider_finalize(p);
+ pkcs11_provider_unref(p);
+ }
+}
+
/*
* register a new provider and get number of keys hold by the token,
* fails if provider already exists
@@ -1694,6 +2040,39 @@ pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp,
return (nkeys);
}
+int
+pkcs11_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
+{
+ switch (key->type) {
+#ifdef WITH_OPENSSL
+ case KEY_RSA:
+ case KEY_RSA_CERT:
+ return pkcs11_sign_rsa(key, sigp, lenp, data, datalen,
+ alg, sk_provider, sk_pin, compat);
+ case KEY_ECDSA:
+ case KEY_ECDSA_CERT:
+ return pkcs11_sign_ecdsa(key, sigp, lenp, data, datalen,
+ alg, sk_provider, sk_pin, compat);
+#endif /* WITH_OPENSSL */
+ case KEY_ED25519:
+ case KEY_ED25519_CERT:
+ return pkcs11_sign_ed25519(key, sigp, lenp, data, datalen,
+ alg, sk_provider, sk_pin, compat);
+ default:
+ return SSH_ERR_KEY_TYPE_UNKNOWN;
+ }
+}
+
+void
+pkcs11_key_free(struct sshkey *key)
+{
+ /* never called */
+}
+
#ifdef WITH_PKCS11_KEYGEN
struct sshkey *
pkcs11_gakp(char *provider_id, char *pin, unsigned int slotidx, char *label,
@@ -1837,16 +2216,27 @@ pkcs11_destroy_keypair(char *provider_id, char *pin, unsigned long slotidx,
*err = rv;
key_type = -1;
}
- if (key_type == CKK_RSA)
+ switch (key_type) {
+ case CKK_RSA:
k = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
- else if (key_type == CKK_ECDSA)
+ break;
+ case CKK_ECDSA:
k = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
+ break;
+ case CKK_EC_EDWARDS:
+ k = pkcs11_fetch_ed25519_pubkey(p, slotidx, &obj);
+ break;
+ default:
+ debug_f("unsupported key type %lu", (u_long)key_type);
+ continue;
+ }
if ((rv = f->C_DestroyObject(session, obj)) != CKR_OK) {
debug_f("could not destroy public key 0x%hhx", keyid);
*err = rv;
goto out;
}
+ sshkey_free(k);
}
out:
diff --git a/ssh-pkcs11.h b/ssh-pkcs11.h
index 5260223..2f05eba 100644
--- a/ssh-pkcs11.h
+++ b/ssh-pkcs11.h
@@ -22,10 +22,17 @@
#define SSH_PKCS11_ERR_PIN_REQUIRED 4
#define SSH_PKCS11_ERR_PIN_LOCKED 5
+struct sshkey;
+
int pkcs11_init(int);
void pkcs11_terminate(void);
int pkcs11_add_provider(char *, char *, struct sshkey ***, char ***);
int pkcs11_del_provider(char *);
+int pkcs11_sign(struct sshkey *, u_char **, size_t *,
+ const u_char *, size_t, const char *, const char *,
+ const char *, u_int);
+void pkcs11_key_free(struct sshkey *);
+
#ifdef WITH_PKCS11_KEYGEN
struct sshkey *
pkcs11_gakp(char *, char *, unsigned int, char *, unsigned int,
@@ -35,9 +42,6 @@ struct sshkey *
u_int32_t *);
#endif
-/* Only available in ssh-pkcs11-client.c so far */
+/* Only available in ssh-pkcs11-client.c */
int pkcs11_make_cert(const struct sshkey *,
const struct sshkey *, struct sshkey **);
-#if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11)
-#undef ENABLE_PKCS11
-#endif
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 6492e60..bdccb43 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -302,8 +302,8 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b,
return r;
}
-static const char *
-rsa_hash_alg_ident(int hash_alg)
+const char *
+ssh_rsa_hash_alg_ident(int hash_alg)
{
switch (hash_alg) {
case SSH_DIGEST_SHA1:
@@ -337,8 +337,8 @@ rsa_hash_id_from_ident(const char *ident)
* all the cases of rsa_hash_id_from_ident() but also the certificate key
* types.
*/
-static int
-rsa_hash_id_from_keyname(const char *alg)
+int
+ssh_rsa_hash_id_from_keyname(const char *alg)
{
int r;
@@ -403,7 +403,6 @@ ssh_rsa_sign(struct sshkey *key,
size_t diff, len = 0;
int slen = 0;
int hash_alg, ret = SSH_ERR_INTERNAL_ERROR;
- struct sshbuf *b = NULL;
if (lenp != NULL)
*lenp = 0;
@@ -413,7 +412,7 @@ ssh_rsa_sign(struct sshkey *key,
if (alg == NULL || strlen(alg) == 0)
hash_alg = SSH_DIGEST_SHA1;
else
- hash_alg = rsa_hash_id_from_keyname(alg);
+ hash_alg = ssh_rsa_hash_id_from_keyname(alg);
if (key == NULL || key->pkey == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA)
@@ -435,16 +434,42 @@ ssh_rsa_sign(struct sshkey *key,
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
+ if ((ret = ssh_rsa_encode_store_sig(hash_alg, sig, slen,
+ sigp, lenp)) != 0)
+ goto out;
- /* encode signature */
+ /* success */
+ ret = 0;
+ out:
+ freezero(sig, slen);
+ return ret;
+}
+
+int
+ssh_rsa_encode_store_sig(int hash_alg, const u_char *sig, size_t slen,
+ u_char **sigp, size_t *lenp)
+{
+ struct sshbuf *b = NULL;
+ int ret = SSH_ERR_INTERNAL_ERROR;
+ size_t len;
+
+ if (lenp != NULL)
+ *lenp = 0;
+ if (sigp != NULL)
+ *sigp = NULL;
+
+ /* Encode signature */
if ((b = sshbuf_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
- if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 ||
+ if ((ret = sshbuf_put_cstring(b,
+ ssh_rsa_hash_alg_ident(hash_alg))) != 0 ||
(ret = sshbuf_put_string(b, sig, slen)) != 0)
goto out;
len = sshbuf_len(b);
+
+ /* Store signature */
if (sigp != NULL) {
if ((*sigp = malloc(len)) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
@@ -456,7 +481,6 @@ ssh_rsa_sign(struct sshkey *key,
*lenp = len;
ret = 0;
out:
- freezero(sig, slen);
sshbuf_free(b);
return ret;
}
@@ -495,7 +519,7 @@ ssh_rsa_verify(const struct sshkey *key,
* legacy reasons, but otherwise the signature type should match.
*/
if (alg != NULL && strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) {
- if ((want_alg = rsa_hash_id_from_keyname(alg)) == -1) {
+ if ((want_alg = ssh_rsa_hash_id_from_keyname(alg)) == -1) {
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c
index 41743ac..8008687 100644
--- a/ssh-sk-helper.c
+++ b/ssh-sk-helper.c
@@ -43,6 +43,7 @@
#include "uidswap.h"
#include "ssherr.h"
#include "ssh-sk.h"
+#include "ssh-pkcs11.h"
extern char *__progname;
@@ -84,6 +85,22 @@ null_empty(char **s)
*s = NULL;
}
+/* stubs */
+int
+pkcs11_sign(struct sshkey *key,
+ u_char **sigp, size_t *lenp,
+ const u_char *data, size_t datalen,
+ const char *alg, const char *sk_provider,
+ const char *sk_pin, u_int compat)
+{
+ return SSH_ERR_INTERNAL_ERROR;
+}
+
+void
+pkcs11_key_free(struct sshkey *key)
+{
+}
+
static struct sshbuf *
process_sign(struct sshbuf *req)
{
diff --git a/sshbuf-misc.c b/sshbuf-misc.c
index 5ef47b1..665505a 100644
--- a/sshbuf-misc.c
+++ b/sshbuf-misc.c
@@ -281,6 +281,20 @@ sshbuf_cmp(const struct sshbuf *b, size_t offset,
return 0;
}
+int
+sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b)
+{
+ if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL)
+ return SSH_ERR_INTERNAL_ERROR;
+ if (sshbuf_len(a) != sshbuf_len(b))
+ return SSH_ERR_MESSAGE_INCOMPLETE;
+ if (sshbuf_len(a) == 0)
+ return 0;
+ if (memcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0)
+ return SSH_ERR_INVALID_FORMAT;
+ return 0;
+}
+
int
sshbuf_find(const struct sshbuf *b, size_t start_offset,
const void *s, size_t len, size_t *offsetp)
diff --git a/sshbuf.h b/sshbuf.h
index 8338d06..b2e5c21 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -265,6 +265,15 @@ int sshbuf_b64tod(struct sshbuf *buf, const char *b64);
int sshbuf_cmp(const struct sshbuf *b, size_t offset,
const void *s, size_t len);
+/*
+ * Test whether two buffers have identical contents.
+ * SSH_ERR_MESSAGE_INCOMPLETE indicates the buffers had differing size.
+ * SSH_ERR_INVALID_FORMAT indicates the buffers were the same size but
+ * had differing contents.
+ * Returns 0 on successful compare (comparing two empty buffers returns 0).
+ */
+int sshbuf_equals(const struct sshbuf *a, const struct sshbuf *b);
+
/*
* Searches the buffer for the specified string. Returns 0 on success
* and updates *offsetp with the offset of the first match, relative to
diff --git a/sshd/Makefile b/sshd/Makefile
index 6543436..d2d8d90 100644
--- a/sshd/Makefile
+++ b/sshd/Makefile
@@ -5,7 +5,7 @@
SRCS= sshd.c servconf.c sshpty.c srclimit.c groupaccess.c auth2-methods.c
SRCS+= dns.c fatal.c compat.c utf8.c authfd.c canohost.c kex-names.c
SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} \
- ${SRCS_MAC} ${SRCS_UTL} ${SRCS_SK_CLIENT}
+ ${SRCS_MAC} ${SRCS_UTL} ${SRCS_SK_CLIENT} ${SRCS_PKCS11_CLIENT}
PROG= sshd
BINMODE=511
diff --git a/sshkey.c b/sshkey.c
index 50e1f56..681c201 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -55,6 +55,7 @@
#include "sshkey.h"
#include "match.h"
#include "ssh-sk.h"
+#include "ssh-pkcs11.h"
#ifdef WITH_XMSS
#include "sshkey-xmss.h"
@@ -738,6 +739,8 @@ sshkey_free_contents(struct sshkey *k)
if (k == NULL)
return;
+ if ((k->flags & SSHKEY_FLAG_EXT) != 0)
+ pkcs11_key_free(k);
if ((impl = sshkey_impl_from_type(k->type)) != NULL &&
impl->funcs->cleanup != NULL)
impl->funcs->cleanup(k);
@@ -860,22 +863,29 @@ sshkey_putb(const struct sshkey *key, struct sshbuf *b)
return to_blob_buf(key, b, 0, SSHKEY_SERIALIZE_DEFAULT);
}
-int
-sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
- enum sshkey_serialize_rep opts)
+static int
+sshkey_puts_opts_internal(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts, int force_plain)
{
struct sshbuf *tmp;
int r;
if ((tmp = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
- r = to_blob_buf(key, tmp, 0, opts);
+ r = to_blob_buf(key, tmp, force_plain, opts);
if (r == 0)
r = sshbuf_put_stringb(b, tmp);
sshbuf_free(tmp);
return r;
}
+int
+sshkey_puts_opts(const struct sshkey *key, struct sshbuf *b,
+ enum sshkey_serialize_rep opts)
+{
+ return sshkey_puts_opts_internal(key, b, opts, 0);
+}
+
int
sshkey_puts(const struct sshkey *key, struct sshbuf *b)
{
@@ -888,6 +898,12 @@ sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)
return to_blob_buf(key, b, 1, SSHKEY_SERIALIZE_DEFAULT);
}
+int
+sshkey_puts_plain(const struct sshkey *key, struct sshbuf *b)
+{
+ return sshkey_puts_opts_internal(key, b, SSHKEY_SERIALIZE_DEFAULT, 1);
+}
+
static int
to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain,
enum sshkey_serialize_rep opts)
@@ -2160,6 +2176,9 @@ sshkey_sign(struct sshkey *key,
if (sshkey_is_sk(key)) {
r = sshsk_sign(sk_provider, key, sigp, lenp, data,
datalen, compat, sk_pin);
+ } else if ((key->flags & SSHKEY_FLAG_EXT) != 0) {
+ r = pkcs11_sign(key, sigp, lenp, data, datalen,
+ alg, sk_provider, sk_pin, compat);
} else {
if (impl->funcs->sign == NULL)
r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
diff --git a/sshkey.h b/sshkey.h
index d3f3962..8168cac 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -269,6 +269,7 @@ int sshkey_puts_opts(const struct sshkey *, struct sshbuf *,
enum sshkey_serialize_rep);
int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
+int sshkey_puts_plain(const struct sshkey *, struct sshbuf *);
int sshkey_sign(struct sshkey *, u_char **, size_t *,
const u_char *, size_t, const char *, const char *, const char *, u_int);
@@ -334,7 +335,15 @@ int sshkey_serialize_private_sk(const struct sshkey *key,
int sshkey_private_deserialize_sk(struct sshbuf *buf, struct sshkey *k);
#ifdef WITH_OPENSSL
int check_rsa_length(const RSA *rsa); /* XXX remove */
+int ssh_rsa_hash_id_from_keyname(const char *);
+const char *ssh_rsa_hash_alg_ident(int);
+int ssh_rsa_encode_store_sig(int, const u_char *, size_t,
+ u_char **, size_t *);
+int ssh_ecdsa_encode_store_sig(const struct sshkey *,
+ const BIGNUM *, const BIGNUM *, u_char **, size_t *);
#endif
+int ssh_ed25519_encode_store_sig(const u_char *, size_t,
+ u_char **, size_t *);
#endif
#ifndef WITH_OPENSSL
diff --git a/pkcs11.h b/pkcs11.h
index b01d58f..09c0ca3 100644
--- a/pkcs11.h
+++ b/pkcs11.h
@@ -1,4 +1,3 @@
-/* $OpenBSD: pkcs11.h,v 1.3 2013/11/26 19:15:09 deraadt Exp $ */
/* pkcs11.h
Copyright 2006, 2007 g10 Code GmbH
Copyright 2006 Andreas Jellinghaus
@@ -64,9 +63,9 @@ extern "C" {
version of this file, please consider deleting the revision macro
(you may use a macro with a different name to keep track of your
versions). */
-#define CRYPTOKI_VERSION_MAJOR 2
-#define CRYPTOKI_VERSION_MINOR 20
-#define CRYPTOKI_VERSION_REVISION 6
+#define CRYPTOKI_VERSION_MAJOR 3
+#define CRYPTOKI_VERSION_MINOR 0
+#define CRYPTOKI_VERSION_REVISION 0
/* Compatibility interface is default, unless CRYPTOKI_GNU is
@@ -96,7 +95,6 @@ extern "C" {
#endif
-
#ifdef CRYPTOKI_COMPAT
/* If we are in compatibility mode, switch all exposed names to the
PKCS #11 variant. There are corresponding #undefs below. */
@@ -155,6 +153,8 @@ extern "C" {
#define ck_mechanism_type_t CK_MECHANISM_TYPE
+#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE
+
#define ck_mechanism _CK_MECHANISM
#define parameter pParameter
#define parameter_len ulParameterLen
@@ -166,7 +166,10 @@ extern "C" {
#define ck_rv_t CK_RV
#define ck_notify_t CK_NOTIFY
+#define ck_interface CK_INTERFACE
+
#define ck_function_list _CK_FUNCTION_LIST
+#define ck_function_list_3_0 _CK_FUNCTION_LIST_3_0
#define ck_createmutex_t CK_CREATEMUTEX
#define ck_destroymutex_t CK_DESTROYMUTEX
@@ -183,7 +186,6 @@ extern "C" {
#endif /* CRYPTOKI_COMPAT */
-
typedef unsigned long ck_flags_t;
struct ck_version
@@ -205,7 +207,7 @@ struct ck_info
typedef unsigned long ck_notification_t;
-#define CKN_SURRENDER (0)
+#define CKN_SURRENDER (0UL)
typedef unsigned long ck_slot_id_t;
@@ -221,10 +223,10 @@ struct ck_slot_info
};
-#define CKF_TOKEN_PRESENT (1 << 0)
-#define CKF_REMOVABLE_DEVICE (1 << 1)
-#define CKF_HW_SLOT (1 << 2)
-#define CKF_ARRAY_ATTRIBUTE (1 << 30)
+#define CKF_TOKEN_PRESENT (1UL << 0)
+#define CKF_REMOVABLE_DEVICE (1UL << 1)
+#define CKF_HW_SLOT (1UL << 2)
+#define CKF_ARRAY_ATTRIBUTE (1UL << 30)
struct ck_token_info
@@ -250,48 +252,48 @@ struct ck_token_info
};
-#define CKF_RNG (1 << 0)
-#define CKF_WRITE_PROTECTED (1 << 1)
-#define CKF_LOGIN_REQUIRED (1 << 2)
-#define CKF_USER_PIN_INITIALIZED (1 << 3)
-#define CKF_RESTORE_KEY_NOT_NEEDED (1 << 5)
-#define CKF_CLOCK_ON_TOKEN (1 << 6)
-#define CKF_PROTECTED_AUTHENTICATION_PATH (1 << 8)
-#define CKF_DUAL_CRYPTO_OPERATIONS (1 << 9)
-#define CKF_TOKEN_INITIALIZED (1 << 10)
-#define CKF_SECONDARY_AUTHENTICATION (1 << 11)
-#define CKF_USER_PIN_COUNT_LOW (1 << 16)
-#define CKF_USER_PIN_FINAL_TRY (1 << 17)
-#define CKF_USER_PIN_LOCKED (1 << 18)
-#define CKF_USER_PIN_TO_BE_CHANGED (1 << 19)
-#define CKF_SO_PIN_COUNT_LOW (1 << 20)
-#define CKF_SO_PIN_FINAL_TRY (1 << 21)
-#define CKF_SO_PIN_LOCKED (1 << 22)
-#define CKF_SO_PIN_TO_BE_CHANGED (1 << 23)
+#define CKF_RNG (1UL << 0)
+#define CKF_WRITE_PROTECTED (1UL << 1)
+#define CKF_LOGIN_REQUIRED (1UL << 2)
+#define CKF_USER_PIN_INITIALIZED (1UL << 3)
+#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5)
+#define CKF_CLOCK_ON_TOKEN (1UL << 6)
+#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8)
+#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9)
+#define CKF_TOKEN_INITIALIZED (1UL << 10)
+#define CKF_SECONDARY_AUTHENTICATION (1UL << 11)
+#define CKF_USER_PIN_COUNT_LOW (1UL << 16)
+#define CKF_USER_PIN_FINAL_TRY (1UL << 17)
+#define CKF_USER_PIN_LOCKED (1UL << 18)
+#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19)
+#define CKF_SO_PIN_COUNT_LOW (1UL << 20)
+#define CKF_SO_PIN_FINAL_TRY (1UL << 21)
+#define CKF_SO_PIN_LOCKED (1UL << 22)
+#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23)
#define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1)
-#define CK_EFFECTIVELY_INFINITE (0)
+#define CK_EFFECTIVELY_INFINITE (0UL)
typedef unsigned long ck_session_handle_t;
-#define CK_INVALID_HANDLE (0)
+#define CK_INVALID_HANDLE (0UL)
typedef unsigned long ck_user_type_t;
-#define CKU_SO (0)
-#define CKU_USER (1)
-#define CKU_CONTEXT_SPECIFIC (2)
+#define CKU_SO (0UL)
+#define CKU_USER (1UL)
+#define CKU_CONTEXT_SPECIFIC (2UL)
typedef unsigned long ck_state_t;
-#define CKS_RO_PUBLIC_SESSION (0)
-#define CKS_RO_USER_FUNCTIONS (1)
-#define CKS_RW_PUBLIC_SESSION (2)
-#define CKS_RW_USER_FUNCTIONS (3)
-#define CKS_RW_SO_FUNCTIONS (4)
+#define CKS_RO_PUBLIC_SESSION (0UL)
+#define CKS_RO_USER_FUNCTIONS (1UL)
+#define CKS_RW_PUBLIC_SESSION (2UL)
+#define CKS_RW_USER_FUNCTIONS (3UL)
+#define CKS_RW_SO_FUNCTIONS (4UL)
struct ck_session_info
@@ -302,8 +304,8 @@ struct ck_session_info
unsigned long device_error;
};
-#define CKF_RW_SESSION (1 << 1)
-#define CKF_SERIAL_SESSION (1 << 2)
+#define CKF_RW_SESSION (1UL << 1)
+#define CKF_SERIAL_SESSION (1UL << 2)
typedef unsigned long ck_object_handle_t;
@@ -311,149 +313,194 @@ typedef unsigned long ck_object_handle_t;
typedef unsigned long ck_object_class_t;
-#define CKO_DATA (0)
-#define CKO_CERTIFICATE (1)
-#define CKO_PUBLIC_KEY (2)
-#define CKO_PRIVATE_KEY (3)
-#define CKO_SECRET_KEY (4)
-#define CKO_HW_FEATURE (5)
-#define CKO_DOMAIN_PARAMETERS (6)
-#define CKO_MECHANISM (7)
-#define CKO_VENDOR_DEFINED (1U << 31)
+#define CKO_DATA (0UL)
+#define CKO_CERTIFICATE (1UL)
+#define CKO_PUBLIC_KEY (2UL)
+#define CKO_PRIVATE_KEY (3UL)
+#define CKO_SECRET_KEY (4UL)
+#define CKO_HW_FEATURE (5UL)
+#define CKO_DOMAIN_PARAMETERS (6UL)
+#define CKO_MECHANISM (7UL)
+#define CKO_OTP_KEY (8UL)
+#define CKO_PROFILE (9UL)
+#define CKO_VENDOR_DEFINED (1UL << 31)
+#define CKP_INVALID_ID (0UL)
+#define CKP_BASELINE_PROVIDER (1UL)
+#define CKP_EXTENDED_PROVIDER (2UL)
+#define CKP_AUTHENTICATION_TOKEN (3UL)
+#define CKP_PUBLIC_CERTIFICATES_TOKEN (4UL)
+#define CKP_VENDOR_DEFINED (1UL << 31)
typedef unsigned long ck_hw_feature_type_t;
-#define CKH_MONOTONIC_COUNTER (1)
-#define CKH_CLOCK (2)
-#define CKH_USER_INTERFACE (3)
-#define CKH_VENDOR_DEFINED (1U << 31)
+#define CKH_MONOTONIC_COUNTER (1UL)
+#define CKH_CLOCK (2UL)
+#define CKH_USER_INTERFACE (3UL)
+#define CKH_VENDOR_DEFINED (1UL << 31)
typedef unsigned long ck_key_type_t;
-#define CKK_RSA (0)
-#define CKK_DSA (1)
-#define CKK_DH (2)
-#define CKK_ECDSA (3)
-#define CKK_EC (3)
-#define CKK_X9_42_DH (4)
-#define CKK_KEA (5)
-#define CKK_GENERIC_SECRET (0x10)
-#define CKK_RC2 (0x11)
-#define CKK_RC4 (0x12)
-#define CKK_DES (0x13)
-#define CKK_DES2 (0x14)
-#define CKK_DES3 (0x15)
-#define CKK_CAST (0x16)
-#define CKK_CAST3 (0x17)
-#define CKK_CAST128 (0x18)
-#define CKK_RC5 (0x19)
-#define CKK_IDEA (0x1a)
-#define CKK_SKIPJACK (0x1b)
-#define CKK_BATON (0x1c)
-#define CKK_JUNIPER (0x1d)
-#define CKK_CDMF (0x1e)
-#define CKK_AES (0x1f)
-#define CKK_BLOWFISH (0x20)
-#define CKK_TWOFISH (0x21)
-#define CKK_VENDOR_DEFINED (1U << 31)
+#define CKK_RSA (0UL)
+#define CKK_DSA (1UL)
+#define CKK_DH (2UL)
+#define CKK_ECDSA (3UL)
+#define CKK_EC (3UL)
+#define CKK_X9_42_DH (4UL)
+#define CKK_KEA (5UL)
+#define CKK_GENERIC_SECRET (0x10UL)
+#define CKK_RC2 (0x11UL)
+#define CKK_RC4 (0x12UL)
+#define CKK_DES (0x13UL)
+#define CKK_DES2 (0x14UL)
+#define CKK_DES3 (0x15UL)
+#define CKK_CAST (0x16UL)
+#define CKK_CAST3 (0x17UL)
+#define CKK_CAST128 (0x18UL)
+#define CKK_RC5 (0x19UL)
+#define CKK_IDEA (0x1aUL)
+#define CKK_SKIPJACK (0x1bUL)
+#define CKK_BATON (0x1cUL)
+#define CKK_JUNIPER (0x1dUL)
+#define CKK_CDMF (0x1eUL)
+#define CKK_AES (0x1fUL)
+#define CKK_BLOWFISH (0x20UL)
+#define CKK_TWOFISH (0x21UL)
+#define CKK_GOSTR3410 (0x30UL)
+#define CKK_GOSTR3411 (0x31UL)
+#define CKK_GOST28147 (0x32UL)
+#define CKK_EC_EDWARDS (0x40UL)
+#define CKK_EC_MONTGOMERY (0x41UL)
+#define CKK_HKDF (0x42UL)
+#define CKK_VENDOR_DEFINED (1UL << 31)
+
+/*
+ * A mask for new GOST algorithms.
+ * For details visit https://tc26.ru/standarts/perevody/guidelines-the-pkcs-11-extensions-for-implementing-the-gost-r-34-10-2012-and-gost-r-34-11-2012-russian-standards-.html
+ */
+#define NSSCK_VENDOR_PKCS11_RU_TEAM (CKK_VENDOR_DEFINED | 0x54321000)
+#define CK_VENDOR_PKCS11_RU_TEAM_TK26 NSSCK_VENDOR_PKCS11_RU_TEAM
+
+#define CKK_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x003)
typedef unsigned long ck_certificate_type_t;
-#define CKC_X_509 (0)
-#define CKC_X_509_ATTR_CERT (1)
-#define CKC_WTLS (2)
-#define CKC_VENDOR_DEFINED (1U << 31)
+#define CKC_X_509 (0UL)
+#define CKC_X_509_ATTR_CERT (1UL)
+#define CKC_WTLS (2UL)
+#define CKC_VENDOR_DEFINED (1UL << 31)
typedef unsigned long ck_attribute_type_t;
-#define CKA_CLASS (0)
-#define CKA_TOKEN (1)
-#define CKA_PRIVATE (2)
-#define CKA_LABEL (3)
-#define CKA_APPLICATION (0x10)
-#define CKA_VALUE (0x11)
-#define CKA_OBJECT_ID (0x12)
-#define CKA_CERTIFICATE_TYPE (0x80)
-#define CKA_ISSUER (0x81)
-#define CKA_SERIAL_NUMBER (0x82)
-#define CKA_AC_ISSUER (0x83)
-#define CKA_OWNER (0x84)
-#define CKA_ATTR_TYPES (0x85)
-#define CKA_TRUSTED (0x86)
-#define CKA_CERTIFICATE_CATEGORY (0x87)
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88)
-#define CKA_URL (0x89)
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8a)
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8b)
-#define CKA_CHECK_VALUE (0x90)
-#define CKA_KEY_TYPE (0x100)
-#define CKA_SUBJECT (0x101)
-#define CKA_ID (0x102)
-#define CKA_SENSITIVE (0x103)
-#define CKA_ENCRYPT (0x104)
-#define CKA_DECRYPT (0x105)
-#define CKA_WRAP (0x106)
-#define CKA_UNWRAP (0x107)
-#define CKA_SIGN (0x108)
-#define CKA_SIGN_RECOVER (0x109)
-#define CKA_VERIFY (0x10a)
-#define CKA_VERIFY_RECOVER (0x10b)
-#define CKA_DERIVE (0x10c)
-#define CKA_START_DATE (0x110)
-#define CKA_END_DATE (0x111)
-#define CKA_MODULUS (0x120)
-#define CKA_MODULUS_BITS (0x121)
-#define CKA_PUBLIC_EXPONENT (0x122)
-#define CKA_PRIVATE_EXPONENT (0x123)
-#define CKA_PRIME_1 (0x124)
-#define CKA_PRIME_2 (0x125)
-#define CKA_EXPONENT_1 (0x126)
-#define CKA_EXPONENT_2 (0x127)
-#define CKA_COEFFICIENT (0x128)
-#define CKA_PRIME (0x130)
-#define CKA_SUBPRIME (0x131)
-#define CKA_BASE (0x132)
-#define CKA_PRIME_BITS (0x133)
-#define CKA_SUB_PRIME_BITS (0x134)
-#define CKA_VALUE_BITS (0x160)
-#define CKA_VALUE_LEN (0x161)
-#define CKA_EXTRACTABLE (0x162)
-#define CKA_LOCAL (0x163)
-#define CKA_NEVER_EXTRACTABLE (0x164)
-#define CKA_ALWAYS_SENSITIVE (0x165)
-#define CKA_KEY_GEN_MECHANISM (0x166)
-#define CKA_MODIFIABLE (0x170)
-#define CKA_ECDSA_PARAMS (0x180)
-#define CKA_EC_PARAMS (0x180)
-#define CKA_EC_POINT (0x181)
-#define CKA_SECONDARY_AUTH (0x200)
-#define CKA_AUTH_PIN_FLAGS (0x201)
-#define CKA_ALWAYS_AUTHENTICATE (0x202)
-#define CKA_WRAP_WITH_TRUSTED (0x210)
-#define CKA_HW_FEATURE_TYPE (0x300)
-#define CKA_RESET_ON_INIT (0x301)
-#define CKA_HAS_RESET (0x302)
-#define CKA_PIXEL_X (0x400)
-#define CKA_PIXEL_Y (0x401)
-#define CKA_RESOLUTION (0x402)
-#define CKA_CHAR_ROWS (0x403)
-#define CKA_CHAR_COLUMNS (0x404)
-#define CKA_COLOR (0x405)
-#define CKA_BITS_PER_PIXEL (0x406)
-#define CKA_CHAR_SETS (0x480)
-#define CKA_ENCODING_METHODS (0x481)
-#define CKA_MIME_TYPES (0x482)
-#define CKA_MECHANISM_TYPE (0x500)
-#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501)
-#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502)
-#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503)
-#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211)
-#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212)
-#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600)
-#define CKA_VENDOR_DEFINED (1U << 31)
+#define CKA_CLASS (0UL)
+#define CKA_TOKEN (1UL)
+#define CKA_PRIVATE (2UL)
+#define CKA_LABEL (3UL)
+#define CKA_UNIQUE_ID (4UL)
+#define CKA_APPLICATION (0x10UL)
+#define CKA_VALUE (0x11UL)
+#define CKA_OBJECT_ID (0x12UL)
+#define CKA_CERTIFICATE_TYPE (0x80UL)
+#define CKA_ISSUER (0x81UL)
+#define CKA_SERIAL_NUMBER (0x82UL)
+#define CKA_AC_ISSUER (0x83UL)
+#define CKA_OWNER (0x84UL)
+#define CKA_ATTR_TYPES (0x85UL)
+#define CKA_TRUSTED (0x86UL)
+#define CKA_CERTIFICATE_CATEGORY (0x87UL)
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL)
+#define CKA_URL (0x89UL)
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL)
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL)
+#define CKA_CHECK_VALUE (0x90UL)
+#define CKA_KEY_TYPE (0x100UL)
+#define CKA_SUBJECT (0x101UL)
+#define CKA_ID (0x102UL)
+#define CKA_SENSITIVE (0x103UL)
+#define CKA_ENCRYPT (0x104UL)
+#define CKA_DECRYPT (0x105UL)
+#define CKA_WRAP (0x106UL)
+#define CKA_UNWRAP (0x107UL)
+#define CKA_SIGN (0x108UL)
+#define CKA_SIGN_RECOVER (0x109UL)
+#define CKA_VERIFY (0x10aUL)
+#define CKA_VERIFY_RECOVER (0x10bUL)
+#define CKA_DERIVE (0x10cUL)
+#define CKA_START_DATE (0x110UL)
+#define CKA_END_DATE (0x111UL)
+#define CKA_MODULUS (0x120UL)
+#define CKA_MODULUS_BITS (0x121UL)
+#define CKA_PUBLIC_EXPONENT (0x122UL)
+#define CKA_PRIVATE_EXPONENT (0x123UL)
+#define CKA_PRIME_1 (0x124UL)
+#define CKA_PRIME_2 (0x125UL)
+#define CKA_EXPONENT_1 (0x126UL)
+#define CKA_EXPONENT_2 (0x127UL)
+#define CKA_COEFFICIENT (0x128UL)
+#define CKA_PUBLIC_KEY_INFO (0x129UL)
+#define CKA_PRIME (0x130UL)
+#define CKA_SUBPRIME (0x131UL)
+#define CKA_BASE (0x132UL)
+#define CKA_PRIME_BITS (0x133UL)
+#define CKA_SUB_PRIME_BITS (0x134UL)
+#define CKA_VALUE_BITS (0x160UL)
+#define CKA_VALUE_LEN (0x161UL)
+#define CKA_EXTRACTABLE (0x162UL)
+#define CKA_LOCAL (0x163UL)
+#define CKA_NEVER_EXTRACTABLE (0x164UL)
+#define CKA_ALWAYS_SENSITIVE (0x165UL)
+#define CKA_KEY_GEN_MECHANISM (0x166UL)
+#define CKA_MODIFIABLE (0x170UL)
+#define CKA_COPYABLE (0x171UL)
+#define CKA_DESTROYABLE (0x172UL)
+#define CKA_ECDSA_PARAMS (0x180UL)
+#define CKA_EC_PARAMS (0x180UL)
+#define CKA_EC_POINT (0x181UL)
+#define CKA_SECONDARY_AUTH (0x200UL)
+#define CKA_AUTH_PIN_FLAGS (0x201UL)
+#define CKA_ALWAYS_AUTHENTICATE (0x202UL)
+#define CKA_WRAP_WITH_TRUSTED (0x210UL)
+#define CKA_GOSTR3410_PARAMS (0x250UL)
+#define CKA_GOSTR3411_PARAMS (0x251UL)
+#define CKA_GOST28147_PARAMS (0x252UL)
+#define CKA_HW_FEATURE_TYPE (0x300UL)
+#define CKA_RESET_ON_INIT (0x301UL)
+#define CKA_HAS_RESET (0x302UL)
+#define CKA_PIXEL_X (0x400UL)
+#define CKA_PIXEL_Y (0x401UL)
+#define CKA_RESOLUTION (0x402UL)
+#define CKA_CHAR_ROWS (0x403UL)
+#define CKA_CHAR_COLUMNS (0x404UL)
+#define CKA_COLOR (0x405UL)
+#define CKA_BITS_PER_PIXEL (0x406UL)
+#define CKA_CHAR_SETS (0x480UL)
+#define CKA_ENCODING_METHODS (0x481UL)
+#define CKA_MIME_TYPES (0x482UL)
+#define CKA_MECHANISM_TYPE (0x500UL)
+#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL)
+#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL)
+#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL)
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL)
+#define CKA_OTP_FORMAT (0x220UL)
+#define CKA_OTP_LENGTH (0x221UL)
+#define CKA_OTP_TIME_INTERVAL (0x222UL)
+#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL)
+#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL)
+#define CKA_OTP_TIME_REQUIREMENT (0x225UL)
+#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL)
+#define CKA_OTP_PIN_REQUIREMENT (0x227UL)
+#define CKA_OTP_USER_IDENTIFIER (0x22AUL)
+#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL)
+#define CKA_OTP_SERVICE_LOGO (0x22CUL)
+#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL)
+#define CKA_OTP_COUNTER (0x22EUL)
+#define CKA_OTP_TIME (0x22FUL)
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL)
+#define CKA_PROFILE_ID (0x601UL)
+#define CKA_VENDOR_DEFINED (1UL << 31)
struct ck_attribute
@@ -474,206 +521,304 @@ struct ck_date
typedef unsigned long ck_mechanism_type_t;
-#define CKM_RSA_PKCS_KEY_PAIR_GEN (0)
-#define CKM_RSA_PKCS (1)
-#define CKM_RSA_9796 (2)
-#define CKM_RSA_X_509 (3)
-#define CKM_MD2_RSA_PKCS (4)
-#define CKM_MD5_RSA_PKCS (5)
-#define CKM_SHA1_RSA_PKCS (6)
-#define CKM_RIPEMD128_RSA_PKCS (7)
-#define CKM_RIPEMD160_RSA_PKCS (8)
-#define CKM_RSA_PKCS_OAEP (9)
-#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xa)
-#define CKM_RSA_X9_31 (0xb)
-#define CKM_SHA1_RSA_X9_31 (0xc)
-#define CKM_RSA_PKCS_PSS (0xd)
-#define CKM_SHA1_RSA_PKCS_PSS (0xe)
-#define CKM_DSA_KEY_PAIR_GEN (0x10)
-#define CKM_DSA (0x11)
-#define CKM_DSA_SHA1 (0x12)
-#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20)
-#define CKM_DH_PKCS_DERIVE (0x21)
-#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30)
-#define CKM_X9_42_DH_DERIVE (0x31)
-#define CKM_X9_42_DH_HYBRID_DERIVE (0x32)
-#define CKM_X9_42_MQV_DERIVE (0x33)
-#define CKM_SHA256_RSA_PKCS (0x40)
-#define CKM_SHA384_RSA_PKCS (0x41)
-#define CKM_SHA512_RSA_PKCS (0x42)
-#define CKM_SHA256_RSA_PKCS_PSS (0x43)
-#define CKM_SHA384_RSA_PKCS_PSS (0x44)
-#define CKM_SHA512_RSA_PKCS_PSS (0x45)
-#define CKM_RC2_KEY_GEN (0x100)
-#define CKM_RC2_ECB (0x101)
-#define CKM_RC2_CBC (0x102)
-#define CKM_RC2_MAC (0x103)
-#define CKM_RC2_MAC_GENERAL (0x104)
-#define CKM_RC2_CBC_PAD (0x105)
-#define CKM_RC4_KEY_GEN (0x110)
-#define CKM_RC4 (0x111)
-#define CKM_DES_KEY_GEN (0x120)
-#define CKM_DES_ECB (0x121)
-#define CKM_DES_CBC (0x122)
-#define CKM_DES_MAC (0x123)
-#define CKM_DES_MAC_GENERAL (0x124)
-#define CKM_DES_CBC_PAD (0x125)
-#define CKM_DES2_KEY_GEN (0x130)
-#define CKM_DES3_KEY_GEN (0x131)
-#define CKM_DES3_ECB (0x132)
-#define CKM_DES3_CBC (0x133)
-#define CKM_DES3_MAC (0x134)
-#define CKM_DES3_MAC_GENERAL (0x135)
-#define CKM_DES3_CBC_PAD (0x136)
-#define CKM_CDMF_KEY_GEN (0x140)
-#define CKM_CDMF_ECB (0x141)
-#define CKM_CDMF_CBC (0x142)
-#define CKM_CDMF_MAC (0x143)
-#define CKM_CDMF_MAC_GENERAL (0x144)
-#define CKM_CDMF_CBC_PAD (0x145)
-#define CKM_MD2 (0x200)
-#define CKM_MD2_HMAC (0x201)
-#define CKM_MD2_HMAC_GENERAL (0x202)
-#define CKM_MD5 (0x210)
-#define CKM_MD5_HMAC (0x211)
-#define CKM_MD5_HMAC_GENERAL (0x212)
-#define CKM_SHA_1 (0x220)
-#define CKM_SHA_1_HMAC (0x221)
-#define CKM_SHA_1_HMAC_GENERAL (0x222)
-#define CKM_RIPEMD128 (0x230)
-#define CKM_RIPEMD128_HMAC (0x231)
-#define CKM_RIPEMD128_HMAC_GENERAL (0x232)
-#define CKM_RIPEMD160 (0x240)
-#define CKM_RIPEMD160_HMAC (0x241)
-#define CKM_RIPEMD160_HMAC_GENERAL (0x242)
-#define CKM_SHA256 (0x250)
-#define CKM_SHA256_HMAC (0x251)
-#define CKM_SHA256_HMAC_GENERAL (0x252)
-#define CKM_SHA384 (0x260)
-#define CKM_SHA384_HMAC (0x261)
-#define CKM_SHA384_HMAC_GENERAL (0x262)
-#define CKM_SHA512 (0x270)
-#define CKM_SHA512_HMAC (0x271)
-#define CKM_SHA512_HMAC_GENERAL (0x272)
-#define CKM_CAST_KEY_GEN (0x300)
-#define CKM_CAST_ECB (0x301)
-#define CKM_CAST_CBC (0x302)
-#define CKM_CAST_MAC (0x303)
-#define CKM_CAST_MAC_GENERAL (0x304)
-#define CKM_CAST_CBC_PAD (0x305)
-#define CKM_CAST3_KEY_GEN (0x310)
-#define CKM_CAST3_ECB (0x311)
-#define CKM_CAST3_CBC (0x312)
-#define CKM_CAST3_MAC (0x313)
-#define CKM_CAST3_MAC_GENERAL (0x314)
-#define CKM_CAST3_CBC_PAD (0x315)
-#define CKM_CAST5_KEY_GEN (0x320)
-#define CKM_CAST128_KEY_GEN (0x320)
-#define CKM_CAST5_ECB (0x321)
-#define CKM_CAST128_ECB (0x321)
-#define CKM_CAST5_CBC (0x322)
-#define CKM_CAST128_CBC (0x322)
-#define CKM_CAST5_MAC (0x323)
-#define CKM_CAST128_MAC (0x323)
-#define CKM_CAST5_MAC_GENERAL (0x324)
-#define CKM_CAST128_MAC_GENERAL (0x324)
-#define CKM_CAST5_CBC_PAD (0x325)
-#define CKM_CAST128_CBC_PAD (0x325)
-#define CKM_RC5_KEY_GEN (0x330)
-#define CKM_RC5_ECB (0x331)
-#define CKM_RC5_CBC (0x332)
-#define CKM_RC5_MAC (0x333)
-#define CKM_RC5_MAC_GENERAL (0x334)
-#define CKM_RC5_CBC_PAD (0x335)
-#define CKM_IDEA_KEY_GEN (0x340)
-#define CKM_IDEA_ECB (0x341)
-#define CKM_IDEA_CBC (0x342)
-#define CKM_IDEA_MAC (0x343)
-#define CKM_IDEA_MAC_GENERAL (0x344)
-#define CKM_IDEA_CBC_PAD (0x345)
-#define CKM_GENERIC_SECRET_KEY_GEN (0x350)
-#define CKM_CONCATENATE_BASE_AND_KEY (0x360)
-#define CKM_CONCATENATE_BASE_AND_DATA (0x362)
-#define CKM_CONCATENATE_DATA_AND_BASE (0x363)
-#define CKM_XOR_BASE_AND_DATA (0x364)
-#define CKM_EXTRACT_KEY_FROM_KEY (0x365)
-#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370)
-#define CKM_SSL3_MASTER_KEY_DERIVE (0x371)
-#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372)
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373)
-#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374)
-#define CKM_TLS_MASTER_KEY_DERIVE (0x375)
-#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376)
-#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377)
-#define CKM_SSL3_MD5_MAC (0x380)
-#define CKM_SSL3_SHA1_MAC (0x381)
-#define CKM_MD5_KEY_DERIVATION (0x390)
-#define CKM_MD2_KEY_DERIVATION (0x391)
-#define CKM_SHA1_KEY_DERIVATION (0x392)
-#define CKM_PBE_MD2_DES_CBC (0x3a0)
-#define CKM_PBE_MD5_DES_CBC (0x3a1)
-#define CKM_PBE_MD5_CAST_CBC (0x3a2)
-#define CKM_PBE_MD5_CAST3_CBC (0x3a3)
-#define CKM_PBE_MD5_CAST5_CBC (0x3a4)
-#define CKM_PBE_MD5_CAST128_CBC (0x3a4)
-#define CKM_PBE_SHA1_CAST5_CBC (0x3a5)
-#define CKM_PBE_SHA1_CAST128_CBC (0x3a5)
-#define CKM_PBE_SHA1_RC4_128 (0x3a6)
-#define CKM_PBE_SHA1_RC4_40 (0x3a7)
-#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8)
-#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9)
-#define CKM_PBE_SHA1_RC2_128_CBC (0x3aa)
-#define CKM_PBE_SHA1_RC2_40_CBC (0x3ab)
-#define CKM_PKCS5_PBKD2 (0x3b0)
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0)
-#define CKM_KEY_WRAP_LYNKS (0x400)
-#define CKM_KEY_WRAP_SET_OAEP (0x401)
-#define CKM_SKIPJACK_KEY_GEN (0x1000)
-#define CKM_SKIPJACK_ECB64 (0x1001)
-#define CKM_SKIPJACK_CBC64 (0x1002)
-#define CKM_SKIPJACK_OFB64 (0x1003)
-#define CKM_SKIPJACK_CFB64 (0x1004)
-#define CKM_SKIPJACK_CFB32 (0x1005)
-#define CKM_SKIPJACK_CFB16 (0x1006)
-#define CKM_SKIPJACK_CFB8 (0x1007)
-#define CKM_SKIPJACK_WRAP (0x1008)
-#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009)
-#define CKM_SKIPJACK_RELAYX (0x100a)
-#define CKM_KEA_KEY_PAIR_GEN (0x1010)
-#define CKM_KEA_KEY_DERIVE (0x1011)
-#define CKM_FORTEZZA_TIMESTAMP (0x1020)
-#define CKM_BATON_KEY_GEN (0x1030)
-#define CKM_BATON_ECB128 (0x1031)
-#define CKM_BATON_ECB96 (0x1032)
-#define CKM_BATON_CBC128 (0x1033)
-#define CKM_BATON_COUNTER (0x1034)
-#define CKM_BATON_SHUFFLE (0x1035)
-#define CKM_BATON_WRAP (0x1036)
-#define CKM_ECDSA_KEY_PAIR_GEN (0x1040)
-#define CKM_EC_KEY_PAIR_GEN (0x1040)
-#define CKM_ECDSA (0x1041)
-#define CKM_ECDSA_SHA1 (0x1042)
-#define CKM_ECDH1_DERIVE (0x1050)
-#define CKM_ECDH1_COFACTOR_DERIVE (0x1051)
-#define CKM_ECMQV_DERIVE (0x1052)
-#define CKM_JUNIPER_KEY_GEN (0x1060)
-#define CKM_JUNIPER_ECB128 (0x1061)
-#define CKM_JUNIPER_CBC128 (0x1062)
-#define CKM_JUNIPER_COUNTER (0x1063)
-#define CKM_JUNIPER_SHUFFLE (0x1064)
-#define CKM_JUNIPER_WRAP (0x1065)
-#define CKM_FASTHASH (0x1070)
-#define CKM_AES_KEY_GEN (0x1080)
-#define CKM_AES_ECB (0x1081)
-#define CKM_AES_CBC (0x1082)
-#define CKM_AES_MAC (0x1083)
-#define CKM_AES_MAC_GENERAL (0x1084)
-#define CKM_AES_CBC_PAD (0x1085)
-#define CKM_DSA_PARAMETER_GEN (0x2000)
-#define CKM_DH_PKCS_PARAMETER_GEN (0x2001)
-#define CKM_X9_42_DH_PARAMETER_GEN (0x2002)
-#define CKM_VENDOR_DEFINED (1U << 31)
+#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL)
+#define CKM_RSA_PKCS (1UL)
+#define CKM_RSA_9796 (2UL)
+#define CKM_RSA_X_509 (3UL)
+#define CKM_MD2_RSA_PKCS (4UL)
+#define CKM_MD5_RSA_PKCS (5UL)
+#define CKM_SHA1_RSA_PKCS (6UL)
+#define CKM_RIPEMD128_RSA_PKCS (7UL)
+#define CKM_RIPEMD160_RSA_PKCS (8UL)
+#define CKM_RSA_PKCS_OAEP (9UL)
+#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL)
+#define CKM_RSA_X9_31 (0xbUL)
+#define CKM_SHA1_RSA_X9_31 (0xcUL)
+#define CKM_RSA_PKCS_PSS (0xdUL)
+#define CKM_SHA1_RSA_PKCS_PSS (0xeUL)
+#define CKM_DSA_KEY_PAIR_GEN (0x10UL)
+#define CKM_DSA (0x11UL)
+#define CKM_DSA_SHA1 (0x12UL)
+#define CKM_DSA_SHA224 (0x13UL)
+#define CKM_DSA_SHA256 (0x14UL)
+#define CKM_DSA_SHA384 (0x15UL)
+#define CKM_DSA_SHA512 (0x16UL)
+#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL)
+#define CKM_DH_PKCS_DERIVE (0x21UL)
+#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL)
+#define CKM_X9_42_DH_DERIVE (0x31UL)
+#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL)
+#define CKM_X9_42_MQV_DERIVE (0x33UL)
+#define CKM_SHA256_RSA_PKCS (0x40UL)
+#define CKM_SHA384_RSA_PKCS (0x41UL)
+#define CKM_SHA512_RSA_PKCS (0x42UL)
+#define CKM_SHA256_RSA_PKCS_PSS (0x43UL)
+#define CKM_SHA384_RSA_PKCS_PSS (0x44UL)
+#define CKM_SHA512_RSA_PKCS_PSS (0x45UL)
+#define CKM_SHA224_RSA_PKCS (0x46UL)
+#define CKM_SHA224_RSA_PKCS_PSS (0x47UL)
+#define CKM_SHA3_256_RSA_PKCS (0x60UL)
+#define CKM_SHA3_384_RSA_PKCS (0x61UL)
+#define CKM_SHA3_512_RSA_PKCS (0x62UL)
+#define CKM_SHA3_256_RSA_PKCS_PSS (0x63UL)
+#define CKM_SHA3_384_RSA_PKCS_PSS (0x64UL)
+#define CKM_SHA3_512_RSA_PKCS_PSS (0x65UL)
+#define CKM_SHA3_224_RSA_PKCS (0x66UL)
+#define CKM_SHA3_224_RSA_PKCS_PSS (0x67UL)
+#define CKM_RC2_KEY_GEN (0x100UL)
+#define CKM_RC2_ECB (0x101UL)
+#define CKM_RC2_CBC (0x102UL)
+#define CKM_RC2_MAC (0x103UL)
+#define CKM_RC2_MAC_GENERAL (0x104UL)
+#define CKM_RC2_CBC_PAD (0x105UL)
+#define CKM_RC4_KEY_GEN (0x110UL)
+#define CKM_RC4 (0x111UL)
+#define CKM_DES_KEY_GEN (0x120UL)
+#define CKM_DES_ECB (0x121UL)
+#define CKM_DES_CBC (0x122UL)
+#define CKM_DES_MAC (0x123UL)
+#define CKM_DES_MAC_GENERAL (0x124UL)
+#define CKM_DES_CBC_PAD (0x125UL)
+#define CKM_DES2_KEY_GEN (0x130UL)
+#define CKM_DES3_KEY_GEN (0x131UL)
+#define CKM_DES3_ECB (0x132UL)
+#define CKM_DES3_CBC (0x133UL)
+#define CKM_DES3_MAC (0x134UL)
+#define CKM_DES3_MAC_GENERAL (0x135UL)
+#define CKM_DES3_CBC_PAD (0x136UL)
+#define CKM_DES3_CMAC_GENERAL (0x137UL)
+#define CKM_DES3_CMAC (0x138UL)
+#define CKM_CDMF_KEY_GEN (0x140UL)
+#define CKM_CDMF_ECB (0x141UL)
+#define CKM_CDMF_CBC (0x142UL)
+#define CKM_CDMF_MAC (0x143UL)
+#define CKM_CDMF_MAC_GENERAL (0x144UL)
+#define CKM_CDMF_CBC_PAD (0x145UL)
+#define CKM_MD2 (0x200UL)
+#define CKM_MD2_HMAC (0x201UL)
+#define CKM_MD2_HMAC_GENERAL (0x202UL)
+#define CKM_MD5 (0x210UL)
+#define CKM_MD5_HMAC (0x211UL)
+#define CKM_MD5_HMAC_GENERAL (0x212UL)
+#define CKM_SHA_1 (0x220UL)
+#define CKM_SHA_1_HMAC (0x221UL)
+#define CKM_SHA_1_HMAC_GENERAL (0x222UL)
+#define CKM_RIPEMD128 (0x230UL)
+#define CKM_RIPEMD128_HMAC (0x231UL)
+#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL)
+#define CKM_RIPEMD160 (0x240UL)
+#define CKM_RIPEMD160_HMAC (0x241UL)
+#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL)
+#define CKM_SHA256 (0x250UL)
+#define CKM_SHA256_HMAC (0x251UL)
+#define CKM_SHA256_HMAC_GENERAL (0x252UL)
+#define CKM_SHA224 (0x255UL)
+#define CKM_SHA224_HMAC (0x256UL)
+#define CKM_SHA224_HMAC_GENERAL (0x257UL)
+#define CKM_SHA384 (0x260UL)
+#define CKM_SHA384_HMAC (0x261UL)
+#define CKM_SHA384_HMAC_GENERAL (0x262UL)
+#define CKM_SHA512 (0x270UL)
+#define CKM_SHA512_HMAC (0x271UL)
+#define CKM_SHA512_HMAC_GENERAL (0x272UL)
+#define CKM_SHA3_256 (0x2B0UL)
+#define CKM_SHA3_256_HMAC (0x2B1UL)
+#define CKM_SHA3_256_HMAC_GENERAL (0x2B2UL)
+#define CKM_SHA3_256_KEY_GEN (0x2B3UL)
+#define CKM_SHA3_224 (0x2B5UL)
+#define CKM_SHA3_224_HMAC (0x2B6UL)
+#define CKM_SHA3_224_HMAC_GENERAL (0x2B7UL)
+#define CKM_SHA3_224_KEY_GEN (0x2B8UL)
+#define CKM_SHA3_384 (0x2C0UL)
+#define CKM_SHA3_384_HMAC (0x2C1UL)
+#define CKM_SHA3_384_HMAC_GENERAL (0x2C2UL)
+#define CKM_SHA3_384_KEY_GEN (0x2C3UL)
+#define CKM_SHA3_512 (0x2D0UL)
+#define CKM_SHA3_512_HMAC (0x2D1UL)
+#define CKM_SHA3_512_HMAC_GENERAL (0x2D2UL)
+#define CKM_SHA3_512_KEY_GEN (0x2D3UL)
+#define CKM_CAST_KEY_GEN (0x300UL)
+#define CKM_CAST_ECB (0x301UL)
+#define CKM_CAST_CBC (0x302UL)
+#define CKM_CAST_MAC (0x303UL)
+#define CKM_CAST_MAC_GENERAL (0x304UL)
+#define CKM_CAST_CBC_PAD (0x305UL)
+#define CKM_CAST3_KEY_GEN (0x310UL)
+#define CKM_CAST3_ECB (0x311UL)
+#define CKM_CAST3_CBC (0x312UL)
+#define CKM_CAST3_MAC (0x313UL)
+#define CKM_CAST3_MAC_GENERAL (0x314UL)
+#define CKM_CAST3_CBC_PAD (0x315UL)
+#define CKM_CAST5_KEY_GEN (0x320UL)
+#define CKM_CAST128_KEY_GEN (0x320UL)
+#define CKM_CAST5_ECB (0x321UL)
+#define CKM_CAST128_ECB (0x321UL)
+#define CKM_CAST5_CBC (0x322UL)
+#define CKM_CAST128_CBC (0x322UL)
+#define CKM_CAST5_MAC (0x323UL)
+#define CKM_CAST128_MAC (0x323UL)
+#define CKM_CAST5_MAC_GENERAL (0x324UL)
+#define CKM_CAST128_MAC_GENERAL (0x324UL)
+#define CKM_CAST5_CBC_PAD (0x325UL)
+#define CKM_CAST128_CBC_PAD (0x325UL)
+#define CKM_RC5_KEY_GEN (0x330UL)
+#define CKM_RC5_ECB (0x331UL)
+#define CKM_RC5_CBC (0x332UL)
+#define CKM_RC5_MAC (0x333UL)
+#define CKM_RC5_MAC_GENERAL (0x334UL)
+#define CKM_RC5_CBC_PAD (0x335UL)
+#define CKM_IDEA_KEY_GEN (0x340UL)
+#define CKM_IDEA_ECB (0x341UL)
+#define CKM_IDEA_CBC (0x342UL)
+#define CKM_IDEA_MAC (0x343UL)
+#define CKM_IDEA_MAC_GENERAL (0x344UL)
+#define CKM_IDEA_CBC_PAD (0x345UL)
+#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL)
+#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL)
+#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL)
+#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL)
+#define CKM_XOR_BASE_AND_DATA (0x364UL)
+#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL)
+#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL)
+#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL)
+#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL)
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL)
+#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL)
+#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL)
+#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL)
+#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL)
+#define CKM_SSL3_MD5_MAC (0x380UL)
+#define CKM_SSL3_SHA1_MAC (0x381UL)
+#define CKM_MD5_KEY_DERIVATION (0x390UL)
+#define CKM_MD2_KEY_DERIVATION (0x391UL)
+#define CKM_SHA1_KEY_DERIVATION (0x392UL)
+#define CKM_PBE_MD2_DES_CBC (0x3a0UL)
+#define CKM_PBE_MD5_DES_CBC (0x3a1UL)
+#define CKM_PBE_MD5_CAST_CBC (0x3a2UL)
+#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL)
+#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL)
+#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL)
+#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL)
+#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL)
+#define CKM_PBE_SHA1_RC4_128 (0x3a6UL)
+#define CKM_PBE_SHA1_RC4_40 (0x3a7UL)
+#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL)
+#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL)
+#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL)
+#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL)
+#define CKM_PKCS5_PBKD2 (0x3b0UL)
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL)
+#define CKM_KEY_WRAP_LYNKS (0x400UL)
+#define CKM_KEY_WRAP_SET_OAEP (0x401UL)
+#define CKM_SKIPJACK_KEY_GEN (0x1000UL)
+#define CKM_SKIPJACK_ECB64 (0x1001UL)
+#define CKM_SKIPJACK_CBC64 (0x1002UL)
+#define CKM_SKIPJACK_OFB64 (0x1003UL)
+#define CKM_SKIPJACK_CFB64 (0x1004UL)
+#define CKM_SKIPJACK_CFB32 (0x1005UL)
+#define CKM_SKIPJACK_CFB16 (0x1006UL)
+#define CKM_SKIPJACK_CFB8 (0x1007UL)
+#define CKM_SKIPJACK_WRAP (0x1008UL)
+#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL)
+#define CKM_SKIPJACK_RELAYX (0x100aUL)
+#define CKM_KEA_KEY_PAIR_GEN (0x1010UL)
+#define CKM_KEA_KEY_DERIVE (0x1011UL)
+#define CKM_FORTEZZA_TIMESTAMP (0x1020UL)
+#define CKM_BATON_KEY_GEN (0x1030UL)
+#define CKM_BATON_ECB128 (0x1031UL)
+#define CKM_BATON_ECB96 (0x1032UL)
+#define CKM_BATON_CBC128 (0x1033UL)
+#define CKM_BATON_COUNTER (0x1034UL)
+#define CKM_BATON_SHUFFLE (0x1035UL)
+#define CKM_BATON_WRAP (0x1036UL)
+#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL)
+#define CKM_EC_KEY_PAIR_GEN (0x1040UL)
+#define CKM_ECDSA (0x1041UL)
+#define CKM_ECDSA_SHA1 (0x1042UL)
+#define CKM_ECDSA_SHA224 (0x1043UL)
+#define CKM_ECDSA_SHA256 (0x1044UL)
+#define CKM_ECDSA_SHA384 (0x1045UL)
+#define CKM_ECDSA_SHA512 (0x1046UL)
+#define CKM_ECDSA_SHA3_224 (0x1047UL)
+#define CKM_ECDSA_SHA3_256 (0x1048UL)
+#define CKM_ECDSA_SHA3_384 (0x1049UL)
+#define CKM_ECDSA_SHA3_512 (0x104AUL)
+#define CKM_ECDH1_DERIVE (0x1050UL)
+#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL)
+#define CKM_ECMQV_DERIVE (0x1052UL)
+#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL)
+#define CKM_EC_MONTGOMERY_KEY_PAIR_GEN (0x1056UL)
+#define CKM_EDDSA (0x1057UL)
+#define CKM_JUNIPER_KEY_GEN (0x1060UL)
+#define CKM_JUNIPER_ECB128 (0x1061UL)
+#define CKM_JUNIPER_CBC128 (0x1062UL)
+#define CKM_JUNIPER_COUNTER (0x1063UL)
+#define CKM_JUNIPER_SHUFFLE (0x1064UL)
+#define CKM_JUNIPER_WRAP (0x1065UL)
+#define CKM_FASTHASH (0x1070UL)
+#define CKM_AES_KEY_GEN (0x1080UL)
+#define CKM_AES_ECB (0x1081UL)
+#define CKM_AES_CBC (0x1082UL)
+#define CKM_AES_MAC (0x1083UL)
+#define CKM_AES_MAC_GENERAL (0x1084UL)
+#define CKM_AES_CBC_PAD (0x1085UL)
+#define CKM_AES_CTR (0x1086UL)
+#define CKM_AES_GCM (0x1087UL)
+#define CKM_AES_CCM (0x1088UL)
+#define CKM_AES_CTS (0x1089UL)
+#define CKM_AES_CMAC (0x108AUL)
+#define CKM_AES_CMAC_GENERAL (0x108BUL)
+#define CKM_AES_XCBC_MAC (0x108CUL)
+#define CKM_AES_XCBC_MAC_96 (0x108DUL)
+#define CKM_AES_GMAC (0x108EUL)
+#define CKM_BLOWFISH_KEY_GEN (0x1090UL)
+#define CKM_BLOWFISH_CBC (0x1091UL)
+#define CKM_TWOFISH_KEY_GEN (0x1092UL)
+#define CKM_TWOFISH_CBC (0x1093UL)
+#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL)
+#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL)
+#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL)
+#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL)
+#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL)
+#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL)
+#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL)
+#define CKM_GOSTR3410 (0x1201UL)
+#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL)
+#define CKM_GOSTR3410_KEY_WRAP (0x1203UL)
+#define CKM_GOSTR3410_DERIVE (0x1204UL)
+#define CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x005)
+#define CKM_GOSTR3410_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x006)
+#define CKM_GOSTR3410_12_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x007)
+#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x008)
+#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x009)
+#define CKM_GOSTR3411 (0x1210UL)
+#define CKM_GOSTR3411_HMAC (0x1211UL)
+#define CKM_GOSTR3411_12_256 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x012)
+#define CKM_GOSTR3411_12_512 (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x013)
+#define CKM_GOSTR3411_12_256_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x014)
+#define CKM_GOSTR3411_12_512_HMAC (CK_VENDOR_PKCS11_RU_TEAM_TK26 | 0x015)
+#define CKM_GOST28147_KEY_GEN (0x1220UL)
+#define CKM_GOST28147_ECB (0x1221UL)
+#define CKM_GOST28147 (0x1222UL)
+#define CKM_GOST28147_MAC (0x1223UL)
+#define CKM_GOST28147_KEY_WRAP (0x1224UL)
+#define CKM_DSA_PARAMETER_GEN (0x2000UL)
+#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL)
+#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL)
+#define CKM_AES_OFB (0x2104UL)
+#define CKM_AES_CFB64 (0x2105UL)
+#define CKM_AES_CFB8 (0x2106UL)
+#define CKM_AES_CFB128 (0x2107UL)
+#define CKM_AES_CFB1 (0x2108UL)
+#define CKM_AES_KEY_WRAP (0x2109UL)
+#define CKM_AES_KEY_WRAP_PAD (0x210AUL)
+#define CKM_XEDDSA (0x4029UL)
+#define CKM_HKDF_DERIVE (0x402AUL)
+#define CKM_HKDF_DATA (0x402BUL)
+#define CKM_HKDF_KEY_GEN (0x402CUL)
+
+#define CKM_VENDOR_DEFINED (1UL << 31)
struct ck_mechanism
{
@@ -690,25 +835,143 @@ struct ck_mechanism_info
ck_flags_t flags;
};
-#define CKF_HW (1 << 0)
-#define CKF_ENCRYPT (1 << 8)
-#define CKF_DECRYPT (1 << 9)
-#define CKF_DIGEST (1 << 10)
-#define CKF_SIGN (1 << 11)
-#define CKF_SIGN_RECOVER (1 << 12)
-#define CKF_VERIFY (1 << 13)
-#define CKF_VERIFY_RECOVER (1 << 14)
-#define CKF_GENERATE (1 << 15)
-#define CKF_GENERATE_KEY_PAIR (1 << 16)
-#define CKF_WRAP (1 << 17)
-#define CKF_UNWRAP (1 << 18)
-#define CKF_DERIVE (1 << 19)
-#define CKF_EXTENSION (1U << 31)
+#define CKF_HW (1UL << 0)
+#define CKF_MESSAGE_ENCRYPT (1UL << 1)
+#define CKF_MESSAGE_DECRYPT (1UL << 2)
+#define CKF_MESSAGE_SIGN (1UL << 3)
+#define CKF_MESSAGE_VERIFY (1UL << 4)
+#define CKF_MULTI_MESSAGE (1UL << 5)
+#define CKF_FIND_OBJECTS (1UL << 6)
+
+#define CKF_ENCRYPT (1UL << 8)
+#define CKF_DECRYPT (1UL << 9)
+#define CKF_DIGEST (1UL << 10)
+#define CKF_SIGN (1UL << 11)
+#define CKF_SIGN_RECOVER (1UL << 12)
+#define CKF_VERIFY (1UL << 13)
+#define CKF_VERIFY_RECOVER (1UL << 14)
+#define CKF_GENERATE (1UL << 15)
+#define CKF_GENERATE_KEY_PAIR (1UL << 16)
+#define CKF_WRAP (1UL << 17)
+#define CKF_UNWRAP (1UL << 18)
+#define CKF_DERIVE (1UL << 19)
+#define CKF_EXTENSION (1UL << 31)
+
+#define CKF_EC_F_P (1UL << 20)
+#define CKF_EC_F_2M (1UL << 21)
+#define CKF_EC_ECPARAMETERS (1UL << 22)
+#define CKF_EC_OID (1UL << 23)
+#define CKF_EC_NAMEDCURVE CKF_EC_OID
+#define CKF_EC_UNCOMPRESS (1UL << 24)
+#define CKF_EC_COMPRESS (1UL << 25)
+#define CKF_EC_CURVENAME (1UL << 26)
/* Flags for C_WaitForSlotEvent. */
-#define CKF_DONT_BLOCK (1)
+#define CKF_DONT_BLOCK (1UL)
+/* Flags for Key derivation */
+#define CKD_NULL (0x1UL)
+#define CKD_SHA1_KDF (0x2UL)
+#define CKD_SHA224_KDF (0x5UL)
+#define CKD_SHA256_KDF (0x6UL)
+#define CKD_SHA384_KDF (0x7UL)
+#define CKD_SHA512_KDF (0x8UL)
+
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ unsigned long kdf;
+ unsigned long ulSharedDataLen;
+ unsigned char * pSharedData;
+ unsigned long ulPublicDataLen;
+ unsigned char * pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ unsigned long kdf;
+ unsigned long ulSharedDataLen;
+ unsigned char * pSharedData;
+ unsigned long ulPublicDataLen;
+ unsigned char * pPublicData;
+ unsigned long ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ unsigned long ulPublicDataLen2;
+ unsigned char * pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef unsigned long ck_rsa_pkcs_mgf_type_t;
+typedef unsigned long CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ void *pSourceData;
+ unsigned long ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ ck_mechanism_type_t hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ unsigned long sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+#define CKG_MGF1_SHA1 (0x00000001UL)
+#define CKG_MGF1_SHA224 (0x00000005UL)
+#define CKG_MGF1_SHA256 (0x00000002UL)
+#define CKG_MGF1_SHA384 (0x00000003UL)
+#define CKG_MGF1_SHA512 (0x00000004UL)
+#define CKG_MGF1_SHA3_224 (0x00000006UL)
+#define CKG_MGF1_SHA3_256 (0x00000007UL)
+#define CKG_MGF1_SHA3_384 (0x00000008UL)
+#define CKG_MGF1_SHA3_512 (0x00000009UL)
+
+#define CKZ_DATA_SPECIFIED (0x00000001UL)
+
+typedef struct CK_GCM_PARAMS {
+ void * pIv;
+ unsigned long ulIvLen;
+ unsigned long ulIvBits;
+ void * pAAD;
+ unsigned long ulAADLen;
+ unsigned long ulTagBits;
+} CK_GCM_PARAMS;
+
+typedef struct CK_CCM_PARAMS {
+ unsigned long ulDataLen;
+ unsigned char *pNonce;
+ unsigned long ulNonceLen;
+ unsigned char *pAAD;
+ unsigned long ulAADLen;
+ unsigned long ulMACLen;
+} CK_CCM_PARAMS;
+
+/* EDDSA */
+typedef struct CK_EDDSA_PARAMS {
+ unsigned char phFlag;
+ unsigned long ulContextDataLen;
+ unsigned char *pContextData;
+} CK_EDDSA_PARAMS;
+
+typedef CK_EDDSA_PARAMS *CK_EDDSA_PARAMS_PTR;
+
+/* XEDDSA */
+typedef struct CK_XEDDSA_PARAMS {
+ unsigned long hash;
+} CK_XEDDSA_PARAMS;
+
+typedef CK_XEDDSA_PARAMS *CK_XEDDSA_PARAMS_PTR;
+
+typedef struct CK_AES_CTR_PARAMS {
+ unsigned long ulCounterBits;
+ unsigned char cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS *CK_AES_CTR_PARAMS_PTR;
+
+typedef unsigned long CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS *CK_MAC_GENERAL_PARAMS_PTR;
typedef unsigned long ck_rv_t;
@@ -716,8 +979,17 @@ typedef unsigned long ck_rv_t;
typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session,
ck_notification_t event, void *application);
+struct ck_interface {
+ char * pInterfaceName;
+ void * pFunctionList;
+ ck_flags_t flags;
+};
+
+#define CKF_INTERFACE_FORK_SAFE (0x00000001UL)
+
/* Forward reference. */
struct ck_function_list;
+struct ck_function_list_3_0;
#define _CK_DECLARE_FUNCTION(name, args) \
typedef ck_rv_t (*CK_ ## name) args; \
@@ -774,7 +1046,7 @@ _CK_DECLARE_FUNCTION (C_SetOperationState,
unsigned char *operation_state,
unsigned long operation_state_len,
ck_object_handle_t encryption_key,
- ck_object_handle_t authentiation_key));
+ ck_object_handle_t authentication_key));
_CK_DECLARE_FUNCTION (C_Login,
(ck_session_handle_t session, ck_user_type_t user_type,
unsigned char *pin, unsigned long pin_len));
@@ -999,6 +1271,147 @@ _CK_DECLARE_FUNCTION (C_GenerateRandom,
_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session));
_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session));
+_CK_DECLARE_FUNCTION (C_GetInterfaceList,
+ (struct ck_interface *interfaces_list,
+ unsigned long *count));
+_CK_DECLARE_FUNCTION (C_GetInterface,
+ (unsigned char *interface_name,
+ struct ck_version *version,
+ struct ck_interface **interface_ptr,
+ ck_flags_t flags));
+
+_CK_DECLARE_FUNCTION (C_LoginUser,
+ (ck_session_handle_t session,
+ ck_user_type_t user_type,
+ unsigned char *pin,
+ unsigned long pin_len,
+ unsigned char *username,
+ unsigned long username_len));
+
+_CK_DECLARE_FUNCTION (C_SessionCancel,
+ (ck_session_handle_t session,
+ ck_flags_t flags));
+
+_CK_DECLARE_FUNCTION (C_MessageEncryptInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_EncryptMessage,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *associated_data,
+ unsigned long associated_data_len,
+ unsigned char *plaintext,
+ unsigned long plaintext_len,
+ unsigned char *ciphertext,
+ unsigned long *ciphertext_len));
+_CK_DECLARE_FUNCTION (C_EncryptMessageBegin,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *associated_data,
+ unsigned long associated_data_len));
+_CK_DECLARE_FUNCTION (C_EncryptMessageNext,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *plaintext_part,
+ unsigned long plaintext_part_len,
+ unsigned char *ciphertext_part,
+ unsigned long *ciphertext_part_len,
+ ck_flags_t flags));
+_CK_DECLARE_FUNCTION (C_MessageEncryptFinal,
+ (ck_session_handle_t session));
+
+_CK_DECLARE_FUNCTION (C_MessageDecryptInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_DecryptMessage,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *associated_data,
+ unsigned long associated_data_len,
+ unsigned char *ciphertext,
+ unsigned long ciphertext_len,
+ unsigned char *plaintext,
+ unsigned long *plaintext_len));
+_CK_DECLARE_FUNCTION (C_DecryptMessageBegin,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *associated_data,
+ unsigned long associated_data_len));
+_CK_DECLARE_FUNCTION (C_DecryptMessageNext,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *ciphertext_part,
+ unsigned long ciphertext_part_len,
+ unsigned char *plaintext_part,
+ unsigned long *plaintext_part_len,
+ ck_flags_t flags));
+_CK_DECLARE_FUNCTION (C_MessageDecryptFinal,
+ (ck_session_handle_t session));
+
+_CK_DECLARE_FUNCTION (C_MessageSignInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_SignMessage,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *data,
+ unsigned long data_len,
+ unsigned char *signature,
+ unsigned long *signature_len));
+_CK_DECLARE_FUNCTION (C_SignMessageBegin,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len));
+_CK_DECLARE_FUNCTION (C_SignMessageNext,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *data,
+ unsigned long data_len,
+ unsigned char *signature,
+ unsigned long *signature_len));
+_CK_DECLARE_FUNCTION (C_MessageSignFinal,
+ (ck_session_handle_t session));
+
+_CK_DECLARE_FUNCTION (C_MessageVerifyInit,
+ (ck_session_handle_t session,
+ struct ck_mechanism *mechanism,
+ ck_object_handle_t key));
+_CK_DECLARE_FUNCTION (C_VerifyMessage,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *data,
+ unsigned long data_len,
+ unsigned char *signature,
+ unsigned long signature_len));
+_CK_DECLARE_FUNCTION (C_VerifyMessageBegin,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len));
+_CK_DECLARE_FUNCTION (C_VerifyMessageNext,
+ (ck_session_handle_t session,
+ void *parameter,
+ unsigned long parameter_len,
+ unsigned char *data,
+ unsigned long data_len,
+ unsigned char *signature,
+ unsigned long signature_len));
+_CK_DECLARE_FUNCTION (C_MessageVerifyFinal,
+ (ck_session_handle_t session));
+
+/* Flags in Message-based encryption/decryption API */
+#define CKF_END_OF_MESSAGE (0x00000001UL)
struct ck_function_list
{
@@ -1073,6 +1486,105 @@ struct ck_function_list
CK_C_WaitForSlotEvent C_WaitForSlotEvent;
};
+struct ck_function_list_3_0
+{
+ struct ck_version version;
+ CK_C_Initialize C_Initialize;
+ CK_C_Finalize C_Finalize;
+ CK_C_GetInfo C_GetInfo;
+ CK_C_GetFunctionList C_GetFunctionList;
+ CK_C_GetSlotList C_GetSlotList;
+ CK_C_GetSlotInfo C_GetSlotInfo;
+ CK_C_GetTokenInfo C_GetTokenInfo;
+ CK_C_GetMechanismList C_GetMechanismList;
+ CK_C_GetMechanismInfo C_GetMechanismInfo;
+ CK_C_InitToken C_InitToken;
+ CK_C_InitPIN C_InitPIN;
+ CK_C_SetPIN C_SetPIN;
+ CK_C_OpenSession C_OpenSession;
+ CK_C_CloseSession C_CloseSession;
+ CK_C_CloseAllSessions C_CloseAllSessions;
+ CK_C_GetSessionInfo C_GetSessionInfo;
+ CK_C_GetOperationState C_GetOperationState;
+ CK_C_SetOperationState C_SetOperationState;
+ CK_C_Login C_Login;
+ CK_C_Logout C_Logout;
+ CK_C_CreateObject C_CreateObject;
+ CK_C_CopyObject C_CopyObject;
+ CK_C_DestroyObject C_DestroyObject;
+ CK_C_GetObjectSize C_GetObjectSize;
+ CK_C_GetAttributeValue C_GetAttributeValue;
+ CK_C_SetAttributeValue C_SetAttributeValue;
+ CK_C_FindObjectsInit C_FindObjectsInit;
+ CK_C_FindObjects C_FindObjects;
+ CK_C_FindObjectsFinal C_FindObjectsFinal;
+ CK_C_EncryptInit C_EncryptInit;
+ CK_C_Encrypt C_Encrypt;
+ CK_C_EncryptUpdate C_EncryptUpdate;
+ CK_C_EncryptFinal C_EncryptFinal;
+ CK_C_DecryptInit C_DecryptInit;
+ CK_C_Decrypt C_Decrypt;
+ CK_C_DecryptUpdate C_DecryptUpdate;
+ CK_C_DecryptFinal C_DecryptFinal;
+ CK_C_DigestInit C_DigestInit;
+ CK_C_Digest C_Digest;
+ CK_C_DigestUpdate C_DigestUpdate;
+ CK_C_DigestKey C_DigestKey;
+ CK_C_DigestFinal C_DigestFinal;
+ CK_C_SignInit C_SignInit;
+ CK_C_Sign C_Sign;
+ CK_C_SignUpdate C_SignUpdate;
+ CK_C_SignFinal C_SignFinal;
+ CK_C_SignRecoverInit C_SignRecoverInit;
+ CK_C_SignRecover C_SignRecover;
+ CK_C_VerifyInit C_VerifyInit;
+ CK_C_Verify C_Verify;
+ CK_C_VerifyUpdate C_VerifyUpdate;
+ CK_C_VerifyFinal C_VerifyFinal;
+ CK_C_VerifyRecoverInit C_VerifyRecoverInit;
+ CK_C_VerifyRecover C_VerifyRecover;
+ CK_C_DigestEncryptUpdate C_DigestEncryptUpdate;
+ CK_C_DecryptDigestUpdate C_DecryptDigestUpdate;
+ CK_C_SignEncryptUpdate C_SignEncryptUpdate;
+ CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate;
+ CK_C_GenerateKey C_GenerateKey;
+ CK_C_GenerateKeyPair C_GenerateKeyPair;
+ CK_C_WrapKey C_WrapKey;
+ CK_C_UnwrapKey C_UnwrapKey;
+ CK_C_DeriveKey C_DeriveKey;
+ CK_C_SeedRandom C_SeedRandom;
+ CK_C_GenerateRandom C_GenerateRandom;
+ CK_C_GetFunctionStatus C_GetFunctionStatus;
+ CK_C_CancelFunction C_CancelFunction;
+ CK_C_WaitForSlotEvent C_WaitForSlotEvent;
+ /* PKCS #11 3.0 functions */
+ CK_C_GetInterfaceList C_GetInterfaceList;
+ CK_C_GetInterface C_GetInterface;
+ CK_C_LoginUser C_LoginUser;
+ CK_C_SessionCancel C_SessionCancel;
+ CK_C_MessageEncryptInit C_MessageEncryptInit;
+ CK_C_EncryptMessage C_EncryptMessage;
+ CK_C_EncryptMessageBegin C_EncryptMessageBegin;
+ CK_C_EncryptMessageNext C_EncryptMessageNext;
+ CK_C_MessageEncryptFinal C_MessageEncryptFinal;
+ CK_C_MessageDecryptInit C_MessageDecryptInit;
+ CK_C_DecryptMessage C_DecryptMessage;
+ CK_C_DecryptMessageBegin C_DecryptMessageBegin;
+ CK_C_DecryptMessageNext C_DecryptMessageNext;
+ CK_C_MessageDecryptFinal C_MessageDecryptFinal;
+ CK_C_MessageSignInit C_MessageSignInit;
+ CK_C_SignMessage C_SignMessage;
+ CK_C_SignMessageBegin C_SignMessageBegin;
+ CK_C_SignMessageNext C_SignMessageNext;
+ CK_C_MessageSignFinal C_MessageSignFinal;
+ CK_C_MessageVerifyInit C_MessageVerifyInit;
+ CK_C_VerifyMessage C_VerifyMessage;
+ CK_C_VerifyMessageBegin C_VerifyMessageBegin;
+ CK_C_VerifyMessageNext C_VerifyMessageNext;
+ CK_C_MessageVerifyFinal C_MessageVerifyFinal;
+};
+
+
typedef ck_rv_t (*ck_createmutex_t) (void **mutex);
typedef ck_rv_t (*ck_destroymutex_t) (void *mutex);
@@ -1091,96 +1603,97 @@ struct ck_c_initialize_args
};
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0)
-#define CKF_OS_LOCKING_OK (1 << 1)
-
-#define CKR_OK (0)
-#define CKR_CANCEL (1)
-#define CKR_HOST_MEMORY (2)
-#define CKR_SLOT_ID_INVALID (3)
-#define CKR_GENERAL_ERROR (5)
-#define CKR_FUNCTION_FAILED (6)
-#define CKR_ARGUMENTS_BAD (7)
-#define CKR_NO_EVENT (8)
-#define CKR_NEED_TO_CREATE_THREADS (9)
-#define CKR_CANT_LOCK (0xa)
-#define CKR_ATTRIBUTE_READ_ONLY (0x10)
-#define CKR_ATTRIBUTE_SENSITIVE (0x11)
-#define CKR_ATTRIBUTE_TYPE_INVALID (0x12)
-#define CKR_ATTRIBUTE_VALUE_INVALID (0x13)
-#define CKR_DATA_INVALID (0x20)
-#define CKR_DATA_LEN_RANGE (0x21)
-#define CKR_DEVICE_ERROR (0x30)
-#define CKR_DEVICE_MEMORY (0x31)
-#define CKR_DEVICE_REMOVED (0x32)
-#define CKR_ENCRYPTED_DATA_INVALID (0x40)
-#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41)
-#define CKR_FUNCTION_CANCELED (0x50)
-#define CKR_FUNCTION_NOT_PARALLEL (0x51)
-#define CKR_FUNCTION_NOT_SUPPORTED (0x54)
-#define CKR_KEY_HANDLE_INVALID (0x60)
-#define CKR_KEY_SIZE_RANGE (0x62)
-#define CKR_KEY_TYPE_INCONSISTENT (0x63)
-#define CKR_KEY_NOT_NEEDED (0x64)
-#define CKR_KEY_CHANGED (0x65)
-#define CKR_KEY_NEEDED (0x66)
-#define CKR_KEY_INDIGESTIBLE (0x67)
-#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68)
-#define CKR_KEY_NOT_WRAPPABLE (0x69)
-#define CKR_KEY_UNEXTRACTABLE (0x6a)
-#define CKR_MECHANISM_INVALID (0x70)
-#define CKR_MECHANISM_PARAM_INVALID (0x71)
-#define CKR_OBJECT_HANDLE_INVALID (0x82)
-#define CKR_OPERATION_ACTIVE (0x90)
-#define CKR_OPERATION_NOT_INITIALIZED (0x91)
-#define CKR_PIN_INCORRECT (0xa0)
-#define CKR_PIN_INVALID (0xa1)
-#define CKR_PIN_LEN_RANGE (0xa2)
-#define CKR_PIN_EXPIRED (0xa3)
-#define CKR_PIN_LOCKED (0xa4)
-#define CKR_SESSION_CLOSED (0xb0)
-#define CKR_SESSION_COUNT (0xb1)
-#define CKR_SESSION_HANDLE_INVALID (0xb3)
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4)
-#define CKR_SESSION_READ_ONLY (0xb5)
-#define CKR_SESSION_EXISTS (0xb6)
-#define CKR_SESSION_READ_ONLY_EXISTS (0xb7)
-#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8)
-#define CKR_SIGNATURE_INVALID (0xc0)
-#define CKR_SIGNATURE_LEN_RANGE (0xc1)
-#define CKR_TEMPLATE_INCOMPLETE (0xd0)
-#define CKR_TEMPLATE_INCONSISTENT (0xd1)
-#define CKR_TOKEN_NOT_PRESENT (0xe0)
-#define CKR_TOKEN_NOT_RECOGNIZED (0xe1)
-#define CKR_TOKEN_WRITE_PROTECTED (0xe2)
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0)
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1)
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2)
-#define CKR_USER_ALREADY_LOGGED_IN (0x100)
-#define CKR_USER_NOT_LOGGED_IN (0x101)
-#define CKR_USER_PIN_NOT_INITIALIZED (0x102)
-#define CKR_USER_TYPE_INVALID (0x103)
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104)
-#define CKR_USER_TOO_MANY_TYPES (0x105)
-#define CKR_WRAPPED_KEY_INVALID (0x110)
-#define CKR_WRAPPED_KEY_LEN_RANGE (0x112)
-#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113)
-#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114)
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115)
-#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120)
-#define CKR_RANDOM_NO_RNG (0x121)
-#define CKR_DOMAIN_PARAMS_INVALID (0x130)
-#define CKR_BUFFER_TOO_SMALL (0x150)
-#define CKR_SAVED_STATE_INVALID (0x160)
-#define CKR_INFORMATION_SENSITIVE (0x170)
-#define CKR_STATE_UNSAVEABLE (0x180)
-#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190)
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191)
-#define CKR_MUTEX_BAD (0x1a0)
-#define CKR_MUTEX_NOT_LOCKED (0x1a1)
-#define CKR_FUNCTION_REJECTED (0x200)
-#define CKR_VENDOR_DEFINED (1U << 31)
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0)
+#define CKF_OS_LOCKING_OK (1UL << 1)
+#define CKR_OK (0UL)
+#define CKR_CANCEL (1UL)
+#define CKR_HOST_MEMORY (2UL)
+#define CKR_SLOT_ID_INVALID (3UL)
+#define CKR_GENERAL_ERROR (5UL)
+#define CKR_FUNCTION_FAILED (6UL)
+#define CKR_ARGUMENTS_BAD (7UL)
+#define CKR_NO_EVENT (8UL)
+#define CKR_NEED_TO_CREATE_THREADS (9UL)
+#define CKR_CANT_LOCK (0xaUL)
+#define CKR_ATTRIBUTE_READ_ONLY (0x10UL)
+#define CKR_ATTRIBUTE_SENSITIVE (0x11UL)
+#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL)
+#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL)
+#define CKR_ACTION_PROHIBITED (0x1BUL)
+#define CKR_DATA_INVALID (0x20UL)
+#define CKR_DATA_LEN_RANGE (0x21UL)
+#define CKR_DEVICE_ERROR (0x30UL)
+#define CKR_DEVICE_MEMORY (0x31UL)
+#define CKR_DEVICE_REMOVED (0x32UL)
+#define CKR_ENCRYPTED_DATA_INVALID (0x40UL)
+#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL)
+#define CKR_FUNCTION_CANCELED (0x50UL)
+#define CKR_FUNCTION_NOT_PARALLEL (0x51UL)
+#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL)
+#define CKR_KEY_HANDLE_INVALID (0x60UL)
+#define CKR_KEY_SIZE_RANGE (0x62UL)
+#define CKR_KEY_TYPE_INCONSISTENT (0x63UL)
+#define CKR_KEY_NOT_NEEDED (0x64UL)
+#define CKR_KEY_CHANGED (0x65UL)
+#define CKR_KEY_NEEDED (0x66UL)
+#define CKR_KEY_INDIGESTIBLE (0x67UL)
+#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL)
+#define CKR_KEY_NOT_WRAPPABLE (0x69UL)
+#define CKR_KEY_UNEXTRACTABLE (0x6aUL)
+#define CKR_MECHANISM_INVALID (0x70UL)
+#define CKR_MECHANISM_PARAM_INVALID (0x71UL)
+#define CKR_OBJECT_HANDLE_INVALID (0x82UL)
+#define CKR_OPERATION_ACTIVE (0x90UL)
+#define CKR_OPERATION_NOT_INITIALIZED (0x91UL)
+#define CKR_PIN_INCORRECT (0xa0UL)
+#define CKR_PIN_INVALID (0xa1UL)
+#define CKR_PIN_LEN_RANGE (0xa2UL)
+#define CKR_PIN_EXPIRED (0xa3UL)
+#define CKR_PIN_LOCKED (0xa4UL)
+#define CKR_SESSION_CLOSED (0xb0UL)
+#define CKR_SESSION_COUNT (0xb1UL)
+#define CKR_SESSION_HANDLE_INVALID (0xb3UL)
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL)
+#define CKR_SESSION_READ_ONLY (0xb5UL)
+#define CKR_SESSION_EXISTS (0xb6UL)
+#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL)
+#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL)
+#define CKR_SIGNATURE_INVALID (0xc0UL)
+#define CKR_SIGNATURE_LEN_RANGE (0xc1UL)
+#define CKR_TEMPLATE_INCOMPLETE (0xd0UL)
+#define CKR_TEMPLATE_INCONSISTENT (0xd1UL)
+#define CKR_TOKEN_NOT_PRESENT (0xe0UL)
+#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL)
+#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL)
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL)
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL)
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL)
+#define CKR_USER_ALREADY_LOGGED_IN (0x100UL)
+#define CKR_USER_NOT_LOGGED_IN (0x101UL)
+#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL)
+#define CKR_USER_TYPE_INVALID (0x103UL)
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL)
+#define CKR_USER_TOO_MANY_TYPES (0x105UL)
+#define CKR_WRAPPED_KEY_INVALID (0x110UL)
+#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL)
+#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL)
+#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL)
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL)
+#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL)
+#define CKR_RANDOM_NO_RNG (0x121UL)
+#define CKR_DOMAIN_PARAMS_INVALID (0x130UL)
+#define CKR_CURVE_NOT_SUPPORTED (0x140UL)
+#define CKR_BUFFER_TOO_SMALL (0x150UL)
+#define CKR_SAVED_STATE_INVALID (0x160UL)
+#define CKR_INFORMATION_SENSITIVE (0x170UL)
+#define CKR_STATE_UNSAVEABLE (0x180UL)
+#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL)
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL)
+#define CKR_MUTEX_BAD (0x1a0UL)
+#define CKR_MUTEX_NOT_LOCKED (0x1a1UL)
+#define CKR_FUNCTION_REJECTED (0x200UL)
+#define CKR_VENDOR_DEFINED (1UL << 31)
/* Compatibility layer. */
@@ -1216,6 +1729,22 @@ typedef void **CK_VOID_PTR_PTR;
#endif
#endif
+typedef struct CK_HKDF_PARAMS {
+ CK_BBOOL bExtract;
+ CK_BBOOL bExpand;
+ CK_MECHANISM_TYPE prfHashMechanism;
+ CK_ULONG ulSaltType;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_OBJECT_HANDLE hSaltKey;
+ CK_BYTE_PTR pInfo;
+ CK_ULONG ulInfoLen;
+} CK_HKDF_PARAMS;
+
+#define CKF_HKDF_SALT_NULL 0x00000001UL
+#define CKF_HKDF_SALT_DATA 0x00000002UL
+#define CKF_HKDF_SALT_KEY 0x00000004UL
+
typedef struct ck_version CK_VERSION;
typedef struct ck_version *CK_VERSION_PTR;
@@ -1247,16 +1776,26 @@ typedef struct ck_date *CK_DATE_PTR;
typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR;
+typedef ck_rsa_pkcs_mgf_type_t *CK_RSA_PKCS_MGF_TYPE_PTR;
+
typedef struct ck_mechanism CK_MECHANISM;
typedef struct ck_mechanism *CK_MECHANISM_PTR;
typedef struct ck_mechanism_info CK_MECHANISM_INFO;
typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR;
+typedef struct ck_interface CK_INTERFACE;
+typedef struct ck_interface *CK_INTERFACE_PTR;
+typedef struct ck_interface **CK_INTERFACE_PTR_PTR;
+
typedef struct ck_function_list CK_FUNCTION_LIST;
typedef struct ck_function_list *CK_FUNCTION_LIST_PTR;
typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
+typedef struct ck_function_list_3_0 CK_FUNCTION_LIST_3_0;
+typedef struct ck_function_list_3_0 *CK_FUNCTION_LIST_3_0_PTR;
+typedef struct ck_function_list_3_0 **CK_FUNCTION_LIST_3_0_PTR_PTR;
+
typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS;
typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
@@ -1317,6 +1856,8 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
#undef ck_mechanism_type_t
+#undef ck_rsa_pkcs_mgf_type_t
+
#undef ck_mechanism
#undef parameter
#undef parameter_len
@@ -1328,7 +1869,10 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
#undef ck_rv_t
#undef ck_notify_t
+#undef ck_interface
+
#undef ck_function_list
+#undef ck_function_list_3_0
#undef ck_createmutex_t
#undef ck_destroymutex_t
@@ -1344,7 +1888,6 @@ typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
#endif /* CRYPTOKI_COMPAT */
-
/* System dependencies. */
#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32)
#pragma pack(pop, cryptoki)
openssh: refactor PKCS#11 and add support for Ed25519