diff options
Diffstat (limited to 'web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c')
-rw-r--r-- | web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c new file mode 100644 index 00000000..6d7b944f --- /dev/null +++ b/web/server/h2o/libh2o/deps/picotls/deps/cifra/shitlisp/sl-cifra.c @@ -0,0 +1,206 @@ +#include "handy.h" +#include "dstr.h" +#include "shitlisp.h" +#include "aes.h" +#include "sha2.h" +#include "hmac.h" +#include "pbkdf2.h" + +#include <assert.h> + +static sl_value * aes_block_fn(sl_value *self, sl_value *args, sl_symboltab *tab, + void (*blockfn)(const cf_aes_context *ctx, + const uint8_t *in, + uint8_t *out)) +{ + sl_iter it = sl_iter_start(args); + sl_value *key = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *block = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + sl_value *ret = NULL; + + if (!key || !block || + (key->u.bytes.len != 16 && key->u.bytes.len != 24 && key->u.bytes.len != 32) || + block->u.bytes.len != AES_BLOCKSZ) + { + ret = sl_get_nil(); + goto x_err; + } + + cf_aes_context ctx; + cf_aes_init(&ctx, key->u.bytes.buf, key->u.bytes.len); + uint8_t blockout[AES_BLOCKSZ]; + blockfn(&ctx, block->u.bytes.buf, blockout); + ret = sl_new_bytes(blockout, AES_BLOCKSZ); + cf_aes_finish(&ctx); + +x_err: + sl_decref(key); + sl_decref(block); + return ret; +} + +static sl_value * aes_block_encrypt(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return aes_block_fn(self, args, tab, cf_aes_encrypt); +} + +static sl_value * aes_block_decrypt(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return aes_block_fn(self, args, tab, cf_aes_decrypt); +} + +/* Hashing */ +static sl_value * hash_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *msg = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + if (!msg) + return sl_get_nil(); + + cf_chash_ctx ctx; + assert(h->ctxsz <= CF_CHASH_MAXCTX); + h->init(&ctx); + h->update(&ctx, msg->u.bytes.buf, msg->u.bytes.len); + sl_decref(msg); + + uint8_t result[CF_MAXHASH]; + assert(h->hashsz <= CF_MAXHASH); + h->digest(&ctx, result); + + return sl_new_bytes(result, h->hashsz); +} + +static sl_value * sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha224); +} + +static sl_value * sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha256); +} + +static sl_value * sha384(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha384); +} + +static sl_value * sha512(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return hash_fn(self, args, tab, &cf_sha512); +} + +/* HMAC */ +static sl_value * hmac_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *key = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *msg = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + + if (!key || !msg) + { + sl_decref(key); + sl_decref(msg); + return sl_get_nil(); + } + + uint8_t result[CF_MAXHASH]; + cf_hmac(key->u.bytes.buf, key->u.bytes.len, + msg->u.bytes.buf, msg->u.bytes.len, + result, + h); + + sl_decref(key); + sl_decref(msg); + return sl_new_bytes(result, h->hashsz); +} + +static sl_value * hmac_sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha224); } + +static sl_value * hmac_sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha256); } + +static sl_value * hmac_sha384(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha384); } + +static sl_value * hmac_sha512(sl_value *self, sl_value *args, sl_symboltab *tab) +{ return hmac_fn(self, args, tab, &cf_sha512); } + + +/* PBKDF2 */ +static sl_value * do_pbkdf2(const cf_chash *h, sl_value *pw, sl_value *salt, + uint32_t iterations, uint32_t outlen) +{ + dstr out; + dstr_init(&out); + if (dstr_expand(&out, outlen)) + return NULL; + + cf_pbkdf2_hmac(pw->u.bytes.buf, pw->u.bytes.len, + salt->u.bytes.buf, salt->u.bytes.len, + iterations, + (uint8_t *) out.start, outlen, + h); + + sl_value *ret = sl_new_bytes((uint8_t *) out.start, outlen); + dstr_free(&out); + return ret; +} + +static sl_value * pbkdf2_fn(sl_value *self, sl_value *args, sl_symboltab *tab, const cf_chash *h) +{ + sl_iter it = sl_iter_start(args); + sl_value *pw = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *salt = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_bytes, tab); + sl_value *iterations = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_integer, tab); + sl_value *outlen = sl_iter_convert(&it, sl_preprocess_eval, sl_assert_integer, tab); + + sl_value *ret; + + if (!pw || !salt || !iterations || !outlen) + ret = sl_get_nil(); + else + { + assert(bignum_len_words(&iterations->u.integer.bn) == 1); + assert(bignum_len_words(&outlen->u.integer.bn) == 1); + ret = do_pbkdf2(h, pw, salt, + iterations->u.integer.bn.v[0], + outlen->u.integer.bn.v[0]); + } + + sl_decref(pw); + sl_decref(salt); + sl_decref(iterations); + sl_decref(outlen); + return ret; +} + +static sl_value * pbkdf2_sha224(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return pbkdf2_fn(self, args, tab, &cf_sha224); +} + +static sl_value * pbkdf2_sha256(sl_value *self, sl_value *args, sl_symboltab *tab) +{ + return pbkdf2_fn(self, args, tab, &cf_sha256); +} + +int SL_MODULE_ENTRY(sl_symboltab *tab) +{ + ER(sl_symboltab_add_name_native(tab, "aes-encrypt", aes_block_encrypt)); + ER(sl_symboltab_add_name_native(tab, "aes-decrypt", aes_block_decrypt)); + ER(sl_symboltab_add_name_native(tab, "sha224", sha224)); + ER(sl_symboltab_add_name_native(tab, "sha256", sha256)); + ER(sl_symboltab_add_name_native(tab, "sha384", sha384)); + ER(sl_symboltab_add_name_native(tab, "sha512", sha512)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha224", hmac_sha224)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha256", hmac_sha256)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha384", hmac_sha384)); + ER(sl_symboltab_add_name_native(tab, "hmac-sha512", hmac_sha512)); + ER(sl_symboltab_add_name_native(tab, "pbkdf2-sha224", pbkdf2_sha224)); + ER(sl_symboltab_add_name_native(tab, "pbkdf2-sha256", pbkdf2_sha256)); + return 0; +} |