summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2019-09-06 17:59:25 +0000
committerjsing <>2019-09-06 17:59:25 +0000
commit11474dfb0e4a1fb55d042fbfb4e2c68602f61508 (patch)
tree41fcc6b250b4f518c93bc01711ee02ee90e03002 /src
parentad62fd73e219aceeb5b13e772228acd3f93d6b23 (diff)
downloadopenbsd-11474dfb0e4a1fb55d042fbfb4e2c68602f61508.tar.gz
openbsd-11474dfb0e4a1fb55d042fbfb4e2c68602f61508.tar.bz2
openbsd-11474dfb0e4a1fb55d042fbfb4e2c68602f61508.zip
Add various macros and controls for EC_PKEY_CTX.
These are needed for the upcoming EC CMS support (nothing else appears to use them). This largely syncs our ec_pmeth.c with OpenSSL 1.1.1b. With input from inoguchi@ and tb@. ok inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/Makefile3
-rw-r--r--src/lib/libcrypto/ec/ec.h100
-rw-r--r--src/lib/libcrypto/ec/ec_err.c6
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c235
4 files changed, 316 insertions, 28 deletions
diff --git a/src/lib/libcrypto/Makefile b/src/lib/libcrypto/Makefile
index fe9e3774f8..3f86b2d0a1 100644
--- a/src/lib/libcrypto/Makefile
+++ b/src/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.34 2019/09/05 16:16:05 jsing Exp $ 1# $OpenBSD: Makefile,v 1.35 2019/09/06 17:59:24 jsing Exp $
2 2
3LIB= crypto 3LIB= crypto
4LIBREBUILD=y 4LIBREBUILD=y
@@ -34,6 +34,7 @@ CFLAGS+= -I${LCRYPTO_SRC}/modes
34# XXX FIXME ecdsa and ec should be merged 34# XXX FIXME ecdsa and ec should be merged
35CFLAGS+= -I${LCRYPTO_SRC}/ecdsa 35CFLAGS+= -I${LCRYPTO_SRC}/ecdsa
36CFLAGS+= -I${LCRYPTO_SRC}/ec 36CFLAGS+= -I${LCRYPTO_SRC}/ec
37CFLAGS+= -I${LCRYPTO_SRC}/ecdh
37 38
38VERSION_SCRIPT= Symbols.map 39VERSION_SCRIPT= Symbols.map
39SYMBOL_LIST= ${.CURDIR}/Symbols.list 40SYMBOL_LIST= ${.CURDIR}/Symbols.list
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 1c5641eca0..d0e3673675 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec.h,v 1.16 2019/01/19 01:17:41 tb Exp $ */ 1/* $OpenBSD: ec.h,v 1.17 2019/09/06 17:59:25 jsing Exp $ */
2/* 2/*
3 * Originally written by Bodo Moeller for the OpenSSL project. 3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */ 4 */
@@ -97,7 +97,7 @@ extern "C" {
97 97
98 98
99#ifndef OPENSSL_ECC_MAX_FIELD_BITS 99#ifndef OPENSSL_ECC_MAX_FIELD_BITS
100# define OPENSSL_ECC_MAX_FIELD_BITS 661 100#define OPENSSL_ECC_MAX_FIELD_BITS 661
101#endif 101#endif
102 102
103/** Enum for the point conversion form as defined in X9.62 (ECDSA) 103/** Enum for the point conversion form as defined in X9.62 (ECDSA)
@@ -714,6 +714,7 @@ typedef struct ec_key_method_st EC_KEY_METHOD;
714/* some values for the flags field */ 714/* some values for the flags field */
715#define EC_FLAG_NON_FIPS_ALLOW 0x1 715#define EC_FLAG_NON_FIPS_ALLOW 0x1
716#define EC_FLAG_FIPS_CHECKED 0x2 716#define EC_FLAG_FIPS_CHECKED 0x2
717#define EC_FLAG_COFACTOR_ECDH 0x1000
717 718
718/** Creates a new EC_KEY object. 719/** Creates a new EC_KEY object.
719 * \return EC_KEY object or NULL if an error occurred. 720 * \return EC_KEY object or NULL if an error occurred.
@@ -995,11 +996,96 @@ EC_KEY *ECParameters_dup(EC_KEY *key);
995#endif 996#endif
996 997
997#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ 998#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
998 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \ 999 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
999 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) 1000 EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
1000 1001 EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
1002
1003#define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
1004 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1005 EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
1006 EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)
1007
1008#define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
1009 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1010 EVP_PKEY_OP_DERIVE, \
1011 EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)
1012
1013#define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
1014 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1015 EVP_PKEY_OP_DERIVE, \
1016 EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)
1017
1018#define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
1019 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1020 EVP_PKEY_OP_DERIVE, \
1021 EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)
1022
1023#define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
1024 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1025 EVP_PKEY_OP_DERIVE, \
1026 EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)
1027
1028#define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
1029 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1030 EVP_PKEY_OP_DERIVE, \
1031 EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md))
1032
1033#define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
1034 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1035 EVP_PKEY_OP_DERIVE, \
1036 EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd))
1037
1038#define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
1039 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1040 EVP_PKEY_OP_DERIVE, \
1041 EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)
1042
1043#define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
1044 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1045 EVP_PKEY_OP_DERIVE, \
1046 EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, \
1047 (void *)(plen))
1048
1049#define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
1050 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1051 EVP_PKEY_OP_DERIVE, \
1052 EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)(p))
1053
1054#define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
1055 EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
1056 EVP_PKEY_OP_DERIVE, \
1057 EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p))
1058
1059/* SM2 will skip the operation check so no need to pass operation here */
1060#define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
1061 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
1062 EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))
1063
1064#define EVP_PKEY_CTX_get1_id(ctx, id) \
1065 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
1066 EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))
1067
1068#define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \
1069 EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
1070 EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len))
1001 1071
1002#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) 1072#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
1073#define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2)
1074#define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3)
1075#define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4)
1076#define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5)
1077#define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6)
1078#define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7)
1079#define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8)
1080#define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9)
1081#define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10)
1082#define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11)
1083#define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12)
1084#define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13)
1085
1086/* KDF types */
1087#define EVP_PKEY_ECDH_KDF_NONE 1
1088#define EVP_PKEY_ECDH_KDF_X9_63 2
1003 1089
1004/* BEGIN ERROR CODES */ 1090/* BEGIN ERROR CODES */
1005/* The following lines are auto generated by the script mkerr.pl. Any changes 1091/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -1172,6 +1258,7 @@ void ERR_load_EC_strings(void);
1172#define EC_R_INVALID_COMPRESSED_POINT 110 1258#define EC_R_INVALID_COMPRESSED_POINT 110
1173#define EC_R_INVALID_COMPRESSION_BIT 109 1259#define EC_R_INVALID_COMPRESSION_BIT 109
1174#define EC_R_INVALID_CURVE 141 1260#define EC_R_INVALID_CURVE 141
1261#define EC_R_INVALID_DIGEST 151
1175#define EC_R_INVALID_DIGEST_TYPE 138 1262#define EC_R_INVALID_DIGEST_TYPE 138
1176#define EC_R_INVALID_ENCODING 102 1263#define EC_R_INVALID_ENCODING 102
1177#define EC_R_INVALID_FIELD 103 1264#define EC_R_INVALID_FIELD 103
@@ -1180,6 +1267,7 @@ void ERR_load_EC_strings(void);
1180#define EC_R_INVALID_PENTANOMIAL_BASIS 132 1267#define EC_R_INVALID_PENTANOMIAL_BASIS 132
1181#define EC_R_INVALID_PRIVATE_KEY 123 1268#define EC_R_INVALID_PRIVATE_KEY 123
1182#define EC_R_INVALID_TRINOMIAL_BASIS 137 1269#define EC_R_INVALID_TRINOMIAL_BASIS 137
1270#define EC_R_KDF_PARAMETER_ERROR 148
1183#define EC_R_KEYS_NOT_SET 140 1271#define EC_R_KEYS_NOT_SET 140
1184#define EC_R_MISSING_PARAMETERS 124 1272#define EC_R_MISSING_PARAMETERS 124
1185#define EC_R_MISSING_PRIVATE_KEY 125 1273#define EC_R_MISSING_PRIVATE_KEY 125
@@ -1190,9 +1278,11 @@ void ERR_load_EC_strings(void);
1190#define EC_R_NO_FIELD_MOD 133 1278#define EC_R_NO_FIELD_MOD 133
1191#define EC_R_NO_PARAMETERS_SET 139 1279#define EC_R_NO_PARAMETERS_SET 139
1192#define EC_R_PASSED_NULL_PARAMETER 134 1280#define EC_R_PASSED_NULL_PARAMETER 134
1281#define EC_R_PEER_KEY_ERROR 149
1193#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 1282#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
1194#define EC_R_POINT_AT_INFINITY 106 1283#define EC_R_POINT_AT_INFINITY 106
1195#define EC_R_POINT_IS_NOT_ON_CURVE 107 1284#define EC_R_POINT_IS_NOT_ON_CURVE 107
1285#define EC_R_SHARED_INFO_ERROR 150
1196#define EC_R_SLOT_FULL 108 1286#define EC_R_SLOT_FULL 108
1197#define EC_R_UNDEFINED_GENERATOR 113 1287#define EC_R_UNDEFINED_GENERATOR 113
1198#define EC_R_UNDEFINED_ORDER 128 1288#define EC_R_UNDEFINED_ORDER 128
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
index fa5deceda5..7c42618881 100644
--- a/src/lib/libcrypto/ec/ec_err.c
+++ b/src/lib/libcrypto/ec/ec_err.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_err.c,v 1.10 2017/01/29 17:49:23 beck Exp $ */ 1/* $OpenBSD: ec_err.c,v 1.11 2019/09/06 17:59:25 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -96,6 +96,7 @@ static ERR_STRING_DATA EC_str_reasons[] =
96 {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, 96 {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
97 {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, 97 {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
98 {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, 98 {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
99 {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
99 {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, 100 {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
100 {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, 101 {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
101 {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, 102 {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
@@ -104,6 +105,7 @@ static ERR_STRING_DATA EC_str_reasons[] =
104 {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, 105 {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
105 {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, 106 {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
106 {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, 107 {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
108 {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
107 {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, 109 {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
108 {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, 110 {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
109 {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, 111 {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
@@ -114,9 +116,11 @@ static ERR_STRING_DATA EC_str_reasons[] =
114 {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, 116 {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
115 {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, 117 {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
116 {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, 118 {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
119 {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
117 {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"}, 120 {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), "pkparameters2group failure"},
118 {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, 121 {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
119 {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, 122 {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
123 {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
120 {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, 124 {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
121 {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, 125 {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
122 {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, 126 {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
index 08172fe0c6..08050df292 100644
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ b/src/lib/libcrypto/ec/ec_pmeth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_pmeth.c,v 1.10 2017/01/29 17:49:23 beck Exp $ */ 1/* $OpenBSD: ec_pmeth.c,v 1.11 2019/09/06 17:59:25 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006. 3 * project 2006.
4 */ 4 */
@@ -66,6 +66,8 @@
66#include <openssl/evp.h> 66#include <openssl/evp.h>
67#include <openssl/x509.h> 67#include <openssl/x509.h>
68 68
69#include "ec_lcl.h"
70#include "ech_locl.h"
69#include "evp_locl.h" 71#include "evp_locl.h"
70 72
71/* EC pkey context structure */ 73/* EC pkey context structure */
@@ -75,17 +77,33 @@ typedef struct {
75 EC_GROUP *gen_group; 77 EC_GROUP *gen_group;
76 /* message digest */ 78 /* message digest */
77 const EVP_MD *md; 79 const EVP_MD *md;
80 /* Duplicate key if custom cofactor needed */
81 EC_KEY *co_key;
82 /* Cofactor mode */
83 signed char cofactor_mode;
84 /* KDF (if any) to use for ECDH */
85 char kdf_type;
86 /* Message digest to use for key derivation */
87 const EVP_MD *kdf_md;
88 /* User key material */
89 unsigned char *kdf_ukm;
90 size_t kdf_ukmlen;
91 /* KDF output length */
92 size_t kdf_outlen;
78} EC_PKEY_CTX; 93} EC_PKEY_CTX;
79 94
80static int 95static int
81pkey_ec_init(EVP_PKEY_CTX * ctx) 96pkey_ec_init(EVP_PKEY_CTX * ctx)
82{ 97{
83 EC_PKEY_CTX *dctx; 98 EC_PKEY_CTX *dctx;
84 dctx = malloc(sizeof(EC_PKEY_CTX)); 99
85 if (!dctx) 100 if ((dctx = calloc(1, sizeof(EC_PKEY_CTX))) == NULL) {
101 ECerror(ERR_R_MALLOC_FAILURE);
86 return 0; 102 return 0;
87 dctx->gen_group = NULL; 103 }
88 dctx->md = NULL; 104
105 dctx->cofactor_mode = -1;
106 dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
89 107
90 ctx->data = dctx; 108 ctx->data = dctx;
91 109
@@ -106,6 +124,24 @@ pkey_ec_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src)
106 return 0; 124 return 0;
107 } 125 }
108 dctx->md = sctx->md; 126 dctx->md = sctx->md;
127
128 if (sctx->co_key) {
129 dctx->co_key = EC_KEY_dup(sctx->co_key);
130 if (!dctx->co_key)
131 return 0;
132 }
133 dctx->kdf_type = sctx->kdf_type;
134 dctx->kdf_md = sctx->kdf_md;
135 dctx->kdf_outlen = sctx->kdf_outlen;
136 if (sctx->kdf_ukm) {
137 if ((dctx->kdf_ukm = calloc(1, sctx->kdf_ukmlen)) == NULL)
138 return 0;
139 memcpy(dctx->kdf_ukm, sctx->kdf_ukm, sctx->kdf_ukmlen);
140 } else
141 dctx->kdf_ukm = NULL;
142
143 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
144
109 return 1; 145 return 1;
110} 146}
111 147
@@ -113,9 +149,13 @@ static void
113pkey_ec_cleanup(EVP_PKEY_CTX * ctx) 149pkey_ec_cleanup(EVP_PKEY_CTX * ctx)
114{ 150{
115 EC_PKEY_CTX *dctx = ctx->data; 151 EC_PKEY_CTX *dctx = ctx->data;
116 if (dctx) { 152
153 if (dctx != NULL) {
117 EC_GROUP_free(dctx->gen_group); 154 EC_GROUP_free(dctx->gen_group);
155 EC_KEY_free(dctx->co_key);
156 free(dctx->kdf_ukm);
118 free(dctx); 157 free(dctx);
158 ctx->data = NULL;
119 } 159 }
120} 160}
121 161
@@ -140,9 +180,7 @@ pkey_ec_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, size_t * siglen,
140 else 180 else
141 type = NID_sha1; 181 type = NID_sha1;
142 182
143
144 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); 183 ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
145
146 if (ret <= 0) 184 if (ret <= 0)
147 return ret; 185 return ret;
148 *siglen = (size_t) sltmp; 186 *siglen = (size_t) sltmp;
@@ -174,13 +212,18 @@ pkey_ec_derive(EVP_PKEY_CTX * ctx, unsigned char *key, size_t * keylen)
174 int ret; 212 int ret;
175 size_t outlen; 213 size_t outlen;
176 const EC_POINT *pubkey = NULL; 214 const EC_POINT *pubkey = NULL;
215 EC_KEY *eckey;
216 EC_PKEY_CTX *dctx = ctx->data;
217
177 if (!ctx->pkey || !ctx->peerkey) { 218 if (!ctx->pkey || !ctx->peerkey) {
178 ECerror(EC_R_KEYS_NOT_SET); 219 ECerror(EC_R_KEYS_NOT_SET);
179 return 0; 220 return 0;
180 } 221 }
222
223 eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
181 if (!key) { 224 if (!key) {
182 const EC_GROUP *group; 225 const EC_GROUP *group;
183 group = EC_KEY_get0_group(ctx->pkey->pkey.ec); 226 group = EC_KEY_get0_group(eckey);
184 *keylen = (EC_GROUP_get_degree(group) + 7) / 8; 227 *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
185 return 1; 228 return 1;
186 } 229 }
@@ -193,18 +236,58 @@ pkey_ec_derive(EVP_PKEY_CTX * ctx, unsigned char *key, size_t * keylen)
193 236
194 outlen = *keylen; 237 outlen = *keylen;
195 238
196 ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0); 239 ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
197 if (ret < 0) 240 if (ret <= 0)
198 return ret; 241 return 0;
242
199 *keylen = ret; 243 *keylen = ret;
244
200 return 1; 245 return 1;
201} 246}
202 247
248static int
249pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
250{
251 EC_PKEY_CTX *dctx = ctx->data;
252 unsigned char *ktmp = NULL;
253 size_t ktmplen;
254 int rv = 0;
255
256 if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
257 return pkey_ec_derive(ctx, key, keylen);
258
259 if (!key) {
260 *keylen = dctx->kdf_outlen;
261 return 1;
262 }
263 if (*keylen != dctx->kdf_outlen)
264 return 0;
265 if (!pkey_ec_derive(ctx, NULL, &ktmplen))
266 return 0;
267 if ((ktmp = calloc(1, ktmplen)) == NULL) {
268 ECerror(ERR_R_MALLOC_FAILURE);
269 return 0;
270 }
271 if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
272 goto err;
273 /* Do KDF stuff */
274 if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, dctx->kdf_ukm,
275 dctx->kdf_ukmlen, dctx->kdf_md))
276 goto err;
277 rv = 1;
278
279 err:
280 freezero(ktmp, ktmplen);
281
282 return rv;
283}
284
203static int 285static int
204pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) 286pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2)
205{ 287{
206 EC_PKEY_CTX *dctx = ctx->data; 288 EC_PKEY_CTX *dctx = ctx->data;
207 EC_GROUP *group; 289 EC_GROUP *group;
290
208 switch (type) { 291 switch (type) {
209 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: 292 case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
210 group = EC_GROUP_new_by_curve_name(p1); 293 group = EC_GROUP_new_by_curve_name(p1);
@@ -216,6 +299,86 @@ pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2)
216 dctx->gen_group = group; 299 dctx->gen_group = group;
217 return 1; 300 return 1;
218 301
302 case EVP_PKEY_CTRL_EC_PARAM_ENC:
303 if (!dctx->gen_group) {
304 ECerror(EC_R_NO_PARAMETERS_SET);
305 return 0;
306 }
307 EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
308 return 1;
309
310 case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
311 if (p1 == -2) {
312 if (dctx->cofactor_mode != -1)
313 return dctx->cofactor_mode;
314 else {
315 EC_KEY *ec_key = ctx->pkey->pkey.ec;
316 return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
317 }
318 } else if (p1 < -1 || p1 > 1)
319 return -2;
320 dctx->cofactor_mode = p1;
321 if (p1 != -1) {
322 EC_KEY *ec_key = ctx->pkey->pkey.ec;
323 if (!ec_key->group)
324 return -2;
325 /* If cofactor is 1 cofactor mode does nothing */
326 if (BN_is_one(&ec_key->group->cofactor))
327 return 1;
328 if (!dctx->co_key) {
329 dctx->co_key = EC_KEY_dup(ec_key);
330 if (!dctx->co_key)
331 return 0;
332 }
333 if (p1)
334 EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
335 else
336 EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
337 } else {
338 EC_KEY_free(dctx->co_key);
339 dctx->co_key = NULL;
340 }
341 return 1;
342
343 case EVP_PKEY_CTRL_EC_KDF_TYPE:
344 if (p1 == -2)
345 return dctx->kdf_type;
346 if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_63)
347 return -2;
348 dctx->kdf_type = p1;
349 return 1;
350
351 case EVP_PKEY_CTRL_EC_KDF_MD:
352 dctx->kdf_md = p2;
353 return 1;
354
355 case EVP_PKEY_CTRL_GET_EC_KDF_MD:
356 *(const EVP_MD **)p2 = dctx->kdf_md;
357 return 1;
358
359 case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
360 if (p1 <= 0)
361 return -2;
362 dctx->kdf_outlen = (size_t)p1;
363 return 1;
364
365 case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
366 *(int *)p2 = dctx->kdf_outlen;
367 return 1;
368
369 case EVP_PKEY_CTRL_EC_KDF_UKM:
370 free(dctx->kdf_ukm);
371 dctx->kdf_ukm = p2;
372 if (p2)
373 dctx->kdf_ukmlen = p1;
374 else
375 dctx->kdf_ukmlen = 0;
376 return 1;
377
378 case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
379 *(unsigned char **)p2 = dctx->kdf_ukm;
380 return dctx->kdf_ukmlen;
381
219 case EVP_PKEY_CTRL_MD: 382 case EVP_PKEY_CTRL_MD:
220 if (EVP_MD_type((const EVP_MD *) p2) != NID_sha1 && 383 if (EVP_MD_type((const EVP_MD *) p2) != NID_sha1 &&
221 EVP_MD_type((const EVP_MD *) p2) != NID_ecdsa_with_SHA1 && 384 EVP_MD_type((const EVP_MD *) p2) != NID_ecdsa_with_SHA1 &&
@@ -243,8 +406,7 @@ pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2)
243} 406}
244 407
245static int 408static int
246pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx, 409pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx, const char *type, const char *value)
247 const char *type, const char *value)
248{ 410{
249 if (!strcmp(type, "ec_paramgen_curve")) { 411 if (!strcmp(type, "ec_paramgen_curve")) {
250 int nid; 412 int nid;
@@ -258,6 +420,26 @@ pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx,
258 return 0; 420 return 0;
259 } 421 }
260 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); 422 return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
423 } else if (strcmp(type, "ec_param_enc") == 0) {
424 int param_enc;
425 if (strcmp(value, "explicit") == 0)
426 param_enc = 0;
427 else if (strcmp(value, "named_curve") == 0)
428 param_enc = OPENSSL_EC_NAMED_CURVE;
429 else
430 return -2;
431 return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
432 } else if (strcmp(type, "ecdh_kdf_md") == 0) {
433 const EVP_MD *md;
434 if ((md = EVP_get_digestbyname(value)) == NULL) {
435 ECerror(EC_R_INVALID_DIGEST);
436 return 0;
437 }
438 return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
439 } else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
440 int co_mode;
441 co_mode = atoi(value);
442 return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
261 } 443 }
262 return -2; 444 return -2;
263} 445}
@@ -287,18 +469,29 @@ static int
287pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) 469pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey)
288{ 470{
289 EC_KEY *ec = NULL; 471 EC_KEY *ec = NULL;
290 if (ctx->pkey == NULL) { 472 EC_PKEY_CTX *dctx = ctx->data;
473
474 if (ctx->pkey == NULL && dctx->gen_group == NULL) {
291 ECerror(EC_R_NO_PARAMETERS_SET); 475 ECerror(EC_R_NO_PARAMETERS_SET);
292 return 0; 476 return 0;
293 } 477 }
294 ec = EC_KEY_new(); 478 ec = EC_KEY_new();
295 if (!ec) 479 if (ec == NULL)
296 return 0; 480 return 0;
297 EVP_PKEY_assign_EC_KEY(pkey, ec); 481 if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) {
298 /* Note: if error return, pkey is freed by parent routine */ 482 EC_KEY_free(ec);
299 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
300 return 0; 483 return 0;
301 return EC_KEY_generate_key(pkey->pkey.ec); 484 }
485 /* Note: if error is returned, we count on caller to free pkey->pkey.ec */
486 if (ctx->pkey != NULL) {
487 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
488 return 0;
489 } else {
490 if (!EC_KEY_set_group(ec, dctx->gen_group))
491 return 0;
492 }
493
494 return EC_KEY_generate_key(ec);
302} 495}
303 496
304const EVP_PKEY_METHOD ec_pkey_meth = { 497const EVP_PKEY_METHOD ec_pkey_meth = {
@@ -316,7 +509,7 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
316 509
317 .verify = pkey_ec_verify, 510 .verify = pkey_ec_verify,
318 511
319 .derive = pkey_ec_derive, 512 .derive = pkey_ec_kdf_derive,
320 513
321 .ctrl = pkey_ec_ctrl, 514 .ctrl = pkey_ec_ctrl,
322 .ctrl_str = pkey_ec_ctrl_str 515 .ctrl_str = pkey_ec_ctrl_str