Subject: [AVTCORE] Comments on the draft-ietf-avtcore-srtp-aes-gcm-02

From: Woo-Hwan Kim <[email-masked]>
Date: Tue, 28 Aug 2012 13:14:34 +0900

Hi.

Here are some comments on the draft-ietf-avtcore-srtp-aes-gcm-02.

1. Typos
Sections 5.2.1, 6. length(plaintext) → length(Plaintext) i.e. plaintext =>
Plaintext
Section 5.2.2. length(ciphertext) → length(Ciphertext) i.e. ciphertext
=> Ciphertext
Section 6. 12 octet IV  =>  12-octet IV
Section 6. ~ to form cipher  =>  to form ciphertext
Section 6(CCM part). 4-octet block counter  =>  3-octet block counter
Section 6(CCM pseudocode). assert len(plaintext) <= 2**28  => ... (2**28-16)
Section 6. keystream of length of up to 2^24 octets for AES-CCM => ...
2^28-16 octgets ...
* In CCM counter starts from 0 and the first block is used for generation
the tag.
Sections 9.1, 10.1 12 octet initialization vector  =>  12-octet
initialization vector (IV)
Section 10.3. cipher field  =>  ciphertext field
Section 11.1. C_MAX CCM: MUST be at most 2^24+16 octets => ... 2^28 octets
...

2. Mode of operations
In Section 6, keystream generation parts of GCM and CCM are described.
But, both descriptions have some flaws based on NIST specifications
For GCM, pseudocode should be modified as follows:
====================================================================
def GCM_keystream(Plaintext, IV, Encryption_key):    assert len(Plaintext)
<== (2**36 - 32)
    key_stream = ""
    block_counter = 1
    first_key_block = AES_ENC(data = IV || block_counter,

                                               key = Encryption_key)
    while len(key_stream) < len(Plaintext):
        block_counter = block_counter + 1
        key_block = AES_ENC(data = IV || block_counter,
                               key = Encryption_key)
        key_stream = key_stream || key_block
    key_stream = truncate(key_stream, len(Plaintext))
    return (key_stream, first_key_block)
====================================================================
Here, the role of the "first_key_block" (or pre_counter block stated in
NIST SP 800-38C) is the same as that of the "last_key_block"

For CCM, pseudocode should be modified as follows:
====================================================================
def CCM_keystream(Plaintext, IV, Counter_Flag, Encryption_key):    assert
len(Plaintext) <== 2**28
    key_stream = ""
    block_counter = 0
    first_key_block = AES_ENC(data = Counter_block_Flag || IV ||
block_counter,
                                              key = Encryption_key)
    while len(key_stream) < len(Plaintext):
        block_counter = block_counter + 1
        key_block = AES_ENC(data = Counter_Flag || IV || block_counter,
                                            key = Encryption_key)
        key_stream = key_stream || key_block
    key_stream = truncate(key_stream, len(Plaintext))
    return (key_stream, first_key_block)
====================================================================
Tag_Size_Flag is only used as the leading octet of the output value of
InputFormattingFunction.
And there is a separate flag namely Counter_Flag to formatting the counter
block.
Because the pseudocode described in this draft is  related to keystream
generation, the flag should be Counter_Block_Flag.

As noted in GCM, the "first_key_block" is used to generate AEAD
authenticated tag.

3. In Section 5.2, AES-CCM uses a Tag_Size_Flag...:
There are two kinds of flags in CCM. One is in the input formatting
function and the other is in the counter block.
"Tag_Size_Flag" seems to be the former and it is determined by the
existence of associated data, tag size and block counter size.
 Thus the term "Tag_Size_Flag" seems to be unsuitable.
Moreover, the term "Tag_Size_Flag" does not have to be used, since  the
algorithm choice determines the tag size in CCM similarly to GCM,

4. RFC 4771
It seems that there are some differences on implementing RFC 4771 when AEAD
authentication mechanism is used instead of general MAC algorithm.
Though the description of those differences is out of scope of this draft,
it may be possible to make certain of it.

