Softdevice with AES GCM suport

We have an existing application, based on the nordic softdevice  s140nrf52701 that uses the AES algorithm, specifically ECB, CTR and CBC mode. We need to migrate to AES GCM.
Is there a library we can use? It look like there should be some lib like nrf_oberon, but I wonder if that is for Zephyr only.

regards

Bob

Parents
  • Hi Bob,

    As you describe the S140 SoftDevice I assume you are also using the nRF5 SDK? If so, you can use nrf_crypto which provide AES GCM via mbed TLS. You can refer to the AES Example to see how it is used.

  • Hi Einar,

    I implemented the GCM encryption. When encrypting and decrypting a string with the library, all went well.
    However when I use Java (Android) to encrypt en the nRF to decrypt, I am not able to get it working.
    I use the following code to generate an encrypted message:

    public static void gcm_encypt() 
      {
        Cipher cipher;
        try {
          byte[] iv = new byte[12]; // Should be 12 bytes (96 bits)
          // For example, a hardcoded IV (In practice, it's strongly recommended to use random IVs)
          iv = "1234567890123456".getBytes(StandardCharsets.UTF_8);
    
          // Step 3: Set up the GCMParameterSpec with the IV and tag length
          GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv); // 128-bit authentication tag
    
          cipher = Cipher.getInstance("AES/GCM/NoPadding");   
          cipher.init(Cipher.ENCRYPT_MODE,    new SecretKeySpec("My SPecial Secret Key to AES/GCM".getBytes(), "AES"), gcmSpec);
          
          String encryptedNonce = Base64.getEncoder().encodeToString(cipher.doFinal("TESTTESTTESTTEST".getBytes()));
          System.out.println(encryptedNonce);
        } catch (Exception e) {
          e.printStackTrace();
        }
    
      }

    This will produce S55R2aMahlD8laYZL0hJ1jufBEMxqD9IVVBtaAJpQJc= 

    Feeding this to the nRF decryption code:

    static nrf_crypto_aead_info_t const * p_gcm_info;
    static nrf_crypto_aead_context_t      gcm_encr_ctx;
    static nrf_crypto_aead_context_t      gcm_decr_ctx;
    static nrf_crypto_key_size_id_t m_key_size = NRF_CRYPTO_KEY_SIZE_128;
    static char        decrypted_text[100];
    static uint8_t     adata[8];
    static uint8_t     gcm_mac[16];
    static aes_context_t ctx;
    static uint8_t     nonce[16];
    static uint8_t temp[AES_KEYLEN * 2];
    static const uint8_t default_key2[AES_KEYLEN] = 
    {
        'M', 'y', ' ', 'S', 'P', 'e', 'c', 'i', 'a', 'l', ' ', 'S', 'e', 'c', 'r', 'e', 't', ' ', 'K', 'e', 'y', ' ', 't', 'o', ' ', 'A', 'E', 'S', '/', 'G', 'C', 'M'
    };
    
    static void test_aes_gcm()
    {
      NRF_LOG_INFO("test_aes_gcm");
    
      //AES_init_ctx( &ctx,default_key );
      
      /* init the AES/GCM stuff */
      memset(gcm_mac,         0,  sizeof(gcm_mac));
      memset(adata,         0,  sizeof(adata));
      memset(decrypted_text,  0,  sizeof(decrypted_text));
      memset(&gcm_decr_ctx,   0,  sizeof(gcm_decr_ctx));
    
      p_gcm_info = &g_nrf_crypto_aes_gcm_256_info;   
          /* Init encrypt and decrypt context */
      ret_code_t ret_val = nrf_crypto_aead_init(&gcm_encr_ctx, p_gcm_info, (uint8_t*)(default_key2));
      NRF_LOG_INFO("nrf_crypto_aead_init result = %d",ret_val);
      ret_val = nrf_crypto_aead_init(&gcm_decr_ctx,p_gcm_info, (uint8_t*)(default_key2));
      NRF_LOG_INFO("nrf_crypto_aead_init result = %d",ret_val);            
          /* encrypt and tag text */
      /* done init the AES/GCM stuff */
    
      int len = decode64("S55R2aMahlD8laYZL0hJ1jufBEMxqD9IVVBtaAJpQJc=", temp, sizeof( temp ) );
      NRF_LOG_INFO("decode 64 len = %d",len); 
                        
      ret_val = nrf_crypto_aead_crypt(&gcm_decr_ctx, //p_context
          NRF_CRYPTO_DECRYPT, //operation
          "1234567890123456", //p_nonce
          16, //nonce_size
          adata, //p_adata 
          0, //adata_size
          temp, //p_data_in
          len, //data_in_size
          decrypted_text, //p_data_out
          gcm_mac, //p_mac
          4); //mac_size 
      
      NRF_LOG_INFO("nrf_crypto_aead_crypt %d",ret_val);
    
    
      NRF_LOG_INFO("done ok %s",decrypted_text);
    }

    will result in:

    <info> app: test_aes_gcm
    <info> app: nrf_crypto_aead_init result = 0
    <info> app: nrf_crypto_aead_init result = 0
    <info> app: decode 64 len = 32
    <info> app: nrf_crypto_aead_crypt 34144
    <info> app: done ok TESTTESTTESTTEST
    à¡mq£3Wµ„9Ž%

    (We modified the gcm.c to skip the  mbedtls_platform_zeroize( output, length );  line in case of an decryption error)

    Any idea what kind of error we created?

    raegard,

    Bob 

  • Hi Bob,

    I am no a Java developer so I may be missing something obvsious, but could this be related to text encoding as you provide the data as text? What if you use binary data/numbers that are not text strings?

  • Hi Einar,

    Thanks for your reply.

    It seems that I was lacking knowledge of the encryption proces. Both encrypter and decrypter must know the initial vector. That piece of information must be send alongside the text that should be encrypted. That solved the problem for me.

    Thanks anyway.

    Bob

Reply Children
Related