Skip to content

sys/crypto: add ccms#13149

Closed
fjmolinas wants to merge 14 commits intoRIOT-OS:masterfrom
fjmolinas:pr_ccms
Closed

sys/crypto: add ccms#13149
fjmolinas wants to merge 14 commits intoRIOT-OS:masterfrom
fjmolinas:pr_ccms

Conversation

@fjmolinas
Copy link
Copy Markdown
Contributor

@fjmolinas fjmolinas commented Jan 17, 2020

Contribution description

This PR extends CCM to add CCM* (CCMS) . It differs from CCM in that it can be used for messages that require only encryption.

The test cases have been taken from [1] as well.

[1] https://mentor.ieee.org/802.15/dcn/04/15-04-0537-02-004b-formal-specification-ccm-star-mode-operation.pdf

Testing procedure

  • run test
    make -C tests/sys_crypto/ all test

  • take a look at [1] to check the implementation (or better said adaptation of the already existing CCM)

@fjmolinas fjmolinas added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: crypto Area: Cryptographic libraries labels Jan 17, 2020
@benpicco benpicco added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR and removed CI: run tests If set, CI server will run tests on hardware for the labeled PR labels Jan 24, 2020
@fjmolinas fjmolinas requested a review from mtausig February 5, 2020 10:27
@fjmolinas
Copy link
Copy Markdown
Contributor Author

Build failed only on insufficient memory and doxygen mistake:

running './dist/tools/headerguards/check.sh' x
Command output:

	--- sys/include/crypto/modes/ccm_common.h
	+++ sys/include/crypto/modes/ccm_common.h
	@@ -46,5 +46,5 @@
	 }
	 #endif
	 
	-#endif /* CRYPTO_MODES_CCM_H */
	+#endif /* CRYPTO_MODES_CCM_COMMON_H */
	 /** @} */

I'll add the boards after review:

atmega1284p
derfmega128
mega-xplained
microduino-corerf
msb-430
msb-430h

Copy link
Copy Markdown
Contributor

@mtausig mtausig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I don't quite see the point of this cipher mode.
The code looks find,though, apart from minor things.

/* MAC */
0x4F, 0xDE, 0x52, 0x90, 0x61, 0xF9, 0xC6, 0xF1
};
static const size_t TEST_IEEE_0537R2_3_EXPECTED_LEN = 38;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you maybe add some more test vectors with longer data. Since the CCM implementation had problems in the past in that area, it would be helpful.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to add those? They both share the same base code, and those extended length cases are already tested in tests-crypto-modes-ccms.c, I could still generate some if you feel its needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just add one long sequence... Doesn't the above referenced document provide one?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I added all the vectors provided in the document. I added in the last fixup some longer test vectors generated with PyCryptodome.

fjmolinas added a commit to fjmolinas/RIOT that referenced this pull request Mar 27, 2020
fjmolinas added a commit to fjmolinas/RIOT that referenced this pull request Apr 3, 2020
fjmolinas added a commit to fjmolinas/RIOT that referenced this pull request Apr 6, 2020
Copy link
Copy Markdown
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good to me, just left some minor comments for improvement. Provided test passes.

