clean up new code for NIST primes
authorBodo Möller <bodo@openssl.org>
Mon, 28 Oct 2002 14:02:19 +0000 (14:02 +0000)
committerBodo Möller <bodo@openssl.org>
Mon, 28 Oct 2002 14:02:19 +0000 (14:02 +0000)
create new lock CRYPTO_LOCK_BN to avoid race condition

CHANGES
crypto/bn/bn.h
crypto/bn/bn_lcl.h
crypto/bn/bn_nist.c
crypto/cryptlib.c
crypto/crypto.h
crypto/ec/ec.h
crypto/ec/ec_cvt.c
crypto/ec/ec_err.c
crypto/ec/ec_lcl.h
crypto/ec/ecp_nist.c

diff --git a/CHANGES b/CHANGES
index c22b945..31ee94b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,9 @@
      if applicable.
      [Nils Larsch <nla@trustcenter.de>]
 
+  *) Add new lock type (CRYPTO_LOCK_BN).
+     [Bodo Moeller]
+
   *) Change the ENGINE framework to automatically load engines
      dynamically from specific directories unless they could be
      found to already be built in or loaded.  Move all the
index 21a1a90..2f203fe 100644 (file)
@@ -547,14 +547,6 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, int words);
                } \
        }
 
-#define bn_clear_top2max(a) \
-       { \
-       int      index = (a)->dmax - (a)->top; \
-       BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
-       for (; index != 0; index--) \
-               *(++ftl) = 0x0; \
-       }
-
 BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
 void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
index 8a4dba3..090a7a0 100644 (file)
@@ -239,6 +239,16 @@ struct bignum_ctx
 #define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
 #define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
 
+
+#define bn_clear_top2max(a) \
+       { \
+       int      index = (a)->dmax - (a)->top; \
+       BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
+       for (; index != 0; index--) \
+               *(++ftl) = 0x0; \
+       }
+
+
 /* This is used for internal error checking and is not normally used */
 #ifdef BN_DEBUG
 # include <assert.h>
index 4e21a05..19bd540 100644 (file)
  */
 
 #include "bn_lcl.h"
+#include "cryptlib.h"
 
 #define BN_NIST_192_TOP        (192+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_224_TOP        (224+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_256_TOP        (256+BN_BITS2-1)/BN_BITS2
-#define        BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_384_TOP        (384+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_521_TOP        (521+BN_BITS2-1)/BN_BITS2
 
 #if BN_BITS2 == 64
@@ -314,7 +315,7 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        if (top == 0)
                return BN_zero(r);
        else if (top > 0)
-               return (r == a)? 1 : !!BN_copy(r ,a);
+               return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
        if (r != a)
                if (!BN_ncopy(r, a, BN_NIST_192_TOP))
@@ -353,7 +354,7 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
                }
        r->top = BN_NIST_192_TOP;
 
-#if 0
+#if 1
        bn_clear_top2max(r);
 #endif
        bn_fix_top(r);
@@ -393,7 +394,7 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        if (tmp_int == 0)
                return BN_zero(r);
        else if (tmp_int > 0)
-               return (r == a)? 1 : !!BN_copy(r ,a);
+               return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
        if (r != a)
                if (!BN_ncopy(r, a, BN_NIST_224_TOP))
@@ -445,7 +446,7 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
                        }
 
        r->top = BN_NIST_224_TOP;
-#if 0
+#if 1
        bn_clear_top2max(r);
 #endif
        bn_fix_top(r);
@@ -503,13 +504,20 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        BN_32_BIT_BUF(14) BN_32_BIT_BUF(15)
 
        if (!_is_set_256_data)
-               _init_256_data();
-
+               {
+               CRYPTO_w_lock(CRYPTO_LOCK_BN);
+               
+               if (!_is_set_256_data)
+                       _init_256_data();
+               
+               CRYPTO_w_unlock(CRYPTO_LOCK_BN);
+               }
+       
        tmp_int = BN_ucmp(field, a);
        if (tmp_int == 0)
                return BN_zero(r);
        else if (tmp_int > 0)
-               return (r == a)? 1 : !!BN_copy(r ,a);
+               return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
        if (r != a)
                if (!BN_ncopy(r, a, BN_NIST_256_TOP))
@@ -596,7 +604,7 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
                }
 
        r->top = BN_NIST_256_TOP;
-#if 0
+#if 1
        bn_clear_top2max(r);
 #endif
        bn_fix_top(r);
@@ -657,13 +665,20 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        BN_32_BIT_BUF(22) BN_32_BIT_BUF(23)
 
        if (!_is_set_384_data)