5. In Sections 9.2, 10.2 and 10.3, the length of authentication tags for
SRTP and SRTCP have the same fixed value (32-bit).
In RFC 3711, however, authentication tag length is configurable.

6. In Section 10.2 (Data types in encrypted SRTCP compounded packets), can
the case of empty plaintext field be occurred?

7. Comparing with Figure 4, the only difference of Figure 5 is that the
plaintext field is to be authenticated but not encrypted.
It would be better to unify the description of Sections 10.2 and 10.3 like
Section 3.4 in RFC 3711.

8. In Section 11.2 and 11.3, the tag size of mandatory implementation for
GCM is 8 octets while that for CCM is 16 octets.
 Are there any reasons causing this difference?

9. What about addition of the following cipher suites in 14.1 like DTLS?
- AEAD_AES_128_CCM_8, AEAD_AES_128_CCM_12, AEAD_AES_256_CCM_8,
AEAD_AES_256_CCM_12.

Thanks.

Woo-Hwan Kim

---

From: "Igoe, Kevin M." <[email-masked]>
Date: Thu, 30 Aug 2012 18:59:45 +0000

Once again, many thanks to Woo-Hwan for his careful review.

I’d caught the bug about taking the last_key_block instead of the first_key_block
about 3 minutes after hitting the submit button.  Murhpy’s law!

Typos & changes suggested in (1) and (2) have been made.

(3) Since the CCM octet flag is constant (0x02) in this application, I hard wired it
into the pseudo-code and eliminated the Tag_Size_Flag/Counter_Flag variable
entirely.

(4) Not sure what you mean in this comment.

(5) The diagrams in section 9.2, 10.2 and 10.3 are largely copied from RFC 3711.
Since we deprecate the use of the existing SRTP authentication field, I think
I’ll leave the diagrams as they are.

(6) If there is no plaintext in the packet, you really should be using section
10.3 (i.e. the encryption bit set to 0).  However there is no harm in having
an empty plaintext field, save that the cipher text field will be non-trivial
since it contains the AEAD-MAC.  Section 10.3 addresses where the MAC
should be put, section 10.2 doesn’t.

(7) On unifying Figure 4 and Figure 5:  I’ve had a hard time typesetting this to
meet the maximum line length specification for RFCs.  My attempts at
combining them kept pushing my over that limit, whence my decision to split
into tow figures.

(8) and (9):  There is a peculiar difference between how CCM and GCM
specify the size of the authentication tag.  In CCM the tag length is an external
parameter, CCM with an 8-octet tag and CCM with a 12-octet tag are
considered to be the same algorithm running with a different tag
size parameter.  But in GCM it has been traditional to consider GCM-8 and
GCM-12  to be separate algorithms.  The draft requires that GCM-8 MUST
be supported,  but by definition any compliant implementation of CCM must be
capable of handling 4, 6, 8, 10, 12, 14 and 16 octet authentication tags.
I agree the distinction between the two approached is largely sophistry,
but it is there none the less.  That affects how things go into the IANA registry.
It also explains why CCM has no single “mandatory to implement” tag size.

Of course any given system is likely to hardwire in one tag size which is
felt to best meet their security and latency constraints.  We felt
8-octets was a reasonable compromise, whence making AES-8 mandatory
to implement for GCM (by definition an 8-octet tag is already mandatory to
implement for CCM, as are the other 6 values.)

I have a draft -03 ready to go, just holding off until I get some more feedback.
Let me know if you’d like to see it before Iformally submit it to the IETF.

From: [email-masked] [mailto:[email-masked]] On Behalf Of Woo-Hwan Kim
Sent: Tuesday, August 28, 2012 12:15 AM
To: [email-masked]; [email-masked]
Cc: Daesung Kwon; Je Hong Park
Subject: [AVTCORE] Comments on the draft-ietf-avtcore-srtp-aes-gcm-02

Hi.

