/***************************************************************************** # * # Copyright 2019 AT&T Intellectual Property * # * # 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. * # * ******************************************************************************/ /* * Copyright (c) 2017 Lev Walkin . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include #include #include int asn_random_fill(const struct asn_TYPE_descriptor_s *td, void **struct_ptr, size_t length) { if(td && td->op->random_fill) { asn_random_fill_result_t res = td->op->random_fill(td, struct_ptr, 0, length); return (res.code == ARFILL_OK) ? 0 : -1; } else { return -1; } } static uintmax_t asn__intmax_range(intmax_t lb, intmax_t ub) { assert(lb <= ub); if((ub < 0) == (lb < 0)) { return ub - lb; } else if(lb < 0) { return 1 + ((uintmax_t)ub + (uintmax_t)-(lb + 1)); } else { assert(!"Unreachable"); return 0; } } intmax_t asn_random_between(intmax_t lb, intmax_t rb) { if(lb == rb) { return lb; } else { const uintmax_t intmax_max = ((~(uintmax_t)0) >> 1); uintmax_t range = asn__intmax_range(lb, rb); uintmax_t value = 0; uintmax_t got_entropy = 0; assert(RAND_MAX > 0xffffff); /* Seen 7ffffffd! */ assert(range < intmax_max); for(; got_entropy < range;) { got_entropy = (got_entropy << 24) | 0xffffff; value = (value << 24) | (random() % 0xffffff); } return lb + (intmax_t)(value % (range + 1)); } }