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.
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/error-crypt.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 Tue Jul 12 2022 20:12:50 by
