intel / tinycrypt Goto Github PK
View Code? Open in Web Editor NEWtinycrypt is a library of cryptographic algorithms with a focus on small, simple implementation.
License: Other
tinycrypt is a library of cryptographic algorithms with a focus on small, simple implementation.
License: Other
# This project will no longer be maintained by Intel. # Intel has ceased development and contributions including, but not limited to, maintenance, bug fixes, new releases, or updates, to this project. Intel no longer accepts patches to this project. If you have an ongoing need to use this project, are interested in independently developing it, or would like to maintain patches for the open source software community, please create your own fork of this project. ================================================================================ TinyCrypt Cryptographic Library ================================================================================ Copyright (c) 2017, Intel Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================================================ Overview: The TinyCrypt Library provides an implementation for constrained devices of a minimal set of standard cryptography primitives. Please, ***SEE THE DOCUMENTATION*** folder for more information on the supported cryptographic primitives and the limitations of TinyCrypt library. For usage, security and technicalities, please see the corresponding header file of each cryptographic primitive. ================================================================================ Organization: /lib: C source code of the cryptographic primitives. /lib/include/tinycrypt: C header files of the cryptographic primitives. /tests: Test vectors of the cryptographic primitives. /doc: Documentation of TinyCrypt. ================================================================================ Building: 1) In Makefile.conf set: - CFLAGS for compiler flags. - CC for compiler. - ENABLE_TESTS for enabling (true) or disabling (false) tests compilation. 2) In lib/Makefile select the primitives required by your project. 3) In tests/Makefile select the corresponding tests of the selected primitives. 4) make 5) run tests in tests/ ================================================================================
It appears to me that tc_ctr_prng_reseed() in ctr_prng.c has a bug(). I believe the following:
/* 10.2.1.4.1 step 4 */
tc_ctr_prng_update(ctx, entropy);
Should be:
/* 10.2.1.4.1 step 4 */
tc_ctr_prng_update(ctx, seed_material);
Bug in the AES-CCM code. The “sanity” check for (plen <= alen) is incorrect. Total message length is not passed in, in this implementation plen and alen are independent. This is a serious problem that causes decryptions to incorrectly fail.
Hi, I'm Jakub from TrustInSoft, an advanced source code analyzer publisher for C and C++. I set up TrustInSoft CI on your tests: https://ci.trust-in-soft.com/projects/jakub-zwolakowski/tinycrypt/
I have found some issues in your code. Here you can check out the issues in TrustInSoft CI (first link in each line) and see your source code for reference (second link in each line):
1) Signed overflow (due to implicit integer conversion) in file 'lib/source/aes_encrypt.c' line 86
2) Invalid memory access (out of bounds read, as a consequence of the wrong length given in the test) in file 'lib/source/utils.c' line 44
3) Invalid pointer arithmetic (pointer arithmetic inside object, computing &array[-1]) in file 'lib/source/cmac_mode.c' line 89
4) Another signed overflow (due to implicit integer conversion) in file 'lib/source/ctr_mode.c' line 61
5) Another invalid pointer arithmetic (inside object, computing &array[-1]) in file 'lib/source/ecc.c' line 238
6) Uninitialized memory (read) in file 'lib/source/sha256.c' line 174
Can you let me know if you find those findings interesting? Would you assess them as harmless or dangerous?
TrustInSoft CI is a new tool based on formal methods. We're currently testing it on Open Source projects so any of your feedback will be greatly appreciated.
set_encrypt_key assumes that unsigned int is at least 32bits. It should I think be using either uint32_t or better yet uint32_fast_t.
SHA256 is also riddled with the same flaw
I suggest to reuse a higher level build system than your current small make file so that powerful checks for software features will become easier.
If the tc_cmac_update() function is called and fills the internal leftover cache completely, the following tc_cmac_final() call will produce a wrong token.
If the tc_cmac_update() is called with a data length which fills up the internal leftover cache completely, the leftover data will be processed instantly and is left empty. This is not the right behavior, because tc_cmac_final() requires that the last block is still in the leftover cache and not processed, because it need special treatment.
See pull request for fix and further information: #52
I would like to point out that identifiers like "__TC_AES_H__
" and "__TC_UTILS_H__
" do eventually not fit to the expected naming convention of the C++ language standard.
Would you like to adjust your selection for unique names?
Lines 50..52 of contants.h
try to define bool
type as follows:
#ifndef bool
enum {false, true} bool;
#endif
There are several issues with the above code, that causes multiple definitions of the same symbol linker error on some strict linkers.
treu
and false
, defines a variable bool
. The right way would be using typedef
keywordbool
does not define the pre-processor symbol bool
, so it does not make sense to enclose the definitionIt is probably better to either include `stdbool.h' or copy its content:
#ifndef bool
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#endif
#endif
PS: This issue was open du to https://gerrit.zephyrproject.org/r/#/c/10848
IS this is an error:
tests/test_cbc_mode.c at line 135:
length = ((unsigned int) sizeof(encrypted));
Should it be the following code:
length = ((unsigned int) sizeof(decrypted));
Hello. I am working in a project to create a library, and this library includes Tinycript within it to provide security functionality.
One issue that we have run into is that the Tinycript library causes linking conflicts with other security libraries (the specific one we are having trouble with is nrf crypto, as we are doing embedded development on the nRF52840 board).
Would it be possible to change the source file names of the Tinycript library to be explicitly Tinycript specific? (i.e., prepend all of them with tc_ or something similar)
It seems that this is already done with the functions within Tinycript, and if it was also done to the source file names it would prevent linking conflicts in certain IDE's like Segger Embedded Studio.
I am vaguely aware that this issue can be solved by changing the names of the object files that the linker generates for the source files that are conflicting, but this solution would make it harder for other users to use our library. I think we could also change the names of the files in the local copy of Tinycript in our library, but that seems like it would make updating Tinycript for our library a hassle in the future.
I am also not sure if this is a design choice on purpose, in order to prevent unnecessary duplicate security implementations that are provided by other security libraries, but it seems like it would still just be more flexible for users of the Tinycript library if they had Tinycript specific source file names.
Thank you very much for reading, and thank you for the nice library!
The rest of the code goes to great pains to use _set() but ecc_dh instead dives into GNUisms, not only that but it dives into non archicture portable GNUisms.
D:\workspace_C>git clone https://github.com/intel/tinycrypt
Cloning into 'tinycrypt'...
remote: Enumerating objects: 698, done.
Receiving objects: 100% (698/698), 891.88 KiB | 2.55 MiB/s, done.
Resolving deltas: 100% (458/458), done.
D:\workspace_C>cd tinycrypt
D:\workspace_C\tinycrypt>ls
AUTHORS documentation LICENSE README VERSION
config.mk lib Makefile tests
D:\workspace_C\tinycrypt>make
make -C lib
make[1]: Entering directory D:/workspace_C/tinycrypt/lib' gcc -Os -std=c99 -Wall -Wextra -D_ISOC99_SOURCE -MMD -I../lib/include/ -I../lib/source/ -I../tests/include/ -DENABLE_TESTS -c -o aes_decrypt.o ../lib/source/aes_decrypt.c process_begin: CreateProcess(NULL, gcc -Os -std=c99 -Wall -Wextra -D_ISOC99_SOURCE -MMD -I../lib/include/ -I../lib/source/ -I../tests/include/ -DENABLE_TESTS -c -o aes_decrypt.o ../lib/source/aes_decrypt.c, ...) failed. make (e=2): 系統找不到指定的檔案。 make[1]: *** [aes_decrypt.o] Error 2 make[1]: Leaving directory
D:/workspace_C/tinycrypt/lib'
make: *** [all] Error 2
Hi,
I want to use uECC_shared_secret()
to derive a shared secret. I have only the x coordinate of the public key. I assume the function uECC_shared_secret()
requires the uncompressed key holding both coordinates {x,y}. How to decompress the public key? I found the following function in uECC link, however, this function appears to not be part of tinycrypt.
The description of the in
parameter of tc_cbc_mode_decrypt
is misleading. All examples show that in
should point on the cipher text offset by the size of the iv (which is a block):
https://github.com/intel/tinycrypt/blob/master/tests/test_cbc_mode.c#L134 :
p = &encrypted[TC_AES_BLOCK_SIZE];
length = ((unsigned int) sizeof(encrypted));
if (tc_cbc_mode_decrypt(decrypted, length, p, length, encrypted, &a) == 0) {
...
But both the note and the description of the in
param are suggesting that it should point on the cipher text including the IV:
https://github.com/intel/tinycrypt/blob/master/lib/include/tinycrypt/cbc_mode.h#L128 :
* @note Assumes:- in == iv + ciphertext, i.e. the iv and the ciphertext are
* contiguous. This allows for a very efficient decryption
* algorithm that would not otherwise be possible
* @param in IN -- ciphertext to decrypt, including IV
I'd propose to modify the doc to something like:
* @note Assumes:- the IV and the ciphertext need to be
* contiguous. This allows for a very efficient decryption
* algorithm that would not otherwise be possible
* @param in IN -- ciphertext to decrypt, not including IV
* @param iv IN -- the IV for the encrypt/decrypt, must be followed by ciphertext
This issue is born out of real-world usage, from the Zephyr project where work is ongoing porting to new platform and compliance cleanup.
A VLA is used in tinycrypt/source/hmac.c
:: tc_hmac_set_key()
, dummy_key
. This is unfortunate for a number of reasons, listed later below.
My understanding:
It appears that dummy_key
is written when key_size <= TC_SHA256_BLOCK_SIZE
and timing between the two branches should be nearly the same to cover up the sidechannel mentioned therein. Normally, key_size
== TC_SHA256_BLOCK_SIZE
and dummy_key
will be written and thrown away. That makes sense, as we only want the timing behavior from tc_sha256_
* in the then-branch. Fine. Call to rekey
is what matters.
Request:
dummy_key
statically sized, to the worst-case (= the usual case) size of TC_SHA256_BLOCK_SIZE
as per the patch below.dummy_key
and dummy_state
to the then-branch.This patch should improve safety too, as 1) the total stack frame usage can now better be analyzed, 2) some compilers may ignore that dummy_key
is only written guarded by key_size <= TC_SHA256_BLOCK_SIZE
since it is declared in the scope outside. So 2 means that stack overflow could happen if key_size was big, even if guarded.
Variable length arrays have multiple issues:
Patch:
diff --git a/ext/lib/crypto/tinycrypt/source/hmac.c b/ext/lib/crypto/tinycrypt/source/hmac.c
index 89878cec7..6e65ae717 100644
--- a/ext/lib/crypto/tinycrypt/source/hmac.c
+++ b/ext/lib/crypto/tinycrypt/source/hmac.c
@@ -63 +63 @@ int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key,
- const uint8_t dummy_key[key_size];
+ const uint8_t dummy_key[TC_SHA256_BLOCK_SIZE];
I'll also be happy to submit a PR.
The function uECC_sign_with_k() applies side-channel resistance to k by multiplying k with a random number "tmp". This is only applied if g_rng_function is set. unfortunately, g_rng_function is never set. The reason is:
ECC implementation is not compliant to FIPS 186. Appendix B.4 allows either generating 64 extra bits and computing c=random mod n, or choosing random bit strings len(n) until a value less than n-2 is found and used as c. This function is only compliant if it fails for a random bit string with integer value less than n-2 is passed in.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.