diff --git a/core/tee/tee_authenc.c b/core/tee/tee_authenc.c index eec7b183077..e8f27869902 100644 --- a/core/tee/tee_authenc.c +++ b/core/tee/tee_authenc.c @@ -25,6 +25,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -413,7 +414,7 @@ TEE_Result tee_authenc_dec_final( goto out; } - if (memcmp(dst_tag, tag, tag_len) != 0) + if (buf_compare_ct(dst_tag, tag, tag_len) != 0) res = TEE_ERROR_MAC_INVALID; else res = TEE_SUCCESS; diff --git a/core/tee/tee_hash.c b/core/tee/tee_hash.c index 7c516524cdb..ac510a447dc 100644 --- a/core/tee/tee_hash.c +++ b/core/tee/tee_hash.c @@ -29,6 +29,7 @@ #include #include #include "tee_ltc_wrapper.h" +#include #define MAX_DIGEST 64 @@ -197,7 +198,7 @@ TEE_Result tee_hash_check( if (res != TEE_SUCCESS) return res; - if (memcmp(digest, hash, hash_size) != 0) + if (buf_compare_ct(digest, hash, hash_size) != 0) return TEE_ERROR_SECURITY; return TEE_SUCCESS; diff --git a/core/tee/tee_rpmb.c b/core/tee/tee_rpmb.c index 9a87e70439e..e69695b2865 100644 --- a/core/tee/tee_rpmb.c +++ b/core/tee/tee_rpmb.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -657,8 +658,8 @@ static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm, } if (rawdata->nonce != NULL) { - if (memcmp(rawdata->nonce, lastfrm.nonce, RPMB_NONCE_SIZE) - != 0) { + if (buf_compare_ct(rawdata->nonce, lastfrm.nonce, + RPMB_NONCE_SIZE) != 0) { DMSG("%s: nonce mismatched", __func__); return TEE_ERROR_SECURITY; } @@ -688,9 +689,9 @@ static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm, return res; } - if (memcmp(rawdata->key_mac, - (datafrm + nbr_frms - 1)->key_mac, - RPMB_KEY_MAC_SIZE) != 0) { + if (buf_compare_ct(rawdata->key_mac, + (datafrm + nbr_frms - 1)->key_mac, + RPMB_KEY_MAC_SIZE) != 0) { DMSG("%s: MAC mismatched:", __func__); #ifdef ENABLE_RPMB_DATA_DUMP HEX_PRINT_BUF((uint8_t *)rawdata->key_mac, 32); diff --git a/lib/libutils/ext/buf_compare_ct.c b/lib/libutils/ext/buf_compare_ct.c new file mode 100644 index 00000000000..1e1b16b7b93 --- /dev/null +++ b/lib/libutils/ext/buf_compare_ct.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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. + */ +#include + +int buf_compare_ct(const void *s1, const void *s2, size_t n) +{ + int res = 0; + unsigned char *c1 = (unsigned char *)s1; + unsigned char *c2 = (unsigned char *)s2; + + while (n--) { + res |= (*c1 ^ *c2); + c1++; + c2++; + } + + return res; +} diff --git a/lib/libutils/ext/include/string_ext.h b/lib/libutils/ext/include/string_ext.h index e284cbe2185..fae93b3c036 100644 --- a/lib/libutils/ext/include/string_ext.h +++ b/lib/libutils/ext/include/string_ext.h @@ -43,4 +43,14 @@ size_t strlcpy(char *dst, const char *src, size_t size); size_t strlcat(char *dst, const char *src, size_t size); +/* + * This memory compare function will compare two buffers in a constant time. + * + * Note that this function will not have same kind of return values as the + * traditional libc memcmp which return either less than or greater than zero + * depending on which string that is lexically greater. This function will + * return 0 if it is a match, otherwise it will return a non-zero value. + */ +int buf_compare_ct(const void *s1, const void *s2, size_t n); + #endif /* STRING_EXT_H */ diff --git a/lib/libutils/ext/sub.mk b/lib/libutils/ext/sub.mk index e8215a0f75a..e065ee938eb 100644 --- a/lib/libutils/ext/sub.mk +++ b/lib/libutils/ext/sub.mk @@ -2,3 +2,4 @@ global-incdirs-y += include srcs-y += strlcat.c srcs-y += strlcpy.c +srcs-y += buf_compare_ct.c