Hilman,

You might want to use srtp_octet_string_hex_string() to dump the contents of buffers, since the v128_hex_string() is intended for use with 16 octet strings.  While AES is a block cipher that operates on 16 octet blocks, the output from ICM over the keystream can be as little as one octet.

The keystream is the length of the data to encrypt. And, yes, one takes that keystream and XORs it with the plaintext to produce the ciphertext as illustrated here: https://tools.ietf.org/html/rfc3711#page-20

The ciphertext is the same length as the original plaintext, which is also the same length as the keystream (in practice, since no padding is used).

Paul

------ Original Message ------
From: "Hilman Fitriana via libsrtp" <libsrtp@lists.packetizer.com>
To: libsrtp@lists.packetizer.com
Sent: 6/22/2020 3:14:08 PM
Subject: [libsrtp] AES CM implementation in SRTP

Hello. I want to ask about the implementation of the AES ICM method in the SRTP payload encryption process.
In my understanding, the AES ICM encryption process works by doing `bitwise XOR` between the `keystream buffer` and the `buffer itself (plaintext)`. Keystream buffers are generated through the AES process with the input value of iv and the master key.
Following is the implementation of the AES CM method in the srtp library.

    static srtp_err_status_t srtp_aes_icm_encrypt(void *cv,unsigned char *buf,unsigned int *enc_len){
       srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
       unsigned int bytes_to_encr = *enc_len;
       unsigned int i;
       uint32_t *b;
       printf("\nbuffer (plaintext)in hexa: %s \n",v128_hex_string(buf));
       
       //.............................................................
       //pass
       /* now loop over entire 16-byte blocks of cast-iron */
       for (i = 0; i < (bytes_to_encr / sizeof(v128_t)); i++) {
        /* fill buffer with new keystream */
           srtp_aes_icm_advance(c);

    /*
    * add keystream into the data buffer (this would be a lot faster
    * if we could assume 32-bit alignment!)
    */

    #if ALIGN_32
           //.............................................................
           //pass
    #else
           if ((((uintptr_t)buf) & 0x03) != 0) {
           } else {
               printf("\nkeystream :%s\n",v128_hex_string(&c->keystream_buffer));
               b = (uint32_t *)buf;
               *b++ ^= c->keystream_buffer.v32[0];
               *b++ ^= c->keystream_buffer.v32[1];
               *b++ ^= c->keystream_buffer.v32[2];
               *b++ ^= c->keystream_buffer.v32[3];
               buf = (uint8_t *)b;
           }
    #endif /* #if ALIGN_32 */
       }
           //.............................................................
           //pass

     printf("\nbuffer after encrypt (ciphertext):%s\n",v128_hex_string(buff));
    return srtp_err_status_ok;
    }

I then tried to display the plaintext stored in buf as well as the keystream used for bitwise xor operations. However, when displaying ciphertext, it does not show the results of bitwise xor `plaintext` and `keystream`. Can anyone help me understand the code?

Thank you