diff options
Diffstat (limited to 'src/sbefw/core/sbeSecurity.C')
-rw-r--r-- | src/sbefw/core/sbeSecurity.C | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/sbefw/core/sbeSecurity.C b/src/sbefw/core/sbeSecurity.C new file mode 100644 index 00000000..3e0090df --- /dev/null +++ b/src/sbefw/core/sbeSecurity.C @@ -0,0 +1,157 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/sbefw/core/sbeSecurity.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "sbeSecurity.H" +#include "sbetrace.H" +#include "sbeglobals.H" + +#include "sbeSecurityGen.H" + +namespace SBE_SECURITY +{ + +// Figure out at compile time, the number of shifts required for the mask +constexpr uint32_t get_shift_len(uint32_t mask, uint8_t shifts = 0) +{ + return ((mask>>shifts) & 0x01) ? (shifts) : (get_shift_len(mask, ++shifts)); +} + +template <typename Func> +map_t<bool, int32_t> binary_search( + const uint32_t search_key, + range_t<int32_t> x_range, + Func get_element) +{ + map_t<bool, int32_t> ret = {false, 0}; // found=false + + while((x_range.start <= x_range.end) && + (ret.key == false)) + { + int32_t midpoint = (x_range.start + x_range.end) / 2; + SBE_DEBUG("binary_search : midpoint[0x%08x]", + midpoint); + uint32_t ele = get_element(midpoint); + SBE_DEBUG("binary_search : search_key[0x%08x] ele[0x%08x]", + search_key, + ele); + if(search_key == ele) + { + ret.key = true; + ret.value = midpoint; + } + else if(search_key < ele) + { + x_range.end = midpoint - 1; + } + else + { + x_range.start = midpoint + 1; + } + SBE_DEBUG("binary_search : x_range.start[0x%08x] x_range.end[0x%08x]", + x_range.start, + x_range.end); + } + SBE_DEBUG("binary_search : ret[%d]",ret.key); + return ret; +} + +template <typename M1_T, typename M1_U, + typename M2_T, typename M2_U, + typename T3> +bool _is_present(const table< map_t< range_t<M1_T>, M1_U > > &table1, + const table< map_t<M2_T, M2_U> > &table2, + const table< T3 > &table3, + const uint32_t i_addr) +{ +#define SBE_FUNC "SBE_SECURITY::_is_present" + SBE_ENTER(SBE_FUNC); + for(size_t i = 0; i < table1.size; i++) + { + uint32_t search_key = (i_addr & table1.mask) >> get_shift_len(table1.mask); + if((table1.table[i].key.start <= search_key) && + (table1.table[i].key.end >= search_key)) + { + SBE_DEBUG(SBE_FUNC" table1:found key[0x%x] table index[%d]", + search_key, i); + // Found the range where key might belong to + search_key = (i_addr & table2.mask) >> get_shift_len(table2.mask); + range_t<int32_t> search_range = {}; + search_range.start = i ? table1.table[i-1].value : 0; + search_range.end = table1.table[i].value - 1; + map_t<bool, int32_t> search_result = + binary_search( + search_key, + search_range, + [&table2](int32_t midpoint) -> uint32_t { + return table2.table[midpoint].key; + }); + if(search_result.key == true) + { + SBE_DEBUG(SBE_FUNC" table2:found key[0x%x] table index[%d]", + search_key, + search_result.value); + // Found the key + search_range.start = (search_result.value ? + table2.table[search_result.value-1].value : 0); + search_range.end = + table2.table[search_result.value].value - 1; + search_key = (i_addr & table3.mask) >> + get_shift_len(table3.mask); + search_result = binary_search( + search_key, + search_range, + [&table3](int32_t midpoint) -> uint32_t { + return table3.table[midpoint]; + }); + if(search_result.key == true) + { + SBE_DEBUG(SBE_FUNC" table3:found key[0x%x] table index[%d]", + search_key, + search_result.value); + // Found the number + return true; + } + } + } + } + SBE_EXIT(SBE_FUNC); + return false; +#undef SBE_FUNC +} + +bool isAllowed(const uint32_t i_addr, accessType type) +{ + bool ret = true; + if(SBE_GLOBAL->sbeFWSecurityEnabled) + { + if(type == WRITE) + ret = WHITELIST::isPresent(i_addr); + else if(type == READ) + ret = !BLACKLIST::isPresent(i_addr); + SBE_INFO("SBE_SECURITY access[%d] allowed[%d] addr[0x%08x]", + type, ret, i_addr); + } + return ret; +} + +} // namespace SBE_SECURITY |