Implement CTR using openssl 77/202177/3
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 25 Mar 2019 09:15:06 +0000 (10:15 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 17 May 2019 12:25:28 +0000 (14:25 +0200)
Crypto core implementation of CTR requires the output buffer to be a
multiplicity of the block size. CTR is a stream cipher and as such it should
produce the output of the length equal to the input.

Switch to openssl implementation.

Change-Id: I15471aaaf887c08020c4e472e8b28df7937bd898

ssflib/inc/ssf_crypto_openssl.h
ssflib/src/ssf_crypto.cpp
ssflib/src/ssf_crypto_openssl.cpp

index e01d66e..d875e21 100644 (file)
 int ossl_crypto_open(crypto_internal_operation *op);
 void ossl_crypto_close(crypto_internal_operation *op);
 
-int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct *key,
-                                               void *iv, size_t iv_len, unsigned int tag_len);
+int ossl_crypto_cipher_init(crypto_internal_operation *op, crypto_internal_keystruct *key,
+                                                       const void *iv, size_t iv_len, unsigned int tag_len = 0);
 
-int ossl_crypto_ae_update_aad(crypto_internal_operation *op, void *aad, size_t aad_len);
-int ossl_crypto_ae_update(crypto_internal_operation *op, void *src, size_t src_len,
+int ossl_crypto_cipher_update_aad(crypto_internal_operation *op, void *aad, size_t aad_len);
+int ossl_crypto_cipher_update(crypto_internal_operation *op, const void *src, size_t src_len,
                                                        void *dst, size_t *dst_len);
 
+int ossl_crypto_cipher_final(crypto_internal_operation *op, void *src, size_t src_len,
+                                                       void *dst, size_t *dst_len);
 int ossl_crypto_ae_enc_final(crypto_internal_operation *op, void *src, size_t src_len,
                                                        void *dst, size_t *dst_len, void *tag, size_t *tag_len);
 int ossl_crypto_ae_dec_final(crypto_internal_operation *op, void *src, size_t src_len,
                                                        void *dst, size_t *dst_len, void *tag, size_t tag_len);
 
-#endif // _SSF_CRYPTO_OPENSSL_H_
\ No newline at end of file
+#endif // _SSF_CRYPTO_OPENSSL_H_
index e1c8914..dc264cf 100644 (file)
@@ -907,7 +907,7 @@ static int sw_crypto_close(crypto_internal_operation *operation)
 
 int crypto_internal_open(crypto_internal_operation *operation)
 {
-       if (operation->info.algorithm == TEE_ALG_AES_GCM) {
+       if (operation->info.algorithm == TEE_ALG_AES_GCM || operation->info.algorithm == TEE_ALG_AES_CTR) {
                return ossl_crypto_open(operation);
        } else {
                return sw_crypto_open(operation);
@@ -916,7 +916,7 @@ int crypto_internal_open(crypto_internal_operation *operation)
 
 int crypto_internal_close(crypto_internal_operation *operation)
 {
-       if (operation->info.algorithm == TEE_ALG_AES_GCM) {
+       if (operation->info.algorithm == TEE_ALG_AES_GCM || operation->info.algorithm == TEE_ALG_AES_CTR) {
                ossl_crypto_close(operation);
                return 0;
        } else {
@@ -2097,8 +2097,14 @@ void TEE_CipherInit(TEE_OperationHandle operation, const void* IV, size_t IVLen)
        if (!key.secret.buffer) {
                CRYPTO_PANIC;
        }
-       if (crypto_internal_init(op, &key, (unsigned char*)IV, IVLen)) {
-               CRYPTO_PANIC;
+       if (op->info.algorithm == TEE_ALG_AES_CTR) {
+               if (ossl_crypto_cipher_init(op, &key, IV, IVLen)) {
+                       CRYPTO_PANIC;
+               }
+       } else {
+               if (crypto_internal_init(op, &key, (unsigned char*)IV, IVLen)) {
+                       CRYPTO_PANIC;
+               }
        }
        op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
        return;
@@ -2118,8 +2124,14 @@ TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void* srcData,
        if (!(op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
                CRYPTO_PANIC;
        }
-       if (crypto_internal_update(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen)) {
-               CRYPTO_PANIC;
+       if (op->info.algorithm == TEE_ALG_AES_CTR) {
+               if (ossl_crypto_cipher_update(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen)) {
+                       CRYPTO_PANIC;
+               }
+       } else {
+               if (crypto_internal_update(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen)) {
+                       CRYPTO_PANIC;
+               }
        }
        return TEE_SUCCESS;
 }
@@ -2135,7 +2147,12 @@ TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, const void* srcData,
        if (!(op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
                CRYPTO_PANIC;
        }
-       int ret = crypto_internal_final(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen);
+       int ret;
+       if (op->info.algorithm == TEE_ALG_AES_CTR) {
+               ret = ossl_crypto_cipher_final(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen);
+       } else {
+               ret = crypto_internal_final(op, (unsigned char*)srcData, srcLen, (unsigned char*)destData, destLen);
+       }
        switch (ret) {
        case 0:
                return TEE_SUCCESS;
@@ -2316,8 +2333,7 @@ TEE_Result TEE_AEInit(TEE_OperationHandle operation, void* nonce, size_t nonceLe
                CRYPTO_PANIC;
        }
 
-       if (ossl_crypto_ae_init(op, &key,
-                                                       (unsigned char*)nonce, nonceLen, tagLen)) {
+       if (ossl_crypto_cipher_init(op, &key, nonce, nonceLen, tagLen)) {
                LOGE(MODULE_SSF_LIB, "Failed to initialize AE algorithm");
                CRYPTO_PANIC;
        }
@@ -2344,7 +2360,7 @@ void TEE_AEUpdateAAD(TEE_OperationHandle operation, void* AADdata, size_t AADdat
                CRYPTO_PANIC;
        }
 
-       if (ossl_crypto_ae_update_aad(op, AADdata, AADdataLen)) {
+       if (ossl_crypto_cipher_update_aad(op, AADdata, AADdataLen)) {
                LOGE(MODULE_SSF_LIB, "Failed to update AAD data");
                CRYPTO_PANIC;
        }
@@ -2370,7 +2386,7 @@ TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, void* srcData, size_t src
                CRYPTO_PANIC;
        }
 
-       if (ossl_crypto_ae_update(op, srcData, srcLen, destData, destLen)) {
+       if (ossl_crypto_cipher_update(op, srcData, srcLen, destData, destLen)) {
                LOGE(MODULE_SSF_LIB, "Failed to update cipher data");
                CRYPTO_PANIC;
        }
index 0778cf0..a965350 100644 (file)
@@ -57,14 +57,14 @@ void ossl_crypto_close(crypto_internal_operation *op)
        op->crypto = 0;
 }
 
-int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct *key,
-                                               void *iv, size_t iv_len, unsigned int tag_len)
+int ossl_crypto_cipher_init(crypto_internal_operation *op, crypto_internal_keystruct *key,
+                                                       const void *iv, size_t iv_len, unsigned int tag_len)
 {
        const EVP_CIPHER *(*EVP_alg)();
        EVP_CIPHER_CTX *ctx;
        int ret = -1;
 
-       LOGI(MODULE_SSF_LIB, "AE Init");
+       LOGI(MODULE_SSF_LIB, "Cipher Init");
 
        ctx = (EVP_CIPHER_CTX *)op->crypto;
        if (ctx == NULL) {
@@ -98,13 +98,22 @@ int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct
                                case 128: EVP_alg = EVP_aes_128_gcm; break;
                                case 192: EVP_alg = EVP_aes_192_gcm; break;
                                case 256: EVP_alg = EVP_aes_256_gcm; break;
-                               default: {
+                               default:
                                        LOGE(MODULE_SSF_LIB, "Unsupported key size %d", op->info.keySize);
                                        return -1;
-                               }
                        }
                        break;
                }
+               case TEE_ALG_AES_CTR:
+                       switch (op->info.keySize) {
+                               case 128: EVP_alg = EVP_aes_128_ctr; break;
+                               case 192: EVP_alg = EVP_aes_192_ctr; break;
+                               case 256: EVP_alg = EVP_aes_256_ctr; break;
+                               default:
+                                       LOGE(MODULE_SSF_LIB, "Unsupported key size %d", op->info.keySize);
+                                       return -1;
+                       }
+                       break;
 
                default: {
                        LOGE(MODULE_SSF_LIB, "Unsupported AE crypto algorithm %x", op->info.algorithm);
@@ -127,7 +136,7 @@ int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct
                }
        }
 
-       ret = EVP_CipherInit(ctx, NULL, key->secret.buffer, (unsigned char*)iv,
+       ret = EVP_CipherInit(ctx, NULL, key->secret.buffer, (const unsigned char*)iv,
                                                (op->info.mode == TEE_MODE_ENCRYPT) ? 1 : 0);
        if (ret != EVP_SUCCESS) {
                LOGE(MODULE_SSF_LIB, "Failed to initialize cipher");
@@ -143,13 +152,13 @@ int ossl_crypto_ae_init(crypto_internal_operation *op, crypto_internal_keystruct
        return 0;
 }
 
-int ossl_crypto_ae_update_aad(crypto_internal_operation *op, void *aad, size_t aad_len)
+int ossl_crypto_cipher_update_aad(crypto_internal_operation *op, void *aad, size_t aad_len)
 {
        EVP_CIPHER_CTX *ctx;
        int dstLen = 0;
        int ret = 0;
 
-       LOGI(MODULE_SSF_LIB, "AE Update AAD");
+       LOGI(MODULE_SSF_LIB, "Cipher Update AAD");
 
        ctx = (EVP_CIPHER_CTX *)op->crypto;
        if (ctx == NULL) {
@@ -166,13 +175,13 @@ int ossl_crypto_ae_update_aad(crypto_internal_operation *op, void *aad, size_t a
        return 0;
 }
 
-int ossl_crypto_ae_update(crypto_internal_operation *op, void *src, size_t src_len,
-                                               void *dst, size_t *dst_len)
+int ossl_crypto_cipher_update(crypto_internal_operation *op, const void *src, size_t src_len,
+                                                               void *dst, size_t *dst_len)
 {
        EVP_CIPHER_CTX *ctx;
        int ret = 0;
 
-       LOGI(MODULE_SSF_LIB, "AE Update");
+       LOGI(MODULE_SSF_LIB, "Cipher Update");
 
        ctx = (EVP_CIPHER_CTX *)op->crypto;
        if (ctx == NULL) {
@@ -180,7 +189,7 @@ int ossl_crypto_ae_update(crypto_internal_operation *op, void *src, size_t src_l
                return -1;
        }
 
-       ret = EVP_CipherUpdate(ctx, (unsigned char*)dst, (int*)dst_len, (unsigned char*)src, src_len);
+       ret = EVP_CipherUpdate(ctx, (unsigned char*)dst, (int*)dst_len, (const unsigned char*)src, src_len);
        if (ret != EVP_SUCCESS) {
                LOGE(MODULE_SSF_LIB, "Cipher Update failed");
                return -1;
@@ -189,8 +198,8 @@ int ossl_crypto_ae_update(crypto_internal_operation *op, void *src, size_t src_l
        return 0;
 }
 
-int ossl_crypto_ae_enc_final(crypto_internal_operation *op, void *src, size_t src_len,
-                                                       void *dst, size_t *dst_len, void *tag, size_t *tag_len)
+int ossl_crypto_cipher_final(crypto_internal_operation *op, void *src, size_t src_len,
+                                                       void *dst, size_t *dst_len)
 {
        EVP_CIPHER_CTX *ctx;
        int ret = -1;
@@ -220,6 +229,20 @@ int ossl_crypto_ae_enc_final(crypto_internal_operation *op, void *src, size_t sr
 
        *dst_len += written;
 
+       return 0;
+}
+
+int ossl_crypto_ae_enc_final(crypto_internal_operation *op, void *src, size_t src_len,
+                                                       void *dst, size_t *dst_len, void *tag, size_t *tag_len)
+{
+       int ret = ossl_crypto_cipher_final(op, src, src_len, dst, dst_len);
+
+       if (ret != 0)
+               return ret;
+
+
+       EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)op->crypto;
+
        // get tag
        ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, *tag_len, tag);
        if (ret != EVP_SUCCESS) {
@@ -269,3 +292,4 @@ int ossl_crypto_ae_dec_final(crypto_internal_operation *op, void *src, size_t sr
        *dst_len += written;
        return 0;
 }
+