-               _init_384_data();
+               {
+               CRYPTO_w_lock(CRYPTO_LOCK_BN);
+               
+               if (!_is_set_384_data)
+                       _init_384_data();
+
+               CRYPTO_w_unlock(CRYPTO_LOCK_BN);
+               }
 
        tmp_int = BN_ucmp(field, a);
        if (tmp_int == 0)
                return BN_zero(r);
        else if (tmp_int > 0)
-               return (r == a)? 1 : !!BN_copy(r ,a);
+               return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
        if (r != a)
                if (!BN_ncopy(r, a, BN_NIST_384_TOP))
@@ -757,7 +772,7 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
                }
 
        r->top = BN_NIST_384_TOP;
-#if 0
+#if 1
        bn_clear_top2max(r);
 #endif
        bn_fix_top(r);
@@ -793,7 +808,7 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
        top = a->top;
        if (top < BN_NIST_521_TOP  || ( top == BN_NIST_521_TOP &&
            (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
-               return (r == a)? 1 : !!BN_copy(r ,a);
+               return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
        BN_CTX_start(ctx);
        tmp = BN_CTX_get(ctx);
index 5d8debd..e16bbc6 100644 (file)
@@ -1,4 +1,57 @@
 /* crypto/cryptlib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -112,7 +165,8 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
        "ecdsa",
        "ec",
        "ecdh",
-#if CRYPTO_NUM_LOCKS != 35
+       "bn",
+#if CRYPTO_NUM_LOCKS != 36
 # error "Inconsistency between crypto.h and cryptlib.c"
 #endif
        };
index 1490db9..f87262f 100644 (file)
@@ -1,4 +1,57 @@
 /* crypto/crypto.h */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -135,7 +188,8 @@ extern "C" {
 #define CRYPTO_LOCK_ECDSA               32
 #define CRYPTO_LOCK_EC                 33
 #define CRYPTO_LOCK_ECDH               34
-#define CRYPTO_NUM_LOCKS               35
+#define CRYPTO_LOCK_BN                 35
+#define CRYPTO_NUM_LOCKS               36
 
 #define CRYPTO_LOCK            1
 #define CRYPTO_UNLOCK          2
index 5abef25..1cd6d34 100644 (file)
@@ -486,6 +486,8 @@ void ERR_load_EC_strings(void);
 #define EC_R_INVALID_PRIVATE_KEY                        123
 #define EC_R_MISSING_PARAMETERS                                 124
 #define EC_R_MISSING_PRIVATE_KEY                        125
+#define EC_R_NOT_A_NIST_PRIME                           135
+#define EC_R_NOT_A_SUPPORTED_NIST_PRIME                         136
 #define EC_R_NOT_IMPLEMENTED                            126
 #define EC_R_NOT_INITIALIZED                            111
 #define EC_R_NO_FIELD_MOD                               133
@@ -494,7 +496,6 @@ void ERR_load_EC_strings(void);
 #define EC_R_PKPARAMETERS2GROUP_FAILURE                         127
 #define EC_R_POINT_AT_INFINITY                          106
 #define EC_R_POINT_IS_NOT_ON_CURVE                      107
-#define EC_R_PRIME_IS_NOT_A_NIST_PRIME                  135
 #define EC_R_SLOT_FULL                                  108
 #define EC_R_UNDEFINED_GENERATOR                        113
 #define EC_R_UNDEFINED_ORDER                            128
index 2078256..7571a3c 100644 (file)
@@ -99,9 +99,25 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
 
        if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
                {
-               /* remove the last error code form the error queue */
-               ERR_get_error();
-               /* try the normal mont method */
+               unsigned long err;
+                 
+               err = ERR_peek_last_error();
+
+               if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
+                       ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
+                        (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
+                       {
+                       /* real error */
+                       
+                       EC_GROUP_clear_free(ret);
+                       return NULL;
+                       }
+                       
+               
+               /* not an actual error, we just cannot use EC_GFp_nist_method */
+
+               ERR_clear_error();
+
                EC_GROUP_clear_free(ret);
                meth = EC_GFp_mont_method();
 
@@ -119,6 +135,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
        return ret;
        }
 
+
 EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
        {
        const EC_METHOD *meth;
index 71b1dcf..58ae9d6 100644 (file)
@@ -195,6 +195,8 @@ static ERR_STRING_DATA EC_str_reasons[]=
 {EC_R_INVALID_PRIVATE_KEY                ,"invalid private key"},
 {EC_R_MISSING_PARAMETERS                 ,"missing parameters"},
 {EC_R_MISSING_PRIVATE_KEY                ,"missing private key"},
+{EC_R_NOT_A_NIST_PRIME                   ,"not a NIST prime"},
+{EC_R_NOT_A_SUPPORTED_NIST_PRIME         ,"not a supported NIST prime"},
 {EC_R_NOT_IMPLEMENTED                    ,"not implemented"},
 {EC_R_NOT_INITIALIZED                    ,"not initialized"},
 {EC_R_NO_FIELD_MOD                       ,"no field mod"},
@@ -203,7 +205,6 @@ static ERR_STRING_DATA EC_str_reasons[]=
 {EC_R_PKPARAMETERS2GROUP_FAILURE         ,"pkparameters2group failure"},
 {EC_R_POINT_AT_INFINITY                  ,"point at infinity"},
 {EC_R_POINT_IS_NOT_ON_CURVE              ,"point is not on curve"},
-{EC_R_PRIME_IS_NOT_A_NIST_PRIME          ,"prime is not a nist prime"},
 {EC_R_SLOT_FULL                          ,"slot full"},
 {EC_R_UNDEFINED_GENERATOR                ,"undefined generator"},
 {EC_R_UNDEFINED_ORDER                    ,"undefined order"},
index 247c985..639d174 100644 (file)
@@ -227,6 +227,7 @@ struct ec_group_st {
 
        void *field_data1; /* method-specific (e.g., Montgomery structure) */
        void *field_data2; /* method-specific */
+       int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
 } /* EC_GROUP */;
 
 
index 3c2b4fa..fb43510 100644 (file)
@@ -109,9 +109,6 @@ const EC_METHOD *EC_GFp_nist_method(void)
        return &ret;
        }
 
-#define        ECP_MOD_CAST    \
-       (int (*)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *))
-
 #if BN_BITS2 == 64 && UINT_MAX != 4294967295UL && ULONG_MAX != 4294967295UL
 #define        NO_32_BIT_TYPE
 #endif
@@ -155,31 +152,34 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
 
        if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
-               group->field_data1 = (void *)BN_nist_mod_192;
+               group->field_mod_func = BN_nist_mod_192;
        else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
-#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
-               group->field_data1 = (void *)BN_nist_mod_224;
+#if !defined(NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
+               group->field_mod_func = BN_nist_mod_224;
 #else
+               ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
                goto err;
 #endif
        else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
-#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
-               group->field_data1 = (void *)BN_nist_mod_256;
+#if !defined(NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
+               group->field_mod_func = BN_nist_mod_256;
 #else
+               ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
                goto err;
 #endif
        else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
-#if !defined(ECP_NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
-               group->field_data1 = (void *)BN_nist_mod_384;
+#if !defined(NO_32_BIT_TYPE) || defined(OPENSSL_NO_ASM)
+               group->field_mod_func = BN_nist_mod_384;
 #else
+               ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
                goto err;
 #endif
        else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
-               group->field_data1 = (void *)BN_nist_mod_521;
+               /* this one works in the NO_32_BIT_TYPE case */
+               group->field_mod_func = BN_nist_mod_521;
        else
                {
-               ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP, 
-                       EC_R_PRIME_IS_NOT_A_NIST_PRIME);
+               ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP, EC_R_NOT_A_NIST_PRIME);
                goto err;
                }
 
@@ -188,10 +188,10 @@ int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
        group->field.neg = 0;
 
        /* group->a */
-       (ECP_MOD_CAST group->field_data1)(&group->a, a, p, ctx);
+       if (!group->field_mod_func(&group->a, a, p, ctx)) goto err;
 
        /* group->b */
-       (ECP_MOD_CAST group->field_data1)(&group->b, b, p, ctx);
+       if (!group->field_mod_func(&group->b, b, p, ctx)) goto err;
 
        /* group->a_is_minus3 */
        if (!BN_add_word(tmp_bn, 3)) goto err;
@@ -242,7 +242,7 @@ int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
 
        if (!BN_mul(r, a, b, ctx)) goto err;
-       if (!(ECP_MOD_CAST group->field_data1)(r, r, &group->field, ctx))
+       if (!group->field_mod_func(r, r, &group->field, ctx))
                goto err;
 
        ret=1;
@@ -267,7 +267,7 @@ int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
 
        if (!BN_sqr(r, a, ctx)) goto err;
-       if (!(ECP_MOD_CAST group->field_data1)(r, r, &group->field, ctx))
+       if (!group->field_mod_func(r, r, &group->field, ctx))
                goto err;
 
        ret=1;