Add CCM cipher suite variants#105
Conversation
98d5444 to
8dd726a
Compare
| #define A_DATA_LEN 13 | ||
| unsigned char nonce[DTLS_CCM_BLOCKSIZE]; | ||
| unsigned char A_DATA[A_DATA_LEN]; | ||
| int macLen = get_cipher_suite_mac_len(security->cipher); |
There was a problem hiding this comment.
With previous suggested change option 2, this type now should probably be uint8_t.
And, as this is C code, please follow the usual conventions for variable naming, i.e., mac_len.
| #define A_DATA_LEN 13 | ||
| unsigned char nonce[DTLS_CCM_BLOCKSIZE]; | ||
| unsigned char A_DATA[A_DATA_LEN]; | ||
| int macLen = get_cipher_suite_mac_len(security->cipher); |
| const dtls_ccm_params_t params = { nonce, 8, 3 }; | ||
| const dtls_ccm_params_t params = { nonce, macLen, 3 }; | ||
|
|
||
| if (clen < 16) /* need at least IV and MAC */ |
There was a problem hiding this comment.
I think that now, we might need to have to check for something like clen < (mac_len + MAX_IV_LENGTH), with MAX_IV_LENGTH currently being 8.
Otherwise, the newly added clen - macLen below might yield an underflow.
There was a problem hiding this comment.
done.
(there is no symbolic IV-length, right?)
There was a problem hiding this comment.
Correct—for some unknown reason, that has not been defined when crafting this check.
There was a problem hiding this comment.
I would propose to go without for this PR.
And have a second PR introducing RECORD_IV_LENGTH.
WDYT?
There was a problem hiding this comment.
Sure, a separate PR would be the cleanest solution.
|
The first part of the changes. I will provided the rest at the weekend. |
|
I added a |
37cd373 to
d6511ef
Compare
6a3f1a4 to
cb6d7f5
Compare
| }; | ||
|
|
||
| typedef enum { | ||
| NONE, |
There was a problem hiding this comment.
I wonder if we should prefix these with, e.g. DTLS_CIPHER_ or similar. Especially NONE might be prone to name clashes.
There was a problem hiding this comment.
What's about KEY_EXCHANGE_...?
|
There is a lot of whitespace change which makes reading this PR a bit difficult. |
I'm used to fix the format of functions when I change them. Yes, that makes it hard to compare. One idea would then be, to spend some time in fix the format at once, and the rebase this PR. Though many files shows "Eclipse Public License v1.0" which is replaced by v2.0, such a cleanup seems to be required anyway. Should I go for format and license fix next week?
The point seems to be, that using a reduced variety, makes it also possible to use very simple implementations. |
1dd7f3c to
b795393
Compare
After analyzing it again, maybe exchange the |
Add cipher suites with full 16 byte MAC. Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
Use cipher_suite_param_t for cipher-suite specific mac_len and key_exchange_algorithm. Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
Simplify cipher suite parameter lookup. Cleanup old functions. Signed-off-by: Achim Kraus <achim.kraus@cloudcoap.net>
|
I reverted many of the whitespace changes, I consider that is easier done separately. |
obgm
left a comment
There was a problem hiding this comment.
I like the new approach with the index into the cipher_suite_params table. I have only a few comments, primarily to fix the data types.
| dtls_compression_t compression; /**< compression method */ | ||
|
|
||
| dtls_cipher_t cipher; /**< cipher type */ | ||
| int cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */ |
There was a problem hiding this comment.
Being an index into an array, size_t would be the correct data type here.
(As the array usually should not have more than, say, 255 non-NULL elements, another unsigned type such as uint8_t might do as well. However, I do not expect cipher_index to be negative at any point in time.)
|
|
||
| dtls_compression_t compression; /**< compression method */ | ||
| dtls_cipher_t cipher; /**< cipher type */ | ||
| int cipher_index; /**< internal index for cipher_suite_params, DTLS_CIPHER_INDEX_NULL for TLS_NULL_WITH_NULL_NULL */ |
| }; | ||
|
|
||
| static inline const cipher_suite_param_t* get_cipher_suite_param(dtls_cipher_t cipher) | ||
| static const int last_cipher_suite_param = sizeof(cipher_suite_params) / sizeof(cipher_suite_param_t); |
There was a problem hiding this comment.
The datatype for last_cipher_suite_param must be size_t.
| static inline const cipher_suite_param_t* get_cipher_suite_param(dtls_cipher_t cipher) | ||
| static const int last_cipher_suite_param = sizeof(cipher_suite_params) / sizeof(cipher_suite_param_t); | ||
|
|
||
| static inline int get_cipher_index(dtls_cipher_t cipher) |
There was a problem hiding this comment.
The return type must be size_t.
| * \return cipher suite. | ||
| */ | ||
| static inline int get_cipher_suite_mac_len(dtls_cipher_t cipher) | ||
| static inline dtls_cipher_t get_cipher_suite(int cipher_index) |
There was a problem hiding this comment.
cipher_index must be of type size_t.
| static inline int get_cipher_suite_mac_len(int cipher_index) | ||
| { | ||
| return get_cipher_suite_param(cipher)->key_exchange_algorithm == DTLS_KEY_EXCHANGE_PSK; | ||
| assert(0 <= cipher_index && cipher_index < last_cipher_suite_param); |
There was a problem hiding this comment.
0 <= cipher_index not needed.
| known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) { | ||
| int psk; | ||
| int ecdsa; | ||
| known_cipher(dtls_context_t *ctx, int cipher_index, int is_client) { |
There was a problem hiding this comment.
cipher_index needs to be of type size_t
| default: | ||
| dtls_crit("calculate_key_block: unknown key exchange %d\n", key_exchange_algorithm); | ||
| return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); | ||
| assert(!"calculate_key_block: not supported key exchange algorithm\n"); |
There was a problem hiding this comment.
I think that this change warrants a PR of its own and should not be hidden somewhere deep down in a harmless looking "enhancement PR".
There was a problem hiding this comment.
Let me try to explain my view:
The most critical "code points" here are the cipher-suite code-points in the Hellos. These code-points must be contained in the cipher_suite_params. The incoming/received "unknown" is therefore the cipher-suite and that fails ahead.
When this "internal/static" function "calculate_key_block" is called, only the cipher_suite_key_exchange_algorithm_t contained in that table are possible.
The "switch-default" itself (previous "unknown key exchange") is to suppress compiler warnings, it doesn't occur (unknown cipher suites are detected ahead and unknown key exchanges don't exist on their own).
Therefore I just moved it to the DTLS_KEY_EXCHANGE_NONE in order to save a couple of bytes.
Maybe a comment instead of separate commit will do it as well?
| } cipher_suite_param_t; | ||
|
|
||
| static const struct cipher_suite_param_t cipher_suite_params[] = { | ||
| { TLS_NULL_WITH_NULL_NULL, 0, DTLS_KEY_EXCHANGE_NONE }, |
There was a problem hiding this comment.
Please add a comment that this entry (with index DTLS_CIPHER_INDEX_NULL must always be the first array element.
|
I prepared PR #147 addressing the left issues here and request to merge it into main. |
In case of CCM gets recommended and CCM8 deprecated.