michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: /** michael@0: * platGenerateCryptoRand michael@0: * @brief Generates a Random Number michael@0: * michael@0: * Generate crypto graphically random number for a desired length. michael@0: * The function uses "secd" 's provided API. The random bytes are michael@0: * generated by "secd" which runs as another process. The function michael@0: * will be much slower than the cpr_rand(). This function should be michael@0: * used when good random number is needed such as random number that michael@0: * to be used for SRTP key for an example. michael@0: * michael@0: * @param[in] buf - pointer to the buffer to store the result of random michael@0: * bytes requested. michael@0: * @param[in] len - pointer to the length of the desired random bytes. michael@0: * When calling the function, the integer's value michael@0: * should be set to the desired number of random michael@0: * bytes ('buf' should be of at least this size). michael@0: * upon success, its value will be set to the michael@0: * actual number of random bytes being returned. michael@0: * (realistically, there is a maximum number of michael@0: * random bytes that can be returned at a time. michael@0: * if the caller request more than that, the michael@0: * 'len' will indicate how many bytes are actually being michael@0: * returned) on failure, its value will be set to 0. michael@0: * michael@0: * @return michael@0: * 1 - success. michael@0: * 0 - fail. michael@0: * michael@0: * @note This function MUST BE REWRITTEN BY THE VENDORS michael@0: * @note The intent of this function is to generate a cryptographically strong michael@0: * random number. Vendors can map this to HandyIron or OpenSSL random number michael@0: * generation functions. michael@0: */ michael@0: int michael@0: platGenerateCryptoRand(uint8_t *buf, int *len) michael@0: { michael@0: int fd; michael@0: int rc = 0; michael@0: ssize_t s; michael@0: michael@0: if ((fd = open("/dev/urandom", O_RDONLY)) == -1) { michael@0: syslog(LOG_ERR, "Failed to open prng driver"); michael@0: return 0; michael@0: } michael@0: michael@0: /* michael@0: * Try to read the given amount of bytes from the PRNG device. We do not michael@0: * handle short reads but just return the number of bytes read from the michael@0: * device. The caller has to manage this. michael@0: * E.g. gsmsdp_generate_key() in core/gsm/gsm_sdp_crypto.c michael@0: */ michael@0: s = read(fd, buf, (size_t) *len); michael@0: michael@0: if (s > 0) { michael@0: *len = s; michael@0: rc = 1; /* Success */ michael@0: } else { michael@0: *len = 0; michael@0: rc = 0; /* Failure */ michael@0: } michael@0: michael@0: (void) close(fd); michael@0: return rc; michael@0: } michael@0: