aes_operation.cpp revision 31e063f8ed913369eb30648537fb5827dfd7a0d3
1/*
2 * Copyright 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19#include <openssl/aes.h>
20#include <openssl/err.h>
21#include <openssl/rand.h>
22
23#include <keymaster/logger.h>
24
25#include "aes_key.h"
26#include "aes_operation.h"
27#include "openssl_err.h"
28
29namespace keymaster {
30
31/**
32 * Abstract base for AES operation factories.  This class does all of the work to create
33 * AES operations.
34 */
35class AesOperationFactory : public OperationFactory {
36  public:
37    virtual KeyType registry_key() const { return KeyType(KM_ALGORITHM_AES, purpose()); }
38
39    virtual Operation* CreateOperation(const Key& key, const AuthorizationSet& begin_params,
40                                       keymaster_error_t* error);
41    virtual const keymaster_block_mode_t* SupportedBlockModes(size_t* block_mode_count) const;
42    virtual const keymaster_padding_t* SupportedPaddingModes(size_t* padding_count) const;
43
44    virtual keymaster_purpose_t purpose() const = 0;
45
46  private:
47    virtual Operation* CreateEvpOperation(const SymmetricKey& key,
48                                          keymaster_block_mode_t block_mode,
49                                          keymaster_padding_t padding, bool caller_iv,
50                                          keymaster_error_t* error);
51};
52
53Operation* AesOperationFactory::CreateOperation(const Key& key,
54                                                const AuthorizationSet& begin_params,
55                                                keymaster_error_t* error) {
56    *error = KM_ERROR_OK;
57    const SymmetricKey* symmetric_key = static_cast<const SymmetricKey*>(&key);
58
59    switch (symmetric_key->key_data_size()) {
60    case 16:
61    case 24:
62    case 32:
63        break;
64    default:
65        *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
66        return nullptr;
67    }
68
69    keymaster_block_mode_t block_mode;
70    if (!begin_params.GetTagValue(TAG_BLOCK_MODE, &block_mode)) {
71        LOG_E("%d block modes specified in begin params", begin_params.GetTagCount(TAG_BLOCK_MODE));
72        *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
73        return nullptr;
74    } else if (!supported(block_mode)) {
75        LOG_E("Block mode %d not supported", block_mode);
76        *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
77        return nullptr;
78    } else if (!key.authorizations().Contains(TAG_BLOCK_MODE, block_mode)) {
79        LOG_E("Block mode %d was specified, but not authorized by key", block_mode);
80        *error = KM_ERROR_INCOMPATIBLE_BLOCK_MODE;
81        return nullptr;
82    }
83
84    keymaster_padding_t padding = KM_PAD_NONE;
85    begin_params.GetTagValue(TAG_PADDING, &padding);
86    if (!key.authorizations().GetTagValue(TAG_PADDING, &padding)) {
87        LOG_E("Padding mode %d was specified, but not authorized by key", padding);
88        *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
89    }
90
91    bool caller_nonce = key.authorizations().GetTagValue(TAG_CALLER_NONCE);
92
93    if (*error != KM_ERROR_OK)
94        return nullptr;
95
96    switch (block_mode) {
97    case KM_MODE_ECB:
98    case KM_MODE_CBC:
99        return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
100    case KM_MODE_CTR:
101        if (padding != KM_PAD_NONE) {
102            *error = KM_ERROR_INCOMPATIBLE_PADDING_MODE;
103            return nullptr;
104        }
105        return CreateEvpOperation(*symmetric_key, block_mode, padding, caller_nonce, error);
106    default:
107        *error = KM_ERROR_UNSUPPORTED_BLOCK_MODE;
108        return nullptr;
109    }
110}
111
112Operation* AesOperationFactory::CreateEvpOperation(const SymmetricKey& key,
113                                                   keymaster_block_mode_t block_mode,
114                                                   keymaster_padding_t padding, bool caller_iv,
115                                                   keymaster_error_t* error) {
116    Operation* op = NULL;
117    switch (purpose()) {
118    case KM_PURPOSE_ENCRYPT:
119        op = new AesEvpEncryptOperation(block_mode, padding, caller_iv, key.key_data(),
120                                        key.key_data_size());
121        break;
122    case KM_PURPOSE_DECRYPT:
123        op = new AesEvpDecryptOperation(block_mode, padding, key.key_data(), key.key_data_size());
124        break;
125    default:
126        *error = KM_ERROR_UNSUPPORTED_PURPOSE;
127        return NULL;
128    }
129
130    if (!op)
131        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
132    return op;
133}
134
135static const keymaster_block_mode_t supported_block_modes[] = {KM_MODE_ECB, KM_MODE_CBC,
136                                                               KM_MODE_CTR};
137
138const keymaster_block_mode_t*
139AesOperationFactory::SupportedBlockModes(size_t* block_mode_count) const {
140    *block_mode_count = array_length(supported_block_modes);
141    return supported_block_modes;
142}
143
144static const keymaster_padding_t supported_padding_modes[] = {KM_PAD_NONE, KM_PAD_PKCS7};
145const keymaster_padding_t*
146AesOperationFactory::SupportedPaddingModes(size_t* padding_mode_count) const {
147    *padding_mode_count = array_length(supported_padding_modes);
148    return supported_padding_modes;
149}
150
151/**
152 * Concrete factory for AES encryption operations.
153 */
154class AesEncryptionOperationFactory : public AesOperationFactory {
155    keymaster_purpose_t purpose() const { return KM_PURPOSE_ENCRYPT; }
156};
157static OperationFactoryRegistry::Registration<AesEncryptionOperationFactory> encrypt_registration;
158
159/**
160 * Concrete factory for AES decryption operations.
161 */
162class AesDecryptionOperationFactory : public AesOperationFactory {
163    keymaster_purpose_t purpose() const { return KM_PURPOSE_DECRYPT; }
164};
165static OperationFactoryRegistry::Registration<AesDecryptionOperationFactory> decrypt_registration;
166
167AesEvpOperation::AesEvpOperation(keymaster_purpose_t purpose, keymaster_block_mode_t block_mode,
168                                 keymaster_padding_t padding, bool caller_iv, const uint8_t* key,
169                                 size_t key_size)
170    : Operation(purpose), key_size_(key_size), block_mode_(block_mode), padding_(padding),
171      caller_iv_(caller_iv) {
172    memcpy(key_, key, key_size_);
173    EVP_CIPHER_CTX_init(&ctx_);
174}
175
176AesEvpOperation::~AesEvpOperation() {
177    EVP_CIPHER_CTX_cleanup(&ctx_);
178}
179
180keymaster_error_t AesEvpOperation::InitializeCipher() {
181    const EVP_CIPHER* cipher;
182    switch (block_mode_) {
183    case KM_MODE_ECB:
184        switch (key_size_) {
185        case 16:
186            cipher = EVP_aes_128_ecb();
187            break;
188        case 24:
189            cipher = EVP_aes_192_ecb();
190            break;
191        case 32:
192            cipher = EVP_aes_256_ecb();
193            break;
194        default:
195            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
196        }
197        break;
198    case KM_MODE_CBC:
199        switch (key_size_) {
200        case 16:
201            cipher = EVP_aes_128_cbc();
202            break;
203        case 24:
204            cipher = EVP_aes_192_cbc();
205            break;
206        case 32:
207            cipher = EVP_aes_256_cbc();
208            break;
209        default:
210            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
211        }
212        break;
213    case KM_MODE_CTR:
214        switch (key_size_) {
215        case 16:
216            cipher = EVP_aes_128_ctr();
217            break;
218        case 24:
219            cipher = EVP_aes_192_ctr();
220            break;
221        case 32:
222            cipher = EVP_aes_256_ctr();
223            break;
224        default:
225            return KM_ERROR_UNSUPPORTED_KEY_SIZE;
226        }
227        break;
228    default:
229        return KM_ERROR_UNSUPPORTED_BLOCK_MODE;
230    }
231
232    int init_result =
233        EVP_CipherInit_ex(&ctx_, cipher, NULL /* engine */, key_, iv_.get(), evp_encrypt_mode());
234
235    if (!init_result)
236        return TranslateLastOpenSslError();
237
238    switch (padding_) {
239    case KM_PAD_NONE:
240        EVP_CIPHER_CTX_set_padding(&ctx_, 0 /* disable padding */);
241        break;
242    case KM_PAD_PKCS7:
243        // This is the default for OpenSSL EVP cipher operations.
244        break;
245    default:
246        return KM_ERROR_UNSUPPORTED_PADDING_MODE;
247    }
248
249    return KM_ERROR_OK;
250}
251
252bool AesEvpOperation::need_iv() const {
253    switch (block_mode_) {
254    case KM_MODE_CBC:
255    case KM_MODE_CTR:
256        return true;
257    case KM_MODE_ECB:
258        return false;
259    default:
260        // Shouldn't get here.
261        assert(false);
262        return false;
263    }
264}
265
266keymaster_error_t AesEvpOperation::Begin(const AuthorizationSet& input_params,
267                                         AuthorizationSet* output_params) {
268    if (!output_params)
269        return KM_ERROR_OUTPUT_PARAMETER_NULL;
270
271    keymaster_error_t error = KM_ERROR_OK;
272    if (need_iv()) {
273        switch (purpose()) {
274        case KM_PURPOSE_ENCRYPT:
275            if (input_params.find(TAG_NONCE) == -1)
276                error = GenerateIv();
277            else if (caller_iv_)
278                error = GetIv(input_params);
279            else
280                error = KM_ERROR_CALLER_NONCE_PROHIBITED;
281
282            if (error == KM_ERROR_OK)
283                output_params->push_back(TAG_NONCE, iv_.get(), AES_BLOCK_SIZE);
284            break;
285
286        case KM_PURPOSE_DECRYPT:
287            error = GetIv(input_params);
288            break;
289        default:
290            return KM_ERROR_UNSUPPORTED_PURPOSE;
291        }
292    }
293
294    if (error == KM_ERROR_OK)
295        error = InitializeCipher();
296
297    return error;
298}
299
300keymaster_error_t AesEvpOperation::GetIv(const AuthorizationSet& input_params) {
301    keymaster_blob_t iv_blob;
302    if (!input_params.GetTagValue(TAG_NONCE, &iv_blob)) {
303        LOG_E("No IV provided", 0);
304        return KM_ERROR_INVALID_ARGUMENT;
305    }
306    if (iv_blob.data_length != AES_BLOCK_SIZE) {
307        LOG_E("Expected %d-byte IV for AES operation, but got %d bytes", AES_BLOCK_SIZE,
308              iv_blob.data_length);
309        return KM_ERROR_INVALID_NONCE;
310    }
311    iv_.reset(dup_array(iv_blob.data, iv_blob.data_length));
312    if (!iv_.get())
313        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
314    return KM_ERROR_OK;
315}
316
317keymaster_error_t AesEvpOperation::GenerateIv() {
318    iv_.reset(new uint8_t[AES_BLOCK_SIZE]);
319    if (!iv_.get())
320        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
321    if (RAND_bytes(iv_.get(), AES_BLOCK_SIZE) != 1)
322        return TranslateLastOpenSslError();
323    return KM_ERROR_OK;
324}
325
326inline size_t min(size_t a, size_t b) {
327    if (a < b)
328        return a;
329    return b;
330}
331
332keymaster_error_t AesEvpOperation::Update(const AuthorizationSet& /* additional_params */,
333                                          const Buffer& input, Buffer* output,
334                                          size_t* input_consumed) {
335    output->reserve(input.available_read() + AES_BLOCK_SIZE);
336
337    const uint8_t* input_pos = input.peek_read();
338    const uint8_t* input_end = input_pos + input.available_read();
339
340    int output_written = -1;
341    if (!EVP_CipherUpdate(&ctx_, output->peek_write(), &output_written, input_pos,
342                          input_end - input_pos))
343        return TranslateLastOpenSslError();
344
345    assert(output_written >= 0);
346    assert(output_written <= (int)output->available_write());
347    output->advance_write(output_written);
348    *input_consumed = input.available_read();
349    return KM_ERROR_OK;
350}
351
352keymaster_error_t AesEvpOperation::Finish(const AuthorizationSet& /* additional_params */,
353                                          const Buffer& /* signature */, Buffer* output) {
354    output->reserve(AES_BLOCK_SIZE);
355
356    int output_written = -1;
357    if (!EVP_CipherFinal_ex(&ctx_, output->peek_write(), &output_written)) {
358        LOG_E("Error encrypting final block: %s", ERR_error_string(ERR_peek_last_error(), NULL));
359        return TranslateLastOpenSslError();
360    }
361
362    assert(output_written <= AES_BLOCK_SIZE);
363    output->advance_write(output_written);
364    return KM_ERROR_OK;
365}
366
367keymaster_error_t AesEvpOperation::Abort() {
368    return KM_ERROR_OK;
369}
370
371}  // namespace keymaster
372