summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c240
1 files changed, 144 insertions, 96 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
index 02609606ff..289bc3b271 100644
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ b/src/lib/libcrypto/ec/ec_asn1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ec_asn1.c,v 1.73 2024/10/15 06:35:59 tb Exp $ */ 1/* $OpenBSD: ec_asn1.c,v 1.74 2024/10/17 14:34:06 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project. 3 * Written by Nils Larsch for the OpenSSL project.
4 */ 4 */
@@ -818,99 +818,98 @@ ec_asn1_group2pkparameters(const EC_GROUP *group)
818 return NULL; 818 return NULL;
819} 819}
820 820
821static EC_GROUP * 821static int
822ec_asn1_parameters2group(const ECPARAMETERS *params) 822ec_asn1_is_prime_field(const X9_62_FIELDID *fieldid)
823{ 823{
824 int ok = 0, tmp; 824 int nid;
825 EC_GROUP *ret = NULL; 825
826 BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL; 826 if (fieldid == NULL) {
827 EC_POINT *point = NULL;
828 int field_bits;
829
830 if (!params->fieldID || !params->fieldID->fieldType ||
831 !params->fieldID->p.ptr) {
832 ECerror(EC_R_ASN1_ERROR); 827 ECerror(EC_R_ASN1_ERROR);
833 goto err; 828 return 0;
834 } 829 }
835 /* now extract the curve parameters a and b */ 830 if ((nid = OBJ_obj2nid(fieldid->fieldType)) == NID_undef) {
836 if (!params->curve || !params->curve->a || 831 ECerror(EC_R_INVALID_FIELD);
837 !params->curve->a->data || !params->curve->b || 832 return 0;
838 !params->curve->b->data) {
839 ECerror(EC_R_ASN1_ERROR);
840 goto err;
841 } 833 }
842 a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); 834 if (nid == NID_X9_62_characteristic_two_field) {
843 if (a == NULL) { 835 ECerror(EC_R_GF2M_NOT_SUPPORTED);
844 ECerror(ERR_R_BN_LIB); 836 return 0;
845 goto err;
846 } 837 }
847 b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); 838 if (nid != NID_X9_62_prime_field) {
848 if (b == NULL) { 839 ECerror(EC_R_UNSUPPORTED_FIELD);
849 ECerror(ERR_R_BN_LIB); 840 return 0;
850 goto err;
851 } 841 }
852 /* get the field parameters */ 842
853 tmp = OBJ_obj2nid(params->fieldID->fieldType); 843 /* We can't check that this is actually a prime due to DoS risk. */
854 if (tmp == NID_X9_62_characteristic_two_field) { 844 if (fieldid->p.prime == NULL) {
855 ECerror(EC_R_GF2M_NOT_SUPPORTED);
856 goto err;
857 } else if (tmp == NID_X9_62_prime_field) {
858 /* we have a curve over a prime field */
859 /* extract the prime number */
860 if (!params->fieldID->p.prime) {
861 ECerror(EC_R_ASN1_ERROR);
862 goto err;
863 }
864 p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
865 if (p == NULL) {
866 ECerror(ERR_R_ASN1_LIB);
867 goto err;
868 }
869 if (BN_is_negative(p) || BN_is_zero(p)) {
870 ECerror(EC_R_INVALID_FIELD);
871 goto err;
872 }
873 field_bits = BN_num_bits(p);
874 if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
875 ECerror(EC_R_FIELD_TOO_LARGE);
876 goto err;
877 }
878 /* create the EC_GROUP structure */
879 ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
880 } else {
881 ECerror(EC_R_INVALID_FIELD); 845 ECerror(EC_R_INVALID_FIELD);
882 goto err; 846 return 0;
883 } 847 }
884 848
885 if (ret == NULL) { 849 return 1;
886 ECerror(ERR_R_EC_LIB); 850}
851
852static int
853ec_asn1_parameters_curve2group(const X9_62_CURVE *curve,
854 const ASN1_INTEGER *prime, EC_GROUP **out_group)
855{
856 EC_GROUP *group = NULL;
857 BIGNUM *p = NULL, *a = NULL, *b = NULL;
858 int ret = 0;
859
860 if (*out_group != NULL)
861 goto err;
862
863 if ((p = ASN1_INTEGER_to_BN(prime, NULL)) == NULL)
864 goto err;
865 if ((a = BN_bin2bn(curve->a->data, curve->a->length, NULL)) == NULL)
866 goto err;
867 if ((b = BN_bin2bn(curve->b->data, curve->b->length, NULL)) == NULL)
868 goto err;
869
870 /*
871 * XXX - move these checks to ec_GFp_simple_group_set_curve()?
872 * What about checking 0 <= a, b < p?
873 */
874 if (BN_is_zero(p) || BN_is_negative(p)) {
875 ECerror(EC_R_INVALID_FIELD);
887 goto err; 876 goto err;
888 } 877 }
889 /* extract seed (optional) */ 878 if (BN_num_bits(p) > OPENSSL_ECC_MAX_FIELD_BITS) {
890 if (params->curve->seed != NULL) { 879 ECerror(EC_R_FIELD_TOO_LARGE);
891 free(ret->seed);
892 if (!(ret->seed = malloc(params->curve->seed->length))) {
893 ECerror(ERR_R_MALLOC_FAILURE);
894 goto err;
895 }
896 memcpy(ret->seed, params->curve->seed->data,
897 params->curve->seed->length);
898 ret->seed_len = params->curve->seed->length;
899 }
900 if (!params->order || !params->base || !params->base->data) {
901 ECerror(EC_R_ASN1_ERROR);
902 goto err; 880 goto err;
903 } 881 }
904 if ((point = EC_POINT_new(ret)) == NULL) 882
883 if ((group = EC_GROUP_new_curve_GFp(p, a, b, NULL)) == NULL)
905 goto err; 884 goto err;
906 885
907 /* set the point conversion form */ 886 *out_group = group;
908 EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) 887 group = NULL;
909 (params->base->data[0] & ~0x01)); 888
889 ret = 1;
890
891 err:
892 BN_free(p);
893 BN_free(a);
894 BN_free(b);
895 EC_GROUP_free(group);
896
897 return ret;
898}
910 899
911 /* extract the ec point */ 900static int
912 if (!EC_POINT_oct2point(ret, point, params->base->data, 901ec_asn1_set_group_parameters(const ECPARAMETERS *params, EC_GROUP *group)
913 params->base->length, NULL)) { 902{
903 EC_POINT *generator;
904 BIGNUM *order = NULL, *cofactor = NULL;
905 const ASN1_BIT_STRING *seed;
906 point_conversion_form_t form;
907 int ret = 0;
908
909 if ((generator = EC_POINT_new(group)) == NULL)
910 goto err;
911 if (!EC_POINT_oct2point(group, generator,
912 params->base->data, params->base->length, NULL)) {
914 ECerror(ERR_R_EC_LIB); 913 ECerror(ERR_R_EC_LIB);
915 goto err; 914 goto err;
916 } 915 }
@@ -918,14 +917,6 @@ ec_asn1_parameters2group(const ECPARAMETERS *params)
918 ECerror(ERR_R_ASN1_LIB); 917 ECerror(ERR_R_ASN1_LIB);
919 goto err; 918 goto err;
920 } 919 }
921 if (BN_is_negative(order) || BN_is_zero(order)) {
922 ECerror(EC_R_INVALID_GROUP_ORDER);
923 goto err;
924 }
925 if (BN_num_bits(order) > field_bits + 1) { /* Hasse bound */
926 ECerror(EC_R_INVALID_GROUP_ORDER);
927 goto err;
928 }
929 if (params->cofactor != NULL) { 920 if (params->cofactor != NULL) {
930 if ((cofactor = ASN1_INTEGER_to_BN(params->cofactor, 921 if ((cofactor = ASN1_INTEGER_to_BN(params->cofactor,
931 NULL)) == NULL) { 922 NULL)) == NULL) {
@@ -933,27 +924,84 @@ ec_asn1_parameters2group(const ECPARAMETERS *params)
933 goto err; 924 goto err;
934 } 925 }
935 } 926 }
936 if (!EC_GROUP_set_generator(ret, point, order, cofactor)) { 927
928 /* Checks the Hasse bound and sets the cofactor if possible or fails. */
929 if (!EC_GROUP_set_generator(group, generator, order, cofactor)) {
937 ECerror(ERR_R_EC_LIB); 930 ECerror(ERR_R_EC_LIB);
938 goto err; 931 goto err;
939 } 932 }
940 ok = 1;
941 933
942 err: 934 if ((seed = params->curve->seed) != NULL) {
943 if (!ok) { 935 if (EC_GROUP_set_seed(group, seed->data, seed->length) == 0) {
944 EC_GROUP_free(ret); 936 ECerror(ERR_R_MALLOC_FAILURE);
945 ret = NULL; 937 goto err;
938 }
946 } 939 }
947 BN_free(p); 940
948 BN_free(a); 941 /* oct2point has ensured that to be compressed, uncompressed, or hybrid. */
949 BN_free(b); 942 form = params->base->data[0] & ~1U;
943 EC_GROUP_set_point_conversion_form(group, form);
944
945 ret = 1;
946
947 err:
948 EC_POINT_free(generator);
950 BN_free(order); 949 BN_free(order);
951 BN_free(cofactor); 950 BN_free(cofactor);
952 EC_POINT_free(point);
953 951
954 return ret; 952 return ret;
955} 953}
956 954
955static int
956ec_asn1_parameters_extract_prime_group(const ECPARAMETERS *params,
957 EC_GROUP **out_group)
958{
959 EC_GROUP *group = NULL;
960 int ret = 0;
961
962 if (*out_group != NULL)
963 goto err;
964
965 if (!ec_asn1_is_prime_field(params->fieldID))
966 goto err;
967 if (!ec_asn1_parameters_curve2group(params->curve,
968 params->fieldID->p.prime, &group))
969 goto err;
970 if (!ec_asn1_set_group_parameters(params, group))
971 goto err;
972
973 *out_group = group;
974 group = NULL;
975
976 ret = 1;
977
978 err:
979 EC_GROUP_free(group);
980
981 return ret;
982}
983
984static EC_GROUP *
985ec_asn1_parameters2group(const ECPARAMETERS *params)
986{
987 EC_GROUP *group = NULL;
988
989 if (params == NULL) {
990 ECerror(EC_R_ASN1_ERROR);
991 goto err;
992 }
993
994 if (!ec_asn1_parameters_extract_prime_group(params, &group))
995 goto err;
996
997 return group;
998
999 err:
1000 EC_GROUP_free(group);
1001
1002 return NULL;
1003}
1004
957EC_GROUP * 1005EC_GROUP *
958ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) 1006ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
959{ 1007{