1 /* 2 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <string.h> 11 #include <openssl/err.h> 12 #include "crypto/ecx.h" 13 14 ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, 15 const char *propq) 16 { 17 ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); 18 19 if (ret == NULL) 20 return NULL; 21 22 ret->libctx = libctx; 23 ret->haspubkey = haspubkey; 24 switch (type) { 25 case ECX_KEY_TYPE_X25519: 26 ret->keylen = X25519_KEYLEN; 27 break; 28 case ECX_KEY_TYPE_X448: 29 ret->keylen = X448_KEYLEN; 30 break; 31 case ECX_KEY_TYPE_ED25519: 32 ret->keylen = ED25519_KEYLEN; 33 break; 34 case ECX_KEY_TYPE_ED448: 35 ret->keylen = ED448_KEYLEN; 36 break; 37 } 38 ret->type = type; 39 ret->references = 1; 40 41 if (propq != NULL) { 42 ret->propq = OPENSSL_strdup(propq); 43 if (ret->propq == NULL) 44 goto err; 45 } 46 47 ret->lock = CRYPTO_THREAD_lock_new(); 48 if (ret->lock == NULL) 49 goto err; 50 return ret; 51 err: 52 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 53 OPENSSL_free(ret); 54 return NULL; 55 } 56 57 void ossl_ecx_key_free(ECX_KEY *key) 58 { 59 int i; 60 61 if (key == NULL) 62 return; 63 64 CRYPTO_DOWN_REF(&key->references, &i, key->lock); 65 REF_PRINT_COUNT("ECX_KEY", key); 66 if (i > 0) 67 return; 68 REF_ASSERT_ISNT(i < 0); 69 70 OPENSSL_free(key->propq); 71 OPENSSL_secure_clear_free(key->privkey, key->keylen); 72 CRYPTO_THREAD_lock_free(key->lock); 73 OPENSSL_free(key); 74 } 75 76 void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx) 77 { 78 key->libctx = libctx; 79 } 80 81 int ossl_ecx_key_up_ref(ECX_KEY *key) 82 { 83 int i; 84 85 if (CRYPTO_UP_REF(&key->references, &i, key->lock) <= 0) 86 return 0; 87 88 REF_PRINT_COUNT("ECX_KEY", key); 89 REF_ASSERT_ISNT(i < 2); 90 return ((i > 1) ? 1 : 0); 91 } 92 93 unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key) 94 { 95 key->privkey = OPENSSL_secure_zalloc(key->keylen); 96 97 return key->privkey; 98 } 99