Line | Count | Source |
1 | | /* ecdh.c - ECDH public key operations used in public key glue code |
2 | | * Copyright (C) 2010, 2011 Free Software Foundation, Inc. |
3 | | * |
4 | | * This file is part of GnuPG. |
5 | | * |
6 | | * GnuPG is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * GnuPG is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include <config.h> |
21 | | #include <stdio.h> |
22 | | #include <stdlib.h> |
23 | | #include <string.h> |
24 | | #include <errno.h> |
25 | | |
26 | | #include "gpg.h" |
27 | | #include "../common/util.h" |
28 | | #include "pkglue.h" |
29 | | #include "main.h" |
30 | | #include "options.h" |
31 | | |
32 | | /* A table with the default KEK parameters used by GnuPG. */ |
33 | | static const struct |
34 | | { |
35 | | unsigned int qbits; |
36 | | int openpgp_hash_id; /* KEK digest algorithm. */ |
37 | | int openpgp_cipher_id; /* KEK cipher algorithm. */ |
38 | | } kek_params_table[] = |
39 | | /* Note: Must be sorted by ascending values for QBITS. */ |
40 | | { |
41 | | { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, |
42 | | { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, |
43 | | |
44 | | /* Note: 528 is 521 rounded to the 8 bit boundary */ |
45 | | { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } |
46 | | }; |
47 | | |
48 | | |
49 | | |
50 | | /* Return KEK parameters as an opaque MPI The caller must free the |
51 | | returned value. Returns NULL and sets ERRNO on error. */ |
52 | | gcry_mpi_t |
53 | | pk_ecdh_default_params (unsigned int qbits) |
54 | 0 | { |
55 | 0 | byte kek_params[4] = { |
56 | 0 | 3, /* Number of bytes to follow. */ |
57 | 0 | 1 /* Version for KDF+AESWRAP. */ |
58 | 0 | }; |
59 | 0 | int i; |
60 | | |
61 | | /* Search for matching KEK parameter. Defaults to the strongest |
62 | | possible choices. Performance is not an issue here, only |
63 | | interoperability. */ |
64 | 0 | for (i=0; i < DIM (kek_params_table); i++) |
65 | 0 | { |
66 | 0 | if (kek_params_table[i].qbits >= qbits |
67 | 0 | || i+1 == DIM (kek_params_table)) |
68 | 0 | { |
69 | 0 | kek_params[2] = kek_params_table[i].openpgp_hash_id; |
70 | 0 | kek_params[3] = kek_params_table[i].openpgp_cipher_id; |
71 | 0 | break; |
72 | 0 | } |
73 | 0 | } |
74 | 0 | log_assert (i < DIM (kek_params_table)); |
75 | 0 | if (DBG_CRYPTO) |
76 | 0 | log_printhex (kek_params, sizeof(kek_params), "ECDH KEK params are"); |
77 | |
|
78 | 0 | return gcry_mpi_set_opaque_copy (NULL, kek_params, 4 * 8); |
79 | 0 | } |
80 | | |
81 | | |
82 | | /* Build KDF parameters */ |
83 | | /* RFC 6637 defines the KDF parameters and its encoding in Section |
84 | | 8. EC DH Algorighm (ECDH). Since it was written for v4 key, it |
85 | | said "20 octets representing a recipient encryption subkey or a |
86 | | master key fingerprint". For v5 key, it is considered "adequate" |
87 | | (in terms of NIST SP 800 56A, see 5.8.2 FixedInfo) to use the first |
88 | | 20 octets of its 32 octets fingerprint. */ |
89 | | gpg_error_t |
90 | | ecc_build_kdf_params (unsigned char **r_kdf_params, size_t *r_len, |
91 | | const unsigned char **r_kdf_params_spec, |
92 | | gcry_mpi_t *pkey, const byte fp[MAX_FINGERPRINT_LEN]) |
93 | 0 | { |
94 | 0 | const unsigned char *oid; |
95 | 0 | const unsigned char *kdf_params_spec; |
96 | 0 | unsigned int nbits; |
97 | 0 | size_t oid_len; |
98 | 0 | size_t len; |
99 | 0 | unsigned char *kdf_params = NULL; |
100 | 0 | int kdf_params_len = 0; |
101 | |
|
102 | 0 | if (!gcry_mpi_get_flag (pkey[0], GCRYMPI_FLAG_OPAQUE)) |
103 | 0 | return gpg_error (GPG_ERR_BAD_PUBKEY); |
104 | | |
105 | 0 | oid = gcry_mpi_get_opaque (pkey[0], &nbits); |
106 | 0 | oid_len = (nbits+7)/8; |
107 | | |
108 | | /* In the public key part, there is a specifier of KDF parameters |
109 | | (namely, hash algo for KDF and symmetric algo for wrapping key). |
110 | | Using this specifier (together with curve OID of the public key |
111 | | and the fingerprint), we build _the_ KDF parameters. */ |
112 | 0 | if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE)) |
113 | 0 | return gpg_error (GPG_ERR_BAD_PUBKEY); |
114 | | |
115 | 0 | kdf_params_spec = gcry_mpi_get_opaque (pkey[2], &nbits); |
116 | 0 | len = (nbits+7)/8; |
117 | | |
118 | | /* Expect 4 bytes 03 01 hash_alg symm_alg. */ |
119 | 0 | if (len != 4 || kdf_params_spec[0] != 3 || kdf_params_spec[1] != 1) |
120 | 0 | return gpg_error (GPG_ERR_BAD_PUBKEY); |
121 | | |
122 | 0 | kdf_params_len = oid_len + 1 + 4 + 20 + 20; |
123 | 0 | kdf_params = xtrymalloc (kdf_params_len); |
124 | 0 | if (!kdf_params) |
125 | 0 | return gpg_error_from_syserror (); |
126 | | |
127 | 0 | memcpy (kdf_params, oid, oid_len); |
128 | 0 | kdf_params[oid_len] = PUBKEY_ALGO_ECDH; |
129 | 0 | memcpy (kdf_params + oid_len + 1, kdf_params_spec, 4); |
130 | 0 | memcpy (kdf_params + oid_len + 1 + 4, "Anonymous Sender ", 20); |
131 | 0 | memcpy (kdf_params + oid_len + 1 + 4 + 20, fp, 20); |
132 | |
|
133 | 0 | if (DBG_CRYPTO) |
134 | 0 | log_printhex (kdf_params, kdf_params_len, |
135 | 0 | "ecdh KDF message params are:"); |
136 | |
|
137 | 0 | *r_kdf_params = kdf_params; |
138 | 0 | *r_len = kdf_params_len; |
139 | 0 | if (r_kdf_params_spec) |
140 | 0 | *r_kdf_params_spec = kdf_params_spec; |
141 | 0 | return 0; |
142 | 0 | } |