/* * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include "prov/ciphercommon.h" /*- * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr. * Used if there is no special hardware implementations. */ int ossl_cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { if (dat->stream.cbc) (*dat->stream.cbc) (in, out, len, dat->ks, dat->iv, dat->enc); else if (dat->enc) CRYPTO_cbc128_encrypt(in, out, len, dat->ks, dat->iv, dat->block); else CRYPTO_cbc128_decrypt(in, out, len, dat->ks, dat->iv, dat->block); return 1; } int ossl_cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { size_t i, bl = dat->blocksize; if (len < bl) return 1; if (dat->stream.ecb) { (*dat->stream.ecb) (in, out, len, dat->ks, dat->enc); } else { for (i = 0, len -= bl; i <= len; i += bl) (*dat->block) (in + i, out + i, dat->ks); } return 1; } int ossl_cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; CRYPTO_ofb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->block); dat->num = num; return 1; } int ossl_cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; CRYPTO_cfb128_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc, dat->block); dat->num = num; return 1; } int ossl_cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; CRYPTO_cfb128_8_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc, dat->block); dat->num = num; return 1; } int ossl_cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; if (dat->use_bits) { CRYPTO_cfb128_1_encrypt(in, out, len, dat->ks, dat->iv, &num, dat->enc, dat->block); dat->num = num; return 1; } while (len >= MAXBITCHUNK) { CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, dat->ks, dat->iv, &num, dat->enc, dat->block); len -= MAXBITCHUNK; out += MAXBITCHUNK; in += MAXBITCHUNK; } if (len) CRYPTO_cfb128_1_encrypt(in, out, len * 8, dat->ks, dat->iv, &num, dat->enc, dat->block); dat->num = num; return 1; } int ossl_cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { unsigned int num = dat->num; if (dat->stream.ctr) CRYPTO_ctr128_encrypt_ctr32(in, out, len, dat->ks, dat->iv, dat->buf, &num, dat->stream.ctr); else CRYPTO_ctr128_encrypt(in, out, len, dat->ks, dat->iv, dat->buf, &num, dat->block); dat->num = num; return 1; } /*- * The chunked cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr. * Used if there is no special hardware implementations. */ int ossl_cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= MAXCHUNK) { ossl_cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK); inl -= MAXCHUNK; in += MAXCHUNK; out += MAXCHUNK; } if (inl > 0) ossl_cipher_hw_generic_cbc(ctx, out, in, inl); return 1; } int ossl_cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t chunk = MAXCHUNK; if (inl < chunk) chunk = inl; while (inl > 0 && inl >= chunk) { ossl_cipher_hw_generic_cfb8(ctx, out, in, inl); inl -= chunk; in += chunk; out += chunk; if (inl < chunk) chunk = inl; } return 1; } int ossl_cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t chunk = MAXCHUNK; if (inl < chunk) chunk = inl; while (inl > 0 && inl >= chunk) { ossl_cipher_hw_generic_cfb128(ctx, out, in, inl); inl -= chunk; in += chunk; out += chunk; if (inl < chunk) chunk = inl; } return 1; } int ossl_cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= MAXCHUNK) { ossl_cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK); inl -= MAXCHUNK; in += MAXCHUNK; out += MAXCHUNK; } if (inl > 0) ossl_cipher_hw_generic_ofb128(ctx, out, in, inl); return 1; }