1. Typos
Sections 5.2.1, 6. length(plaintext) → length(Plaintext) i.e. plaintext => Plaintext
Section 5.2.2. length(ciphertext) → length(Ciphertext) i.e. ciphertext => Ciphertext
Section 6. 12 octet IV  =>  12-octet IV
Section 6. ~ to form cipher  =>  to form ciphertext
Section 6(CCM part). 4-octet block counter  =>  3-octet block counter
Section 6(CCM pseudocode). assert len(plaintext) <= 2**28  => ... (2**28-16)
Section 6. keystream of length of up to 2^24 octets for AES-CCM => ... 2^28-16 octgets ...
* In CCM counter starts from 0 and the first block is used for generation the tag.
Sections 9.1, 10.1 12 octet initialization vector  =>  12-octet initialization vector (IV)
Section 10.3. cipher field  =>  ciphertext field
Section 11.1. C_MAX CCM: MUST be at most 2^24+16 octets => ... 2^28 octets ...

2. Mode of operations
def GCM_keystream(Plaintext, IV, Encryption_key):    assert len(Plaintext) <== (2**36 - 32)
    key_stream = “”
Here, the role of the “first_key_block” (or pre_counter block stated in NIST SP 800-38C) is the same as that of the “last_key_block”

For CCM, pseudocode should be modified as follows:
====================================================================
def CCM_keystream(Plaintext, IV, Counter_Flag, Encryption_key):    assert len(Plaintext) <== 2**28
    key_stream = “”
    block_counter = 0
    first_key_block = AES_ENC(data = Counter_block_Flag || IV || block_counter,
                                              key = Encryption_key)
    while len(key_stream) < len(Plaintext):
        block_counter = block_counter + 1
        key_block = AES_ENC(data = Counter_Flag || IV || block_counter,
                                            key = Encryption_key)
        key_stream = key_stream || key_block
    key_stream = truncate(key_stream, len(Plaintext))
    return (key_stream, first_key_block)
====================================================================
Tag_Size_Flag is only used as the leading octet of the output value of InputFormattingFunction.
And there is a separate flag namely Counter_Flag to formatting the counter block.
Because the pseudocode described in this draft is  related to keystream generation, the flag should be Counter_Block_Flag.

As noted in GCM, the “first_key_block” is used to generate AEAD authenticated tag.

3. In Section 5.2, AES-CCM uses a Tag_Size_Flag...:
There are two kinds of flags in CCM. One is in the input formatting function and the other is in the counter block.
"Tag_Size_Flag" seems to be the former and it is determined by the existence of associated data, tag size and block counter size.
 Thus the term "Tag_Size_Flag" seems to be unsuitable.
Moreover, the term "Tag_Size_Flag" does not have to be used, since  the algorithm choice determines the tag size in CCM similarly to GCM,

4. RFC 4771
It seems that there are some differences on implementing RFC 4771 when AEAD authentication mechanism is used instead of general MAC algorithm.
Though the description of those differences is out of scope of this draft, it may be possible to make certain of it.

5. In Sections 9.2, 10.2 and 10.3, the length of authentication tags for SRTP and SRTCP have the same fixed value (32-bit).
In RFC 3711, however, authentication tag length is configurable.

6. In Section 10.2 (Data types in encrypted SRTCP compounded packets), can the case of empty plaintext field be occurred?

7. Comparing with Figure 4, the only difference of Figure 5 is that the plaintext field is to be authenticated but not encrypted.
It would be better to unify the description of Sections 10.2 and 10.3 like Section 3.4 in RFC 3711.

8. In Section 11.2 and 11.3, the tag size of mandatory implementation for GCM is 8 octets while that for CCM is 16 octets.
 Are there any reasons causing this difference?

9. What about addition of the following cipher suites in 14.1 like DTLS?
- AEAD_AES_128_CCM_8, AEAD_AES_128_CCM_12, AEAD_AES_256_CCM_8, AEAD_AES_256_CCM_12.

Thanks.

Woo-Hwan Kim