iPXE
dhe.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27/** @file
28 *
29 * Ephemeral Diffie-Hellman key exchange
30 *
31 */
32
33#include <stdint.h>
34#include <stdlib.h>
35#include <errno.h>
36#include <ipxe/bigint.h>
37#include <ipxe/dhe.h>
38
39/**
40 * Calculate Diffie-Hellman key
41 *
42 * @v modulus Prime modulus
43 * @v len Length of prime modulus
44 * @v generator Generator
45 * @v generator_len Length of generator
46 * @v partner Partner public key
47 * @v partner_len Length of partner public key
48 * @v private Private key
49 * @v private_len Length of private key
50 * @ret public Public key (length equal to prime modulus)
51 * @ret shared Shared secret (length equal to prime modulus)
52 * @ret rc Return status code
53 */
54int dhe_key ( const void *modulus, size_t len, const void *generator,
55 size_t generator_len, const void *partner, size_t partner_len,
56 const void *private, size_t private_len, void *public,
57 void *shared ) {
58 unsigned int size = bigint_required_size ( len );
59 unsigned int private_size = bigint_required_size ( private_len );
60 bigint_t ( size ) *mod;
61 size_t tmp_len = bigint_mod_exp_tmp_len ( mod );
62 struct {
63 bigint_t ( size ) modulus;
64 bigint_t ( size ) generator;
66 bigint_t ( private_size ) private;
68 uint8_t tmp[tmp_len];
69 } __attribute__ (( packed )) *ctx;
70 int rc;
71
72 DBGC2 ( modulus, "DHE %p modulus:\n", modulus );
73 DBGC2_HDA ( modulus, 0, modulus, len );
74 DBGC2 ( modulus, "DHE %p generator:\n", modulus );
75 DBGC2_HDA ( modulus, 0, generator, generator_len );
76 DBGC2 ( modulus, "DHE %p partner public key:\n", modulus );
77 DBGC2_HDA ( modulus, 0, partner, partner_len );
78 DBGC2 ( modulus, "DHE %p private key:\n", modulus );
79 DBGC2_HDA ( modulus, 0, private, private_len );
80
81 /* Sanity checks */
82 if ( generator_len > len ) {
83 DBGC ( modulus, "DHE %p overlength generator\n", modulus );
84 rc = -EINVAL;
85 goto err_sanity;
86 }
87 if ( partner_len > len ) {
88 DBGC ( modulus, "DHE %p overlength partner public key\n",
89 modulus );
90 rc = -EINVAL;
91 goto err_sanity;
92 }
93 if ( private_len > len ) {
94 DBGC ( modulus, "DHE %p overlength private key\n", modulus );
95 rc = -EINVAL;
96 goto err_sanity;
97 }
98
99 /* Allocate context */
100 ctx = malloc ( sizeof ( *ctx ) );
101 if ( ! ctx ) {
102 rc = -ENOMEM;
103 goto err_alloc;
104 }
105
106 /* Initialise context */
107 bigint_init ( &ctx->modulus, modulus, len );
108 bigint_init ( &ctx->generator, generator, generator_len );
109 bigint_init ( &ctx->partner, partner, partner_len );
110 bigint_init ( &ctx->private, private, private_len );
111
112 /* Calculate public key */
113 bigint_mod_exp ( &ctx->generator, &ctx->modulus, &ctx->private,
114 &ctx->result, ctx->tmp );
115 bigint_done ( &ctx->result, public, len );
116 DBGC2 ( modulus, "DHE %p public key:\n", modulus );
117 DBGC2_HDA ( modulus, 0, public, len );
118
119 /* Calculate shared secret */
120 bigint_mod_exp ( &ctx->partner, &ctx->modulus, &ctx->private,
121 &ctx->result, ctx->tmp );
122 bigint_done ( &ctx->result, shared, len );
123 DBGC2 ( modulus, "DHE %p shared secret:\n", modulus );
124 DBGC2_HDA ( modulus, 0, shared, len );
125
126 /* Success */
127 rc = 0;
128
129 free ( ctx );
130 err_alloc:
131 err_sanity:
132 return rc;
133}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint16_t result
Definition hyperv.h:33
unsigned char uint8_t
Definition stdint.h:10
int dhe_key(const void *modulus, size_t len, const void *generator, size_t generator_len, const void *partner, size_t partner_len, const void *private, size_t private_len, void *public, void *shared)
Calculate Diffie-Hellman key.
Definition dhe.c:54
Ephemeral Diffie-Hellman key exchange.
ring len
Length.
Definition dwmac.h:226
Error codes.
struct eth_slow_lacp_entity_tlv partner
Partner information.
Definition eth_slow.h:5
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
Big integer support.
#define bigint_mod_exp(base, modulus, exponent, result, tmp)
Perform modular exponentiation of big integers.
Definition bigint.h:347
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition bigint.h:361
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:31
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
unsigned long tmp
Definition linux_pci.h:65
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55