summaryrefslogtreecommitdiffstats
path: root/crypto/ec/ecx_key.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-01-27 16:50:47 +0000
committerMatt Caswell <matt@openssl.org>2020-02-11 22:32:47 +0000
commit4de88fe6daad0b7bd65b20bc887ff1ac62ae2ce8 (patch)
tree0efbd17f92152f5a091238799a171a6565232e50 /crypto/ec/ecx_key.c
parent620c97b671a9c7bc31ca36a24b2242aa1aa80022 (diff)
Implement a stricter ECX_KEY type
Add ref counting and control how we allocate storage for the private key. We will need this type in following commits where we move the ecx code to be provider aware. Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10964)
Diffstat (limited to 'crypto/ec/ecx_key.c')
-rw-r--r--crypto/ec/ecx_key.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c
new file mode 100644
index 0000000000..59643cc6ad
--- /dev/null
+++ b/crypto/ec/ecx_key.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include "crypto/ecx.h"
+
+ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
+{
+ ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+ if (ret == NULL)
+ return NULL;
+
+ ret->haspubkey = haspubkey;
+ ret->keylen = keylen;
+ ret->references = 1;
+
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+void ecx_key_free(ECX_KEY *key)
+{
+ int i;
+
+ if (key == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&key->references, &i, key->lock);
+ REF_PRINT_COUNT("ECX_KEY", r);
+ if (i > 0)
+ return;
+ REF_ASSERT_ISNT(i < 0);
+
+ OPENSSL_secure_clear_free(key->privkey, key->keylen);
+ CRYPTO_THREAD_lock_free(key->lock);
+ OPENSSL_free(key);
+}
+
+int ecx_key_up_ref(ECX_KEY *key)
+{
+ int i;
+
+ if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0)
+ return 0;
+
+ REF_PRINT_COUNT("ECX_KEY", key);
+ REF_ASSERT_ISNT(i < 2);
+ return ((i > 1) ? 1 : 0);
+}
+
+unsigned char *ecx_key_allocate_privkey(ECX_KEY *key)
+{
+ key->privkey = OPENSSL_secure_zalloc(key->keylen);
+
+ return key->privkey;
+}