Set custom IV length in AES GCM 35/190635/2
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 4 Oct 2018 08:53:52 +0000 (10:53 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 5 Oct 2018 13:20:31 +0000 (15:20 +0200)
Current implementation assumed the default IV length (12B) silently ignoring
longer IVs. As a result the encryption output did not match the expected one.

This commit modifies the implementation to always set the actual IV length in
the encryption context.

Change-Id: I82f9bc916f108563a4a940d340945279c661bbaa

ssflib/src/ssf_crypto_openssl.cpp

index 7968e5c..0778cf0 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -87,10 +87,13 @@ int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct
                return -1;
        }
 
+       int iv_len_option = -1;
+
        // right now use AES GCM only (could be further extended to CCM)
        switch (op->info.algorithm)
        {
                case TEE_ALG_AES_GCM: {
+                       iv_len_option = EVP_CTRL_GCM_SET_IVLEN;
                        switch (op->info.keySize) {
                                case 128: EVP_alg = EVP_aes_128_gcm; break;
                                case 192: EVP_alg = EVP_aes_192_gcm; break;
@@ -109,7 +112,22 @@ int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct
                }
        }
 
-       ret = EVP_CipherInit(ctx, EVP_alg(), key->secret.buffer, (unsigned char*)iv,
+       ret = EVP_CipherInit(ctx, EVP_alg(), NULL, NULL,
+                                               (op->info.mode == TEE_MODE_ENCRYPT) ? 1 : 0);
+       if (ret != EVP_SUCCESS) {
+               LOGE(MODULE_SSF_LIB, "Failed to initialize cipher");
+               return ret;
+       }
+
+       if (iv_len_option >= 0) {
+               ret = EVP_CIPHER_CTX_ctrl(ctx, iv_len_option, iv_len, NULL);
+               if (ret != EVP_SUCCESS) {
+                       LOGE(MODULE_SSF_LIB, "EVP_CIPHER_CTX_ctrl() failed");
+                       return ret;
+               }
+       }
+
+       ret = EVP_CipherInit(ctx, NULL, key->secret.buffer, (unsigned char*)iv,
                                                (op->info.mode == TEE_MODE_ENCRYPT) ? 1 : 0);
        if (ret != EVP_SUCCESS) {
                LOGE(MODULE_SSF_LIB, "Failed to initialize cipher");