diff options
author | jsing <> | 2019-09-06 17:59:25 +0000 |
---|---|---|
committer | jsing <> | 2019-09-06 17:59:25 +0000 |
commit | 11474dfb0e4a1fb55d042fbfb4e2c68602f61508 (patch) | |
tree | 41fcc6b250b4f518c93bc01711ee02ee90e03002 /src | |
parent | ad62fd73e219aceeb5b13e772228acd3f93d6b23 (diff) | |
download | openbsd-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/Makefile | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec.h | 100 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_err.c | 6 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_pmeth.c | 235 |
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 | ||
3 | LIB= crypto | 3 | LIB= crypto |
4 | LIBREBUILD=y | 4 | LIBREBUILD=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 |
35 | CFLAGS+= -I${LCRYPTO_SRC}/ecdsa | 35 | CFLAGS+= -I${LCRYPTO_SRC}/ecdsa |
36 | CFLAGS+= -I${LCRYPTO_SRC}/ec | 36 | CFLAGS+= -I${LCRYPTO_SRC}/ec |
37 | CFLAGS+= -I${LCRYPTO_SRC}/ecdh | ||
37 | 38 | ||
38 | VERSION_SCRIPT= Symbols.map | 39 | VERSION_SCRIPT= Symbols.map |
39 | SYMBOL_LIST= ${.CURDIR}/Symbols.list | 40 | SYMBOL_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 | ||
80 | static int | 95 | static int |
81 | pkey_ec_init(EVP_PKEY_CTX * ctx) | 96 | pkey_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 | |||
113 | pkey_ec_cleanup(EVP_PKEY_CTX * ctx) | 149 | pkey_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 | ||
248 | static int | ||
249 | pkey_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 | |||
203 | static int | 285 | static int |
204 | pkey_ec_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) | 286 | pkey_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 | ||
245 | static int | 408 | static int |
246 | pkey_ec_ctrl_str(EVP_PKEY_CTX * ctx, | 409 | pkey_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 | |||
287 | pkey_ec_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) | 469 | pkey_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 | ||
304 | const EVP_PKEY_METHOD ec_pkey_meth = { | 497 | const 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 |