diff options
Diffstat (limited to 'board/cr50/dcrypto/util.c')
-rw-r--r-- | board/cr50/dcrypto/util.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/board/cr50/dcrypto/util.c b/board/cr50/dcrypto/util.c new file mode 100644 index 0000000000..08167bd9c5 --- /dev/null +++ b/board/cr50/dcrypto/util.c @@ -0,0 +1,205 @@ +/* Copyright 2021 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Utility functions for Chrome EC within the FIPS boundary */ + +#include "common.h" +#include "console.h" +#include "util.h" + +__stdlib_compat size_t strlen(const char *s) +{ + int len = 0; + + while (*s++) + len++; + + return len; +} + + +__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; +} |