From 0ec02cb2feaf546739c96d9822d9b4ee9ac441ce Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Tue, 20 Jul 2021 19:18:22 -0500 Subject: common/util: group the code needed in the fips module Group the code we are going to move into the fips module. memcmp memcpy memset memmove reverse strncmp BUG=none TEST=make buildall -j Change-Id: Idb1162dd47f00f676cb1c1ec3f77b85808ad9c30 Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3043358 Reviewed-by: Vadim Bendebury --- common/util.c | 370 +++++++++++++++++++++++++++++-------------------------- include/config.h | 2 + 2 files changed, 195 insertions(+), 177 deletions(-) diff --git a/common/util.c b/common/util.c index 8d12dc59f4..99a7da8a2a 100644 --- a/common/util.c +++ b/common/util.c @@ -9,6 +9,12 @@ #include "console.h" #include "util.h" +/****************************************************************************/ +/* + * Standard functions that need to be a within the cr50 fips boundary. There + * will be equivalent functions in board/cr50/dcrypto that are built separately. + */ +#ifndef CONFIG_FIPS_UTIL __stdlib_compat size_t strlen(const char *s) { int len = 0; @@ -20,6 +26,193 @@ __stdlib_compat size_t strlen(const char *s) } +__stdlib_compat int memcmp(const void *s1, const void *s2, size_t len) +{ + const char *sa = s1; + const char *sb = s2; + + int diff = 0; + + while (len-- > 0) { + diff = *(sa++) - *(sb++); + if (diff) + return diff; + } + + return 0; +} + + +__stdlib_compat void *memcpy(void *dest, const void *src, size_t len) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + uint32_t *dw; + const uint32_t *sw; + char *head; + char * const tail = (char *)dest + len; + /* Set 'body' to the last word boundary */ + uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3); + + if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { + /* Misaligned. no body, no tail. */ + head = tail; + } else { + /* Aligned */ + if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) + /* len is shorter than the first word boundary */ + head = tail; + else + /* Set 'head' to the first word boundary */ + head = (char *)(((uintptr_t)d + 3) & ~3); + } + + /* Copy head */ + while (d < head) + *(d++) = *(s++); + + /* Copy body */ + dw = (uint32_t *)d; + sw = (uint32_t *)s; + while (dw < body) + *(dw++) = *(sw++); + + /* Copy tail */ + d = (char *)dw; + s = (const char *)sw; + while (d < tail) + *(d++) = *(s++); + + return dest; +} + + +__stdlib_compat __visible void *memset(void *dest, int c, size_t len) +{ + char *d = (char *)dest; + uint32_t cccc; + uint32_t *dw; + char *head; + char * const tail = (char *)dest + len; + /* Set 'body' to the last word boundary */ + uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3); + + c &= 0xff; /* Clear upper bits before ORing below */ + cccc = c | (c << 8) | (c << 16) | (c << 24); + + if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) + /* len is shorter than the first word boundary */ + head = tail; + else + /* Set 'head' to the first word boundary */ + head = (char *)(((uintptr_t)d + 3) & ~3); + + /* Copy head */ + while (d < head) + *(d++) = c; + + /* Copy body */ + dw = (uint32_t *)d; + while (dw < body) + *(dw++) = cccc; + + /* Copy tail */ + d = (char *)dw; + while (d < tail) + *(d++) = c; + + return dest; +} + + +__stdlib_compat void *memmove(void *dest, const void *src, size_t len) +{ + if ((uintptr_t)dest <= (uintptr_t)src || + (uintptr_t)dest >= (uintptr_t)src + len) { + /* + * Start of destination doesn't overlap source, so just use + * memcpy(). + */ + return memcpy(dest, src, len); + } + + { + /* Need to copy from tail because there is overlap. */ + char *d = (char *)dest + len; + const char *s = (const char *)src + len; + uint32_t *dw; + const uint32_t *sw; + char *head; + char * const tail = (char *)dest; + /* Set 'body' to the last word boundary */ + uint32_t * const body = (uint32_t *)(((uintptr_t)tail+3) & ~3); + + if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { + /* Misaligned. no body, no tail. */ + head = tail; + } else { + /* Aligned */ + if ((uintptr_t)tail > ((uintptr_t)d & ~3)) + /* Shorter than the first word boundary */ + head = tail; + else + /* Set 'head' to the first word boundary */ + head = (char *)((uintptr_t)d & ~3); + } + + /* Copy head */ + while (d > head) + *(--d) = *(--s); + + /* Copy body */ + dw = (uint32_t *)d; + sw = (uint32_t *)s; + while (dw > body) + *(--dw) = *(--sw); + + /* Copy tail */ + d = (char *)dw; + s = (const char *)sw; + while (d > tail) + *(--d) = *(--s); + + return dest; + } +} + + +void reverse(void *dest, size_t len) +{ + int i; + uint8_t *start = dest; + uint8_t *end = start + len; + + for (i = 0; i < len / 2; ++i) { + uint8_t tmp = *start; + + *start++ = *--end; + *end = tmp; + } +} + + +__stdlib_compat int strncmp(const char *s1, const char *s2, size_t n) +{ + while (n--) { + if (*s1 != *s2) + return *s1 - *s2; + if (!*s1) + break; + s1++; + s2++; + + } + return 0; +} +#endif /* CONFIG_FIPS_BOUNDARY */ +/****************************************************************************/ + + __stdlib_compat size_t strnlen(const char *s, size_t maxlen) { size_t len = 0; @@ -247,20 +440,6 @@ __stdlib_compat int parse_bool(const char *s, int *dest) return 0; } -__stdlib_compat int memcmp(const void *s1, const void *s2, size_t len) -{ - const char *sa = s1; - const char *sb = s2; - - int diff = 0; - while (len-- > 0) { - diff = *(sa++) - *(sb++); - if (diff) - return diff; - } - - return 0; -} /* Constant-time memory comparison */ int safe_memcmp(const void *s1, const void *s2, size_t size) @@ -282,139 +461,6 @@ int safe_memcmp(const void *s1, const void *s2, size_t size) return result != 0; } -__stdlib_compat void *memcpy(void *dest, const void *src, size_t len) -{ - char *d = (char *)dest; - const char *s = (const char *)src; - uint32_t *dw; - const uint32_t *sw; - char *head; - char * const tail = (char *)dest + len; - /* Set 'body' to the last word boundary */ - uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3); - - if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { - /* Misaligned. no body, no tail. */ - head = tail; - } else { - /* Aligned */ - if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) - /* len is shorter than the first word boundary */ - head = tail; - else - /* Set 'head' to the first word boundary */ - head = (char *)(((uintptr_t)d + 3) & ~3); - } - - /* Copy head */ - while (d < head) - *(d++) = *(s++); - - /* Copy body */ - dw = (uint32_t *)d; - sw = (uint32_t *)s; - while (dw < body) - *(dw++) = *(sw++); - - /* Copy tail */ - d = (char *)dw; - s = (const char *)sw; - while (d < tail) - *(d++) = *(s++); - - return dest; -} - - -__stdlib_compat __visible void *memset(void *dest, int c, size_t len) -{ - char *d = (char *)dest; - uint32_t cccc; - uint32_t *dw; - char *head; - char * const tail = (char *)dest + len; - /* Set 'body' to the last word boundary */ - uint32_t * const body = (uint32_t *)((uintptr_t)tail & ~3); - - c &= 0xff; /* Clear upper bits before ORing below */ - cccc = c | (c << 8) | (c << 16) | (c << 24); - - if ((uintptr_t)tail < (((uintptr_t)d + 3) & ~3)) - /* len is shorter than the first word boundary */ - head = tail; - else - /* Set 'head' to the first word boundary */ - head = (char *)(((uintptr_t)d + 3) & ~3); - - /* Copy head */ - while (d < head) - *(d++) = c; - - /* Copy body */ - dw = (uint32_t *)d; - while (dw < body) - *(dw++) = cccc; - - /* Copy tail */ - d = (char *)dw; - while (d < tail) - *(d++) = c; - - return dest; -} - - -__stdlib_compat void *memmove(void *dest, const void *src, size_t len) -{ - if ((uintptr_t)dest <= (uintptr_t)src || - (uintptr_t)dest >= (uintptr_t)src + len) { - /* Start of destination doesn't overlap source, so just use - * memcpy(). */ - return memcpy(dest, src, len); - } else { - /* Need to copy from tail because there is overlap. */ - char *d = (char *)dest + len; - const char *s = (const char *)src + len; - uint32_t *dw; - const uint32_t *sw; - char *head; - char * const tail = (char *)dest; - /* Set 'body' to the last word boundary */ - uint32_t * const body = (uint32_t *)(((uintptr_t)tail+3) & ~3); - - if (((uintptr_t)dest & 3) != ((uintptr_t)src & 3)) { - /* Misaligned. no body, no tail. */ - head = tail; - } else { - /* Aligned */ - if ((uintptr_t)tail > ((uintptr_t)d & ~3)) - /* Shorter than the first word boundary */ - head = tail; - else - /* Set 'head' to the first word boundary */ - head = (char *)((uintptr_t)d & ~3); - } - - /* Copy head */ - while (d > head) - *(--d) = *(--s); - - /* Copy body */ - dw = (uint32_t *)d; - sw = (uint32_t *)s; - while (dw > body) - *(--dw) = *(--sw); - - /* Copy tail */ - d = (char *)dw; - s = (const char *)sw; - while (d > tail) - *(--d) = *(--s); - - return dest; - } -} - __stdlib_compat void *memchr(const void *buffer, int c, size_t n) { @@ -430,21 +476,6 @@ __stdlib_compat void *memchr(const void *buffer, int c, size_t n) } -void reverse(void *dest, size_t len) -{ - int i; - uint8_t *start = dest; - uint8_t *end = start + len; - - for (i = 0; i < len / 2; ++i) { - uint8_t tmp = *start; - - *start++ = *--end; - *end = tmp; - } -} - - __stdlib_compat char *strzcpy(char *dest, const char *src, int len) { char *d = dest; @@ -473,21 +504,6 @@ __stdlib_compat char *strncpy(char *dest, const char *src, size_t n) } -__stdlib_compat int strncmp(const char *s1, const char *s2, size_t n) -{ - while (n--) { - if (*s1 != *s2) - return *s1 - *s2; - if (!*s1) - break; - s1++; - s2++; - - } - return 0; -} - - int uint64divmod(uint64_t *n, int d) { uint64_t q = 0, mask; diff --git a/include/config.h b/include/config.h index b800904829..5bab6a1c08 100644 --- a/include/config.h +++ b/include/config.h @@ -1358,6 +1358,8 @@ * Use dcrypto in the board directory instead of chip/g. */ #undef CONFIG_DCRYPTO_BOARD +/* Build FIPS utils in the module */ +#undef CONFIG_FIPS_UTIL /* * This provides struct definitions and function declarations that can be * implemented by unit tests for testing code that depends on dcrypto. -- cgit v1.2.1