123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- /*
- * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
- #include <stdlib.h>
- #include <string.h>
- #include "aes.h"
- #include "modes.h"
- #include "sha2.h"
- #include "picotls.h"
- #include "picotls/minicrypto.h"
- struct aesecb_context_t {
- ptls_cipher_context_t super;
- cf_aes_context aes;
- };
- static inline void aesecb_dispose(ptls_cipher_context_t *_ctx)
- {
- struct aesecb_context_t *ctx = (struct aesecb_context_t *)_ctx;
- ptls_clear_memory(ctx, sizeof(*ctx));
- }
- static inline void aesecb_encrypt(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
- {
- struct aesecb_context_t *ctx = (struct aesecb_context_t *)_ctx;
- assert(len % AES_BLOCKSZ == 0);
- cf_aes_encrypt(&ctx->aes, input, output);
- }
- static inline void aesecb_decrypt(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
- {
- struct aesecb_context_t *ctx = (struct aesecb_context_t *)_ctx;
- assert(len % AES_BLOCKSZ == 0);
- cf_aes_decrypt(&ctx->aes, input, output);
- }
- static inline int aesecb_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key)
- {
- struct aesecb_context_t *ctx = (struct aesecb_context_t *)_ctx;
- ctx->super.do_dispose = aesecb_dispose;
- ctx->super.do_init = NULL;
- ctx->super.do_transform = is_enc ? aesecb_encrypt : aesecb_decrypt;
- cf_aes_init(&ctx->aes, key, ctx->super.algo->key_size);
- return 0;
- }
- struct aesctr_context_t {
- ptls_cipher_context_t super;
- cf_aes_context aes;
- cf_ctr ctr;
- };
- static inline void aesctr_dispose(ptls_cipher_context_t *_ctx)
- {
- struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx;
- ptls_clear_memory(ctx, sizeof(*ctx));
- }
- static inline void aesctr_init(ptls_cipher_context_t *_ctx, const void *iv)
- {
- struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx;
- cf_ctr_init(&ctx->ctr, &cf_aes, &ctx->aes, iv);
- }
- static inline void aesctr_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
- {
- struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx;
- cf_ctr_cipher(&ctx->ctr, input, output, len);
- }
- static inline int aesctr_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key)
- {
- struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx;
- ctx->super.do_dispose = aesctr_dispose;
- ctx->super.do_init = aesctr_init;
- ctx->super.do_transform = aesctr_transform;
- cf_aes_init(&ctx->aes, key, ctx->super.algo->key_size);
- return 0;
- }
- struct aesgcm_context_t {
- ptls_aead_context_t super;
- cf_aes_context aes;
- cf_gcm_ctx gcm;
- uint8_t static_iv[PTLS_AESGCM_IV_SIZE];
- };
- static inline void aesgcm_dispose_crypto(ptls_aead_context_t *_ctx)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- /* clear all memory except super */
- ptls_clear_memory((uint8_t *)ctx + sizeof(ctx->super), sizeof(*ctx) - sizeof(ctx->super));
- }
- static inline void aesgcm_encrypt_init(ptls_aead_context_t *_ctx, uint64_t seq, const void *aad, size_t aadlen)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- uint8_t iv[PTLS_AES_BLOCK_SIZE];
- ptls_aead__build_iv(ctx->super.algo, iv, ctx->static_iv, seq);
- cf_gcm_encrypt_init(&cf_aes, &ctx->aes, &ctx->gcm, aad, aadlen, iv, PTLS_AESGCM_IV_SIZE);
- }
- static inline size_t aesgcm_encrypt_update(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- cf_gcm_encrypt_update(&ctx->gcm, input, inlen, output);
- return inlen;
- }
- static inline size_t aesgcm_encrypt_final(ptls_aead_context_t *_ctx, void *output)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- cf_gcm_encrypt_final(&ctx->gcm, output, PTLS_AESGCM_TAG_SIZE);
- return PTLS_AESGCM_TAG_SIZE;
- }
- static inline size_t aesgcm_decrypt(ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen, uint64_t seq,
- const void *aad, size_t aadlen)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- uint8_t iv[PTLS_AES_BLOCK_SIZE];
- if (inlen < PTLS_AESGCM_TAG_SIZE)
- return SIZE_MAX;
- size_t tag_offset = inlen - PTLS_AESGCM_TAG_SIZE;
- ptls_aead__build_iv(ctx->super.algo, iv, ctx->static_iv, seq);
- if (cf_gcm_decrypt(&cf_aes, &ctx->aes, input, tag_offset, aad, aadlen, iv, PTLS_AESGCM_IV_SIZE, (uint8_t *)input + tag_offset,
- PTLS_AESGCM_TAG_SIZE, output) != 0)
- return SIZE_MAX;
- return tag_offset;
- }
- static inline void aesgcm_get_iv(ptls_aead_context_t *_ctx, void *iv)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- memcpy(iv, ctx->static_iv, sizeof(ctx->static_iv));
- }
- static inline void aesgcm_set_iv(ptls_aead_context_t *_ctx, const void *iv)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- memcpy(ctx->static_iv, iv, sizeof(ctx->static_iv));
- }
- static inline int aead_aesgcm_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, const void *iv)
- {
- struct aesgcm_context_t *ctx = (struct aesgcm_context_t *)_ctx;
- ctx->super.dispose_crypto = aesgcm_dispose_crypto;
- ctx->super.do_get_iv = aesgcm_get_iv;
- ctx->super.do_set_iv = aesgcm_set_iv;
- if (is_enc) {
- ctx->super.do_encrypt_init = aesgcm_encrypt_init;
- ctx->super.do_encrypt_update = aesgcm_encrypt_update;
- ctx->super.do_encrypt_final = aesgcm_encrypt_final;
- ctx->super.do_encrypt = ptls_aead__do_encrypt;
- ctx->super.do_encrypt_v = ptls_aead__do_encrypt_v;
- ctx->super.do_decrypt = NULL;
- } else {
- ctx->super.do_encrypt_init = NULL;
- ctx->super.do_encrypt_update = NULL;
- ctx->super.do_encrypt_final = NULL;
- ctx->super.do_encrypt = NULL;
- ctx->super.do_encrypt_v = NULL;
- ctx->super.do_decrypt = aesgcm_decrypt;
- }
- cf_aes_init(&ctx->aes, key, ctx->super.algo->key_size);
- memcpy(ctx->static_iv, iv, sizeof(ctx->static_iv));
- return 0;
- }
|