You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2019/06/14 10:08:40 UTC

[mynewt-core] 02/04: [STM32] Fix crypto driver IV/nonce handling

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 8608902f884a24a87d82c6054d5dbd00c1ed4a43
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Tue May 28 12:21:42 2019 -0300

    [STM32] Fix crypto driver IV/nonce handling
---
 hw/drivers/crypto/crypto_stm32/src/crypto_stm32.c | 30 +++++++++++++++++++----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/hw/drivers/crypto/crypto_stm32/src/crypto_stm32.c b/hw/drivers/crypto/crypto_stm32/src/crypto_stm32.c
index ca1c424..b81e075 100644
--- a/hw/drivers/crypto/crypto_stm32/src/crypto_stm32.c
+++ b/hw/drivers/crypto/crypto_stm32/src/crypto_stm32.c
@@ -65,11 +65,16 @@ stm32_has_support(struct crypto_dev *crypto, uint8_t op, uint16_t algo,
 
 static uint32_t
 stm32_crypto_op(struct crypto_dev *crypto, uint8_t op, uint16_t algo,
-        uint16_t mode, const uint8_t *key, uint16_t keylen, const uint8_t *iv,
+        uint16_t mode, const uint8_t *key, uint16_t keylen, uint8_t *iv,
         const uint8_t *inbuf, uint8_t *outbuf, uint32_t len)
 {
     HAL_StatusTypeDef status;
     uint32_t sz = 0;
+    uint8_t i;
+    uint8_t iv_save[AES_BLOCK_LEN];
+    unsigned int inc;
+    unsigned int carry;
+    unsigned int v;
 
     if (!stm32_has_support(crypto, op, algo, mode, keylen)) {
         return 0;
@@ -106,9 +111,16 @@ stm32_crypto_op(struct crypto_dev *crypto, uint8_t op, uint16_t algo,
         if (op == CRYPTO_OP_ENCRYPT) {
             status = HAL_CRYP_AESCBC_Encrypt(&g_hcryp, (uint8_t *)inbuf, len,
                     outbuf, HAL_MAX_DELAY);
+            if (status == HAL_OK) {
+                memcpy(iv, &outbuf[len-AES_BLOCK_LEN], AES_BLOCK_LEN);
+            }
         } else {
+            memcpy(iv_save, &inbuf[len-AES_BLOCK_LEN], AES_BLOCK_LEN);
             status = HAL_CRYP_AESCBC_Decrypt(&g_hcryp, (uint8_t *)inbuf, len,
                     outbuf, HAL_MAX_DELAY);
+            if (status == HAL_OK) {
+                memcpy(iv, iv_save, AES_BLOCK_LEN);
+            }
         }
         break;
     case CRYPTO_MODE_CTR:
@@ -119,18 +131,26 @@ stm32_crypto_op(struct crypto_dev *crypto, uint8_t op, uint16_t algo,
             status = HAL_CRYP_AESCTR_Decrypt(&g_hcryp, (uint8_t *)inbuf, len,
                     outbuf, HAL_MAX_DELAY);
         }
+        if (status == HAL_OK) {
+            inc = (len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
+            carry = 0;
+            for (i = AES_BLOCK_LEN; (inc != 0 || carry != 0) && i > 0; --i) {
+                v = carry + (uint8_t)inc + iv[i - 1];
+                iv[i - 1] = (uint8_t)v;
+                inc >>= 8;
+                carry = v >> 8;
+            }
+        }
         break;
     default:
         sz = 0;
         goto out;
     }
 
-    if (status != HAL_OK) {
-        sz = 0;
+    if (status == HAL_OK) {
+        sz = len;
     }
 
-    /* XXX update IV/nonce if OK */
-
 out:
     os_mutex_release(&gmtx);
     return sz;