154e04708SPascal Brand /* 254e04708SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 354e04708SPascal Brand * All rights reserved. 454e04708SPascal Brand * 554e04708SPascal Brand * Redistribution and use in source and binary forms, with or without 654e04708SPascal Brand * modification, are permitted provided that the following conditions are met: 754e04708SPascal Brand * 854e04708SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 954e04708SPascal Brand * this list of conditions and the following disclaimer. 1054e04708SPascal Brand * 1154e04708SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 1254e04708SPascal Brand * this list of conditions and the following disclaimer in the documentation 1354e04708SPascal Brand * and/or other materials provided with the distribution. 1454e04708SPascal Brand * 1554e04708SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1654e04708SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1754e04708SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1854e04708SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1954e04708SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2054e04708SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2154e04708SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2254e04708SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2354e04708SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2454e04708SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2554e04708SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 2654e04708SPascal Brand */ 2754e04708SPascal Brand 2854e04708SPascal Brand #include <kernel/tee_common.h> 2954e04708SPascal Brand #include <kernel/chip_services.h> 3054e04708SPascal Brand #include <kernel/tee_misc.h> 3154e04708SPascal Brand #include <mm/core_memprot.h> 3254e04708SPascal Brand #include <mm/tee_mmu_defs.h> 3354e04708SPascal Brand 3454e04708SPascal Brand 3554e04708SPascal Brand #include <kernel/tee_common_otp.h> 3654e04708SPascal Brand #include <kernel/tee_core_trace.h> 3754e04708SPascal Brand 3854e04708SPascal Brand static uint8_t tee_b2hs_add_base(uint8_t in) 3954e04708SPascal Brand { 4054e04708SPascal Brand if (in > 9) 4154e04708SPascal Brand return in + 55; 4254e04708SPascal Brand else 4354e04708SPascal Brand return in + 48; 4454e04708SPascal Brand } 4554e04708SPascal Brand 4654e04708SPascal Brand static int tee_hs2b_rem_base(uint8_t in, uint8_t *out) 4754e04708SPascal Brand { 4854e04708SPascal Brand if (in < 48 || in > 70 || (in > 57 && in < 65)) 4954e04708SPascal Brand return -1; 5054e04708SPascal Brand 5154e04708SPascal Brand if (in < 58) 5254e04708SPascal Brand *out = in - 48; 5354e04708SPascal Brand else 5454e04708SPascal Brand *out = in - 55; 5554e04708SPascal Brand 5654e04708SPascal Brand return 0; 5754e04708SPascal Brand } 5854e04708SPascal Brand 5954e04708SPascal Brand uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen) 6054e04708SPascal Brand { 6154e04708SPascal Brand uint32_t i = 0; 6254e04708SPascal Brand 6354e04708SPascal Brand if (blen * 2 + 1 > hslen) 6454e04708SPascal Brand return 0; 6554e04708SPascal Brand 6654e04708SPascal Brand for (; i < blen; i++) { 6754e04708SPascal Brand hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf); 6854e04708SPascal Brand hs[i * 2] = tee_b2hs_add_base(b[i] >> 4); 6954e04708SPascal Brand } 7054e04708SPascal Brand hs[blen * 2] = 0; 7154e04708SPascal Brand 7254e04708SPascal Brand return blen * 2; 7354e04708SPascal Brand } 7454e04708SPascal Brand 7554e04708SPascal Brand uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen) 7654e04708SPascal Brand { 7754e04708SPascal Brand uint32_t i = 0; 7854e04708SPascal Brand uint32_t len = TEE_HS2B_BBUF_SIZE(hslen); 7954e04708SPascal Brand uint8_t hi; 8054e04708SPascal Brand uint8_t lo; 8154e04708SPascal Brand 8254e04708SPascal Brand if (len > blen) 8354e04708SPascal Brand return 0; 8454e04708SPascal Brand 8554e04708SPascal Brand for (; i < len; i++) { 8654e04708SPascal Brand if (tee_hs2b_rem_base(hs[i * 2], &hi)) 8754e04708SPascal Brand return 0; 8854e04708SPascal Brand if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo)) 8954e04708SPascal Brand return 0; 9054e04708SPascal Brand b[i] = (hi << 4) + lo; 9154e04708SPascal Brand } 9254e04708SPascal Brand 9354e04708SPascal Brand return len; 9454e04708SPascal Brand } 95*106d8aa6SPascal Brand 96*106d8aa6SPascal Brand static bool is_valid_conf_and_notnull_size( 97*106d8aa6SPascal Brand vaddr_t b, size_t bl, vaddr_t a, size_t al) 98*106d8aa6SPascal Brand { 99*106d8aa6SPascal Brand /* invalid config return false */ 100*106d8aa6SPascal Brand if ((b + bl < b) || (a + al < a)) 101*106d8aa6SPascal Brand return false; 102*106d8aa6SPascal Brand /* null sized areas are never inside / outside / overlap */ 103*106d8aa6SPascal Brand if (!bl || !al) 104*106d8aa6SPascal Brand return false; 105*106d8aa6SPascal Brand return true; 106*106d8aa6SPascal Brand } 107*106d8aa6SPascal Brand 108*106d8aa6SPascal Brand /* Returns true when buffer 'b' is fully contained in area 'a' */ 109*106d8aa6SPascal Brand bool _core_is_buffer_inside(vaddr_t b, size_t bl, vaddr_t a, size_t al) 110*106d8aa6SPascal Brand { 111*106d8aa6SPascal Brand /* invalid config or "null size" return false */ 112*106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 113*106d8aa6SPascal Brand return false; 114*106d8aa6SPascal Brand 115*106d8aa6SPascal Brand if ((b >= a) && (b + bl <= a + al)) 116*106d8aa6SPascal Brand return true; 117*106d8aa6SPascal Brand return false; 118*106d8aa6SPascal Brand } 119*106d8aa6SPascal Brand 120*106d8aa6SPascal Brand /* Returns true when buffer 'b' is fully contained in area 'a' */ 121*106d8aa6SPascal Brand bool _core_is_buffer_outside(vaddr_t b, size_t bl, vaddr_t a, size_t al) 122*106d8aa6SPascal Brand { 123*106d8aa6SPascal Brand /* invalid config or "null size" return false */ 124*106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 125*106d8aa6SPascal Brand return false; 126*106d8aa6SPascal Brand 127*106d8aa6SPascal Brand if ((b + bl <= a) || (b >= a + al)) 128*106d8aa6SPascal Brand return true; 129*106d8aa6SPascal Brand return false; 130*106d8aa6SPascal Brand } 131*106d8aa6SPascal Brand 132*106d8aa6SPascal Brand /* Returns true when buffer 'b' intersects area 'a' */ 133*106d8aa6SPascal Brand bool _core_is_buffer_intersect(vaddr_t b, size_t bl, vaddr_t a, size_t al) 134*106d8aa6SPascal Brand { 135*106d8aa6SPascal Brand /* invalid config or "null size" return false */ 136*106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 137*106d8aa6SPascal Brand return false; 138*106d8aa6SPascal Brand 139*106d8aa6SPascal Brand if ((b + bl <= a) || (b >= a + al)) 140*106d8aa6SPascal Brand return false; 141*106d8aa6SPascal Brand return true; 142*106d8aa6SPascal Brand } 143