const uint8_t *input, size_t input_len,
uint8_t *plain)
{
if(_validate_mac_length_ccms(mac_length)){
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to double check, this is the only difference to cipher_decrypt_ccm above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and no. CCM* specifies as well that:

The nonce N shall encode the potential values for M such that one can uniquely determine from N the actually used value of M. The exact format of the nonce N is outside the scope of this specification and shall be determined and fixed by the actual implementation environment of the CCM* mode.

This part I did not address, this PR intended only to allow messages requiring only encryption. How to generate that nonce to encode M, and how to decode M from the nonce, was not required for me currently. I would address it latter if needed. But I realize this is not clear in the documentation I will add a comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check how this is implemented elsewhere? OpenWSN?

}

#define do_test_decrypt_op(name) do { \
test_decrypt_op(TEST_ ## name ## _KEY, TEST_ ## name ## _KEY_LEN, \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the new tests/sys_crypto structure. Is it possible to share this between tests-crypto-modes-ccm.c and tests-crypto-modes-ccms.c ?

Copy link
Copy Markdown
Contributor Author

@fjmolinas fjmolinas Apr 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macros could be in a shared header file yes , and I could move the shared test_decrypt_op()/test_encrypt_op into a helper source file as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this hasn't been addressed yet.

@PeterKietzmann
Copy link
Copy Markdown
Member

TBH, I don't quite see the point of this cipher mode.

@mtausig the OpenWSN re-integration in #13824 requires it. This mode is involved in link layer security in TSCH networks. Do you have objections?

@mtausig
Copy link
Copy Markdown
Contributor

mtausig commented Apr 8, 2020

TBH, I don't quite see the point of this cipher mode.

@mtausig the OpenWSN re-integration in #13824 requires it. This mode is involved in link layer security in TSCH networks. Do you have objections?

No, if there is a valid reason for it I'm OK with it. Maybe add a disclaimer in the documentation to prevent it from beeing used for generic encryption.

… test

change doc to make explicit that plaintext=0 is allowed
Explicit plaintext length in header
Copy link
Copy Markdown
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjmolinas thanks for addressing my comments! The code looks good, an adequate amount of documentation is in place and tests still pass. ACK from my side. Please squash

@leandrolanzieri leandrolanzieri added this to the Release 2020.04 milestone Apr 9, 2020
Add implemenation disclaimer.
@fjmolinas
Copy link
Copy Markdown
Contributor Author

No, if there is a valid reason for it I'm OK with it. Maybe add a disclaimer in the documentation to prevent it from beeing used for generic encryption.

Added a note in the documentation

Just to double check, this is the only difference to cipher_decrypt_ccm above?
Yes and no. CCM* specifies as well that:

The nonce N shall encode the potential values for M such that one can uniquely determine from N the actually used value of M. The exact format of the nonce N is outside the scope of this specification and shall be determined and fixed by the actual implementation environment of the CCM* mode.

This part I did not address, this PR intended only to allow messages requiring only encryption. How to generate that nonce to encode M, and how to decode M from the nonce, was not required for me currently. I would address it latter if needed. But I realize this is not clear in the documentation I will add a comment.

Add more context on this in the documentation. Note that If at some point the nonce is encoded, this would depend on the application. Since this was out of scope of the specification they just use the source address, frame counter and security level, OpenWSN does something similar using source address and the ASN (absolute slot number).

@fjmolinas
Copy link
Copy Markdown
Contributor Author

Add more context on this in the documentation. Note that If at some point the nonce is encoded, this would depend on the application. Since this was out of scope of the specification they just use the source address, frame counter and security level, OpenWSN does something similar using source address and the ASN (absolute slot number).

Contiki's implementation also just receives the nonce. But let me take a second look elsewhere.

@fjmolinas
Copy link
Copy Markdown
Contributor Author

The CCM* mode extends the definition of the original CCM mode, such as to provide for confidentiality-only services, in addition to the other security service options already offered. Moreover, the CCM* mode adapts the original CCM mode such that the resulting mode can be used securely with variable-length authentication tags, rather than fixed-length authentication tags only. Thus, the CCM* mode takes away the disadvantages of the CCM mode pointed out above. For the detailed specification of the CCM* mode of operation, see Section 2.

I looked again into ccm, ccms documentation and implementations. I now think I agree with @mtausig, there is no interest in adding CCMS as this PR is constructed. Using CCMS for encryption only is not recommended security wise, so its not to be expected that upper layers would have a use for it. Only the nonce part could be of interest, but its not part of the PR. OpenWSN on its side although it uses an implementation of ccms similar to this PR (so it allows encryption only), it never uses encryption only mode, for the same security issues.

Also in the case of OpenWSN oscore or iee802154e specifies how the nonce should be computed, so there is no use case for the second feature that a CCM extension would provide. Since my main use case was the OpenWSN PR, and since it is no longer needed, I'll would like to close this PR, and split the change that adds the test and handling of input_len=0 3b4aca6.

If I come around implementing a scheme for nonce encoding, I would re-open.

@fjmolinas
Copy link
Copy Markdown
Contributor Author

Closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: crypto Area: Cryptographic libraries CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants