xref: /aosp_15_r20/external/boringssl/src/crypto/evp/p_dh.c (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /*
2  * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <openssl/evp.h>
11 
12 #include <assert.h>
13 
14 #include <openssl/dh.h>
15 #include <openssl/err.h>
16 #include <openssl/mem.h>
17 
18 #include "internal.h"
19 
20 
21 typedef struct dh_pkey_ctx_st {
22   int pad;
23 } DH_PKEY_CTX;
24 
pkey_dh_init(EVP_PKEY_CTX * ctx)25 static int pkey_dh_init(EVP_PKEY_CTX *ctx) {
26   DH_PKEY_CTX *dctx = OPENSSL_zalloc(sizeof(DH_PKEY_CTX));
27   if (dctx == NULL) {
28     return 0;
29   }
30 
31   ctx->data = dctx;
32   return 1;
33 }
34 
pkey_dh_copy(EVP_PKEY_CTX * dst,EVP_PKEY_CTX * src)35 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
36   if (!pkey_dh_init(dst)) {
37     return 0;
38   }
39 
40   const DH_PKEY_CTX *sctx = src->data;
41   DH_PKEY_CTX *dctx = dst->data;
42   dctx->pad = sctx->pad;
43   return 1;
44 }
45 
pkey_dh_cleanup(EVP_PKEY_CTX * ctx)46 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) {
47   OPENSSL_free(ctx->data);
48   ctx->data = NULL;
49 }
50 
pkey_dh_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)51 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
52   DH *dh = DH_new();
53   if (dh == NULL || !EVP_PKEY_assign_DH(pkey, dh)) {
54     DH_free(dh);
55     return 0;
56   }
57 
58   if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey)) {
59     return 0;
60   }
61 
62   return DH_generate_key(dh);
63 }
64 
pkey_dh_derive(EVP_PKEY_CTX * ctx,uint8_t * out,size_t * out_len)65 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len) {
66   DH_PKEY_CTX *dctx = ctx->data;
67   if (ctx->pkey == NULL || ctx->peerkey == NULL) {
68     OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
69     return 0;
70   }
71 
72   DH *our_key = ctx->pkey->pkey;
73   DH *peer_key = ctx->peerkey->pkey;
74   if (our_key == NULL || peer_key == NULL) {
75     OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
76     return 0;
77   }
78 
79   const BIGNUM *pub_key = DH_get0_pub_key(peer_key);
80   if (pub_key == NULL) {
81     OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
82     return 0;
83   }
84 
85   if (out == NULL) {
86     *out_len = DH_size(our_key);
87     return 1;
88   }
89 
90   if (*out_len < (size_t)DH_size(our_key)) {
91     OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
92     return 0;
93   }
94 
95   int ret = dctx->pad ? DH_compute_key_padded(out, pub_key, our_key)
96                       : DH_compute_key(out, pub_key, our_key);
97   if (ret < 0) {
98     return 0;
99   }
100 
101   assert(ret <= DH_size(our_key));
102   *out_len = (size_t)ret;
103   return 1;
104 }
105 
pkey_dh_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)106 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
107   DH_PKEY_CTX *dctx = ctx->data;
108   switch (type) {
109     case EVP_PKEY_CTRL_PEER_KEY:
110       // |EVP_PKEY_derive_set_peer| requires the key implement this command,
111       // even if it is a no-op.
112       return 1;
113 
114     case EVP_PKEY_CTRL_DH_PAD:
115       dctx->pad = p1;
116       return 1;
117 
118     default:
119       OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
120       return 0;
121   }
122 }
123 
124 const EVP_PKEY_METHOD dh_pkey_meth = {
125     .pkey_id = EVP_PKEY_DH,
126     .init = pkey_dh_init,
127     .copy = pkey_dh_copy,
128     .cleanup = pkey_dh_cleanup,
129     .keygen = pkey_dh_keygen,
130     .derive = pkey_dh_derive,
131     .ctrl = pkey_dh_ctrl,
132 };
133 
EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX * ctx,int pad)134 int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) {
135   return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE,
136                            EVP_PKEY_CTRL_DH_PAD, pad, NULL);
137 }
138