1 | /* |
2 | * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | |
10 | /*- |
11 | * AES-NI support for AES modes ecb, cbc, ofb, cfb, ctr. |
12 | * This file is included by cipher_aes_hw.c |
13 | */ |
14 | |
15 | #define cipher_hw_aesni_ofb128 cipher_hw_generic_ofb128 |
16 | #define cipher_hw_aesni_cfb128 cipher_hw_generic_cfb128 |
17 | #define cipher_hw_aesni_cfb8 cipher_hw_generic_cfb8 |
18 | #define cipher_hw_aesni_cfb1 cipher_hw_generic_cfb1 |
19 | #define cipher_hw_aesni_ctr cipher_hw_generic_ctr |
20 | |
21 | static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, |
22 | const unsigned char *key, size_t keylen) |
23 | { |
24 | int ret; |
25 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; |
26 | AES_KEY *ks = &adat->ks.ks; |
27 | |
28 | dat->ks = ks; |
29 | |
30 | if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE) |
31 | && !dat->enc) { |
32 | ret = aesni_set_decrypt_key(key, keylen * 8, ks); |
33 | dat->block = (block128_f) aesni_decrypt; |
34 | dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ? |
35 | (cbc128_f) aesni_cbc_encrypt : NULL; |
36 | } else { |
37 | ret = aesni_set_encrypt_key(key, keylen * 8, ks); |
38 | dat->block = (block128_f) aesni_encrypt; |
39 | if (dat->mode == EVP_CIPH_CBC_MODE) |
40 | dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt; |
41 | else if (dat->mode == EVP_CIPH_CTR_MODE) |
42 | dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; |
43 | else |
44 | dat->stream.cbc = NULL; |
45 | } |
46 | |
47 | if (ret < 0) { |
48 | ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED); |
49 | return 0; |
50 | } |
51 | |
52 | return 1; |
53 | } |
54 | |
55 | static int cipher_hw_aesni_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, |
56 | const unsigned char *in, size_t len) |
57 | { |
58 | const AES_KEY *ks = ctx->ks; |
59 | |
60 | aesni_cbc_encrypt(in, out, len, ks, ctx->iv, ctx->enc); |
61 | |
62 | return 1; |
63 | } |
64 | |
65 | static int cipher_hw_aesni_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, |
66 | const unsigned char *in, size_t len) |
67 | { |
68 | if (len < ctx->blocksize) |
69 | return 1; |
70 | |
71 | aesni_ecb_encrypt(in, out, len, ctx->ks, ctx->enc); |
72 | |
73 | return 1; |
74 | } |
75 | |
76 | #define PROV_CIPHER_HW_declare(mode) \ |
77 | static const PROV_CIPHER_HW aesni_##mode = { \ |
78 | cipher_hw_aesni_initkey, \ |
79 | cipher_hw_aesni_##mode, \ |
80 | cipher_hw_aes_copyctx \ |
81 | }; |
82 | #define PROV_CIPHER_HW_select(mode) \ |
83 | if (AESNI_CAPABLE) \ |
84 | return &aesni_##mode; |
85 | |