parsav  Diff

Differences From Artifact [530b761d29]:

To Artifact [2e175d9d09]:


     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  +