Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TLS_cyassl TLS_cyassl
dsa.c
00001 /* dsa.c 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_DSA 00029 00030 #include <cyassl/ctaocrypt/dsa.h> 00031 #include <cyassl/ctaocrypt/sha.h> 00032 #include <cyassl/ctaocrypt/random.h> 00033 #include <cyassl/ctaocrypt/ctaoerror2.h> 00034 00035 00036 enum { 00037 DSA_HALF_SIZE = 20, /* r and s size */ 00038 DSA_SIG_SIZE = 40 /* signature size */ 00039 }; 00040 00041 00042 #ifndef min 00043 00044 static INLINE word32 min(word32 a, word32 b) 00045 { 00046 return a > b ? b : a; 00047 } 00048 00049 #endif /* min */ 00050 00051 00052 void InitDsaKey(DsaKey* key) 00053 { 00054 key->type = -1; /* haven't decided yet */ 00055 00056 /* TomsFastMath doesn't use memory allocation */ 00057 #ifndef USE_FAST_MATH 00058 key->p.dp = 0; /* public alloc parts */ 00059 key->q.dp = 0; 00060 key->g.dp = 0; 00061 key->y.dp = 0; 00062 00063 key->x.dp = 0; /* private alloc parts */ 00064 #endif 00065 } 00066 00067 00068 void FreeDsaKey(DsaKey* key) 00069 { 00070 (void)key; 00071 /* TomsFastMath doesn't use memory allocation */ 00072 #ifndef USE_FAST_MATH 00073 if (key->type == DSA_PRIVATE) 00074 mp_clear(&key->x); 00075 mp_clear(&key->y); 00076 mp_clear(&key->g); 00077 mp_clear(&key->q); 00078 mp_clear(&key->p); 00079 #endif 00080 } 00081 00082 00083 int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) 00084 { 00085 mp_int k, kInv, r, s, H; 00086 int ret = 0, sz; 00087 byte buffer[DSA_HALF_SIZE]; 00088 00089 if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) 00090 return MP_INIT_E; 00091 00092 sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q)); 00093 00094 /* generate k */ 00095 RNG_GenerateBlock(rng, buffer, sz); 00096 buffer[0] |= 0x0C; 00097 00098 if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) 00099 ret = MP_READ_E; 00100 00101 if (mp_cmp_d(&k, 1) != MP_GT) 00102 ret = MP_CMP_E; 00103 00104 /* inverse k mod q */ 00105 if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY) 00106 ret = MP_INVMOD_E; 00107 00108 /* generate r, r = (g exp k mod p) mod q */ 00109 if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) 00110 ret = MP_EXPTMOD_E; 00111 00112 if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) 00113 ret = MP_MOD_E; 00114 00115 /* generate H from sha digest */ 00116 if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY) 00117 ret = MP_READ_E; 00118 00119 /* generate s, s = (kInv * (H + x*r)) % q */ 00120 if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY) 00121 ret = MP_MUL_E; 00122 00123 if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY) 00124 ret = MP_ADD_E; 00125 00126 if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY) 00127 ret = MP_MULMOD_E; 00128 00129 /* write out */ 00130 if (ret == 0) { 00131 int rSz = mp_unsigned_bin_size(&r); 00132 int sSz = mp_unsigned_bin_size(&s); 00133 00134 if (rSz == DSA_HALF_SIZE - 1) { 00135 out[0] = 0; 00136 out++; 00137 } 00138 00139 if (mp_to_unsigned_bin(&r, out) != MP_OKAY) 00140 ret = MP_TO_E; 00141 else { 00142 if (sSz == DSA_HALF_SIZE - 1) { 00143 out[rSz] = 0; 00144 out++; 00145 } 00146 ret = mp_to_unsigned_bin(&s, out + rSz); 00147 } 00148 } 00149 00150 mp_clear(&H); 00151 mp_clear(&s); 00152 mp_clear(&r); 00153 mp_clear(&kInv); 00154 mp_clear(&k); 00155 00156 return ret; 00157 } 00158 00159 00160 int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) 00161 { 00162 mp_int w, u1, u2, v, r, s; 00163 int ret = 0; 00164 00165 if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY) 00166 return MP_INIT_E; 00167 00168 /* set r and s from signature */ 00169 if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY || 00170 mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) 00171 ret = MP_READ_E; 00172 00173 /* sanity checks */ 00174 00175 00176 /* put H into u1 from sha digest */ 00177 if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY) 00178 ret = MP_READ_E; 00179 00180 /* w = s invmod q */ 00181 if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY) 00182 ret = MP_INVMOD_E; 00183 00184 /* u1 = (H * w) % q */ 00185 if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY) 00186 ret = MP_MULMOD_E; 00187 00188 /* u2 = (r * w) % q */ 00189 if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY) 00190 ret = MP_MULMOD_E; 00191 00192 /* verify v = ((g^u1 * y^u2) mod p) mod q */ 00193 if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY) 00194 ret = MP_EXPTMOD_E; 00195 00196 if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY) 00197 ret = MP_EXPTMOD_E; 00198 00199 if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY) 00200 ret = MP_MULMOD_E; 00201 00202 if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY) 00203 ret = MP_MULMOD_E; 00204 00205 /* do they match */ 00206 if (ret == 0 && mp_cmp(&r, &v) == MP_EQ) 00207 *answer = 1; 00208 else 00209 *answer = 0; 00210 00211 mp_clear(&s); 00212 mp_clear(&r); 00213 mp_clear(&u1); 00214 mp_clear(&u2); 00215 mp_clear(&w); 00216 mp_clear(&v); 00217 00218 return ret; 00219 } 00220 00221 00222 #endif /* NO_DSA */ 00223
Generated on Thu Jul 14 2022 20:26:02 by
1.7.2