1 #include <lib9.h> 2 #include <kernel.h> 3 #include <isa.h> 4 #include "interp.h" 5 #include "../libinterp/runt.h" 6 #include "mp.h" 7 #include "libsec.h" 8 #include "keys.h" 9 10 static char* pkattr[] = { "p", "alpha", "key", nil }; 11 static char* skattr[] = { "p", "alpha", "key", "!secret", nil }; 12 static char* sigattr[] = { "r", "s", nil }; 13 14 static void* 15 eg_str2sk(char *str, char **strp) 16 { 17 EGpriv *eg; 18 char *p; 19 20 eg = egprivalloc(); 21 eg->pub.p = base64tobig(str, &p); 22 eg->pub.alpha = base64tobig(p, &p); 23 eg->pub.key = base64tobig(p, &p); 24 eg->secret = base64tobig(p, &p); 25 if(strp) 26 *strp = p; 27 if(eg->pub.p == nil || eg->pub.alpha == nil || eg->pub.key == nil || eg->secret == nil){ 28 egprivfree(eg); 29 return nil; 30 } 31 return eg; 32 } 33 34 static void* 35 eg_str2pk(char *str, char **strp) 36 { 37 EGpub *eg; 38 char *p; 39 40 eg = egpuballoc(); 41 eg->p = base64tobig(str, &p); 42 eg->alpha = base64tobig(p, &p); 43 eg->key = base64tobig(p, &p); 44 if(strp) 45 *strp = p; 46 if(eg->p == nil || eg->alpha == nil || eg->key == nil){ 47 egpubfree(eg); 48 return nil; 49 } 50 return eg; 51 } 52 53 static void* 54 eg_str2sig(char *str, char **strp) 55 { 56 EGsig *eg; 57 char *p; 58 59 eg = egsigalloc(); 60 eg->r = base64tobig(str, &p); 61 eg->s = base64tobig(p, &p); 62 if(strp) 63 *strp = p; 64 if(eg->r == nil || eg->s == nil){ 65 egsigfree(eg); 66 return nil; 67 } 68 return eg; 69 } 70 71 static int 72 eg_sk2str(void *veg, char *buf, int len) 73 { 74 EGpriv *eg; 75 char *cp, *ep; 76 77 eg = (EGpriv*)veg; 78 ep = buf + len - 1; 79 cp = buf; 80 81 cp += snprint(cp, ep - cp, "%U\n", eg->pub.p); 82 cp += snprint(cp, ep - cp, "%U\n", eg->pub.alpha); 83 cp += snprint(cp, ep - cp, "%U\n", eg->pub.key); 84 cp += snprint(cp, ep - cp, "%U\n", eg->secret); 85 *cp = 0; 86 87 return cp - buf; 88 } 89 90 static int 91 eg_pk2str(void *veg, char *buf, int len) 92 { 93 EGpub *eg; 94 char *cp, *ep; 95 96 eg = (EGpub*)veg; 97 ep = buf + len - 1; 98 cp = buf; 99 100 cp += snprint(cp, ep - cp, "%U\n", eg->p); 101 cp += snprint(cp, ep - cp, "%U\n", eg->alpha); 102 cp += snprint(cp, ep - cp, "%U\n", eg->key); 103 *cp = 0; 104 105 return cp - buf; 106 } 107 108 static int 109 eg_sig2str(void *veg, char *buf, int len) 110 { 111 EGsig *eg; 112 char *cp, *ep; 113 114 eg = veg; 115 ep = buf + len - 1; 116 cp = buf; 117 118 cp += snprint(cp, ep - cp, "%U\n", eg->r); 119 cp += snprint(cp, ep - cp, "%U\n", eg->s); 120 *cp = 0; 121 122 return cp - buf; 123 } 124 125 static void* 126 eg_sk2pk(void *vs) 127 { 128 return egprivtopub((EGpriv*)vs); 129 } 130 131 /* generate an el gamal secret key with new params */ 132 static void* 133 eg_gen(int len) 134 { 135 return eggen(len, 0); 136 } 137 138 /* generate an el gamal secret key with same params as a public key */ 139 static void* 140 eg_genfrompk(void *vpub) 141 { 142 EGpub *pub; 143 EGpriv *priv; 144 int nlen; 145 146 pub = vpub; 147 priv = egprivalloc(); 148 priv->pub.p = mpcopy(pub->p); 149 priv->pub.alpha = mpcopy(pub->alpha); 150 nlen = mpsignif(pub->p); 151 pub = &priv->pub; 152 pub->key = mpnew(0); 153 priv->secret = mpnew(0); 154 mprand(nlen-1, genrandom, priv->secret); 155 mpexp(pub->alpha, priv->secret, pub->p, pub->key); 156 return priv; 157 } 158 159 static void* 160 eg_sign(mpint* mp, void *key) 161 { 162 return egsign((EGpriv*)key, mp); 163 } 164 165 static int 166 eg_verify(mpint* mp, void *sig, void *key) 167 { 168 return egverify((EGpub*)key, (EGsig*)sig, mp) == 0; 169 } 170 171 static void 172 eg_freepub(void *a) 173 { 174 egpubfree((EGpub*)a); 175 } 176 177 static void 178 eg_freepriv(void *a) 179 { 180 egprivfree((EGpriv*)a); 181 } 182 183 static void 184 eg_freesig(void *a) 185 { 186 egsigfree((EGsig*)a); 187 } 188 189 SigAlgVec* 190 elgamalinit(void) 191 { 192 SigAlgVec *vec; 193 194 vec = malloc(sizeof(SigAlgVec)); 195 if(vec == nil) 196 return nil; 197 198 vec->name = "elgamal"; 199 200 vec->pkattr = pkattr; 201 vec->skattr = skattr; 202 vec->sigattr = sigattr; 203 204 vec->str2sk = eg_str2sk; 205 vec->str2pk = eg_str2pk; 206 vec->str2sig = eg_str2sig; 207 208 vec->sk2str = eg_sk2str; 209 vec->pk2str = eg_pk2str; 210 vec->sig2str = eg_sig2str; 211 212 vec->sk2pk = eg_sk2pk; 213 214 vec->gensk = eg_gen; 215 vec->genskfrompk = eg_genfrompk; 216 vec->sign = eg_sign; 217 vec->verify = eg_verify; 218 219 vec->skfree = eg_freepriv; 220 vec->pkfree = eg_freepub; 221 vec->sigfree = eg_freesig; 222 223 return vec; 224 } 225