Differences From
Artifact [530b761d29]:
1 1 -- vim: ft=terra
2 2 local const = {
3 3 keybits = 2048;
4 - sighash = lib.md.MBEDTLS_MD_SHA256;
4 + sighash = constant(uint32, lib.md.MBEDTLS_MD_SHA256);
5 5 }
6 +const.keybits_c = constant(uint32,const.keybits);
6 7 local err = {
7 8 rawcode = terra(code: int)
8 9 if code < 0 then code = -code end
9 10 return code and 0xFF80
10 11 end;
11 12 toobig = -lib.pk.MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
12 13 }
................................................................................
88 89 terra m.der(pub: bool, key: &ctx, buf: &uint8): binblob
89 90 var ofs: ptrdiff
90 91 if pub then
91 92 ofs = lib.pk.mbedtls_pk_write_pubkey_der(key, buf, const.maxdersz)
92 93 else
93 94 ofs = lib.pk.mbedtls_pk_write_key_der(key, buf, const.maxdersz)
94 95 end
95 - if ofs < 0 then return binblob.null() end
96 +
97 + if ofs == lib.asn1.MBEDTLS_ERR_ASN1_BUF_TOO_SMALL then
98 + lib.warn("BUG: bad buffer size for lib.crypt.der")
99 + return binblob.null()
100 + elseif ofs == lib.pk.MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE then
101 + lib.warn("mbedtls broken! asymmetric-key crypto unsupported")
102 + return binblob.null()
103 + elseif ofs == lib.pk.MBEDTLS_ERR_RSA_BAD_INPUT_DATA then
104 + lib.warn("bad RSA input to lib.crypt.der")
105 + return binblob.null()
106 + elseif ofs < 0 then
107 + var num: int8[21]
108 + var sz = lib.str.bfmt(num, "%lld", ofs)
109 + lib.warn("unknown MBEDTLS error ", {&num[0], sz});
110 + return binblob.null()
111 + end
112 +
96 113 return binblob {
97 114 ptr = buf + (const.maxdersz - ofs);
98 115 ct = ofs;
99 116 }
100 117 end
101 118
102 119 m.destroy = lib.dispatch {
103 120 [ctx] = function(v) return `lib.pk.mbedtls_pk_free(&v) end;
104 121
105 122 [false] = function(ptr) return `ptr:free() end;
106 123 }
124 +
125 +terra m.pk_genrsa(pk: &ctx)
126 +-- fuck you arm for making requiring this inane pipe-through-cat
127 +-- what is wrong with you demented bastards
128 + var noise: uint8[2048]
129 + m.spray(noise,2048)
130 + var rng: lib.drbg.mbedtls_ctr_drbg_context
131 + var entropy: lib.entropy.mbedtls_entropy_context
132 + lib.drbg.mbedtls_ctr_drbg_init(&rng)
133 + lib.entropy.mbedtls_entropy_init(&entropy)
134 + lib.drbg.mbedtls_ctr_drbg_seed(&rng, lib.entropy.mbedtls_entropy_func, &entropy, &noise[0], 2048)
135 + var rsa = lib.pk.pk2rsa(@pk)
136 + lib.rsa.mbedtls_rsa_init(rsa)
137 + var e = lib.rsa.mbedtls_rsa_gen_key(rsa, lib.drbg.mbedtls_ctr_drbg_random, &rng, const.keybits_c, 3)
138 + if e < 0 then
139 + var buf: int8[22]
140 + lib.bail("BUG: could not buf-generate RSA keypair; mbedtls reports error ",
141 + lib.math.decstrs(e, &buf[21]))
142 + end
143 + if lib.rsa.mbedtls_rsa_check_privkey(rsa) < 0 then
144 + lib.bail("BUG: generated bad RSA keypair")
145 + end
146 +end
107 147
108 148 terra m.genkp(): lib.pk.mbedtls_pk_context
109 149 lib.dbg('generating new keypair')
110 150
111 151 var pk: ctx
112 152 lib.pk.mbedtls_pk_init(&pk)
113 - lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA))
114 - var rsa = [&lib.rsa.mbedtls_rsa_context](pk.pk_ctx)
115 - lib.rsa.mbedtls_rsa_gen_key(rsa, callbacks.randomize, nil, const.keybits, 65537)
116 -
153 + if lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA)) < 0 then
154 + lib.bail 'pk context setup failed'
155 + end
156 + m.pk_genrsa(&pk)
117 157 return pk
118 158 end
159 +
119 160
120 161 local binblob = lib.mem.ptr(uint8)
121 162 terra m.loadpriv(buf: binblob): lib.stat(ctx)
122 163 lib.dbg('parsing saved private key')
123 164
124 165 var pk: ctx
125 166 lib.pk.mbedtls_pk_init(&pk)
126 - var rt = lib.pk.mbedtls_pk_parse_key(&pk, buf.ptr, buf.ct, nil, 0)
167 + var rt = lib.pk.mbedtls_pk_parse_key(&pk,
168 + [&uint8](buf.ptr), [intptr](buf.ct),
169 + nil, 0,
170 + callbacks.randomize, nil)
127 171 if rt == 0 then
128 172 return [lib.stat(ctx)] { ok = true, val = pk }
129 173 else
130 174 lib.pk.mbedtls_pk_free(&pk)
131 175 return [lib.stat(ctx)] { ok = false, error = rt }
132 176 end
133 177 end
................................................................................
154 198
155 199 lib.dbg('(1/2) hashing message')
156 200 if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(const.sighash), [&uint8](txt), len, hash) ~= 0 then
157 201 lib.bail('could not hash message')
158 202 end
159 203
160 204 lib.dbg('(2/2) signing hash')
161 - var ret = lib.pk.mbedtls_pk_sign(pk, const.sighash, hash, 0, [&uint8](sig.ptr), &osz, callbacks.randomize, nil)
205 + var ret = lib.pk.mbedtls_pk_sign(pk, const.sighash,
206 + hash, sizeof([hash.type]),
207 + [&uint8](sig.ptr), 2048, &osz,
208 + callbacks.randomize, nil)
162 209 if ret ~= 0 then lib.bail('could not sign message hash')
163 210 else sig:resize(osz) end
164 211
165 212 return sig
166 213 end
214 +
167 215
168 216 terra m.verify(pk: &ctx, txt: rawstring, len: intptr,
169 217 sig: &uint8, siglen: intptr): {bool, uint8}
170 218 lib.dbg('verifying signature')
171 219 var osz: intptr = 0
172 220 var hash: uint8[64]
173 221
................................................................................
201 249 if lib.pk.mbedtls_pk_verify(pk, hk, hash, 0, [&uint8](sig), siglen) == 0 then
202 250 return true, secl
203 251 end
204 252 end
205 253 lib.dbg('all hash algorithms failed')
206 254 return false, 0
207 255 end
208 -
209 256 terra m.hmac(alg: hashalg, key: lib.mem.ptr(uint8), txt: lib.mem.ptr(int8), buf: &uint8)
210 257 lib.md.mbedtls_md_hmac(
211 258 lib.md.mbedtls_md_info_from_type(alg.id),
212 259 key.ptr, key.ct,
213 260 [&uint8](txt.ptr), txt.ct,
214 261 buf) -- sz(buf) >= hash output size
215 262 end
................................................................................
256 303 for i = 0, len do
257 304 a:ppush(words[m.random(intptr,0,[words.type.N])]):lpush '-'
258 305 end
259 306 a:ipush(m.random(uint32,0,99999))
260 307 end
261 308
262 309 return m
310 +