Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting cryptographically secure random numbers in C++ on iOS

I'm working on an iOS app that is written in Objective-C and C++. In the C++ part, I need cryptographically secure random numbers.

  1. As I understand the iOS security model, there is no way to access /dev/random directly. Is that correct?

  2. The official way to get secure random numbers is SecRandomCopyBytes. Sadly, this is an Objective-C interface. Is there a way to use this interface from C++, ideally without resorting to Objective-C++?

There's also arc4random, but I'm reluctant to use anything that's based on RC4 nowadays...

like image 574
Daniel Seither Avatar asked Sep 24 '15 17:09

Daniel Seither


2 Answers

One way to get cryptographically secure random numbers on any "C" based language including Swift is the "C" arc4random functions.

For random number integers (u_int32_t) use arc4random() and arc4random_uniform().

For a range of random bytes use the arc4random_buf() function fills the buffer of length nbytes with ARC4-derived random data.

RC4 is a part of arc4random, the key is the continual seeding:

The arc4random() function provides a high quality 32-bit pseudo-random number very quickly. arc4random() seeds itself on a regular basis from the kernel strong random number subsystem described in random(4).

The arc4random source code is available. Note that it is seeded by (stir) partially by reading from /dev/urandom. Care is taken to avoid well known RC4 weaknesses. Additionally the time is included when initializing the state making it impossible to regenerate the same random sequence twice.

Note: While the docs state that /dev/random blocks on lack of entropy this may not be true on OS X and it may be more like /dev/urandom.

like image 80
zaph Avatar answered Sep 22 '22 13:09

zaph


The official way to get secure random numbers is SecRandomCopyBytes. Sadly, this is an Objective-C interface. Is there a way to use this interface from C++, ideally without resorting to Objective-C++?

SecRandomCopyBytes is a C API. There is no problem using it from C++.

Here's a full example. No ObjC++ required, even using fancy vector and whatnot to show it's all C++. Obviously you could just use malloc.

#include <iostream>
#include <Security/Security.h>
#include <vector>

int main(int argc, const char * argv[]) {
    const int length = 20;
    std::vector<uint8_t> randomBytes(length, 0);

    int rc = SecRandomCopyBytes(kSecRandomDefault, randomBytes.size(), &(randomBytes[0]));
    if (rc != 0) {
        std::cout << "Failed: " << rc << std::endl;
        return 1;
    }

    for (int i = 0; i < randomBytes.size(); ++i) {
        std::cout << std::hex << +randomBytes[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}
like image 44
Rob Napier Avatar answered Sep 25 '22 13:09

Rob Napier