1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include "pal_evp_pkey_ecdh.h"
EVP_PKEY_CTX* CryptoNative_EvpPKeyCtxCreate(EVP_PKEY* pkey, EVP_PKEY* peerkey, uint32_t* secretLength)
{
if (secretLength != NULL)
*secretLength = 0;
if (pkey == NULL || peerkey == NULL || secretLength == NULL)
{
return NULL;
}
/* Create the context for the shared secret derivation */
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (ctx == NULL)
{
return NULL;
}
size_t tmpLength = 0;
/* Initialize, provide the peer public key, and determine the buffer size */
if (1 != EVP_PKEY_derive_init(ctx) || 1 != EVP_PKEY_derive_set_peer(ctx, peerkey) ||
1 != EVP_PKEY_derive(ctx, NULL, &tmpLength))
{
EVP_PKEY_CTX_free(ctx);
return NULL;
}
*secretLength = (uint32_t)tmpLength;
return ctx;
}
int32_t CryptoNative_EvpPKeyDeriveSecretAgreement(uint8_t* secret, uint32_t secretLength, EVP_PKEY_CTX* ctx)
{
size_t tmpSize = (size_t)secretLength;
int ret = 0;
if (secret != NULL && ctx != NULL)
{
ret = EVP_PKEY_derive(ctx, secret, &tmpSize);
if (ret == 1 && tmpSize != (size_t)secretLength)
{
OPENSSL_cleanse(secret, secretLength);
ret = 0;
}
}
return ret;
}
void CryptoNative_EvpPKeyCtxDestroy(EVP_PKEY_CTX* ctx)
{
if (ctx != NULL)
{
EVP_PKEY_CTX_free(ctx);
}
}
|