How to use /dev/random or urandom in C?

前端 未结 5 1994
面向向阳花
面向向阳花 2020-11-28 02:37

I want to use /dev/random or /dev/urandom in C. How can I do it? I don\'t know how can I handle them in C, if someone knows please tell me how. Tha

5条回答
  •  感动是毒
    2020-11-28 02:54

    zneak's answer covers it simply, however the reality is more complicated than that. For example, you need to consider whether /dev/{u}random really is the random number device in the first place. Such a scenario may occur if your machine has been compromised and the devices replaced with symlinks to /dev/zero or a sparse file. If this happens, the random stream is now completely predictable.

    The simplest way (at least on Linux and FreeBSD) is to perform an ioctl call on the device that will only succeed if the device is a random generator:

    int data;
    int result = ioctl(fd, RNDGETENTCNT, &data); 
    // Upon success data now contains amount of entropy available in bits
    

    If this is performed before the first read of the random device, then there's a fair bet that you've got the random device. So @zneak's answer can better be extended to be:

    int randomData = open("/dev/random", O_RDONLY);
    int entropy;
    int result = ioctl(randomData, RNDGETENTCNT, &entropy);
    
    if (!result) {
       // Error - /dev/random isn't actually a random device
       return;
    }
    
    if (entropy < sizeof(int) * 8) {
        // Error - there's not enough bits of entropy in the random device to fill the buffer
        return;
    }
    
    int myRandomInteger;
    size_t randomDataLen = 0;
    while (randomDataLen < sizeof myRandomInteger)
    {
        ssize_t result = read(randomData, ((char*)&myRandomInteger) + randomDataLen, (sizeof myRandomInteger) - randomDataLen);
        if (result < 0)
        {
            // error, unable to read /dev/random 
        }
        randomDataLen += result;
    }
    close(randomData);
    

    The Insane Coding blog covered this, and other pitfalls not so long ago; I strongly recommend reading the entire article. I have to give credit to their where this solution was pulled from.

    Edited to add (2014-07-25)...
    Co-incidentally, I read last night that as part of the LibReSSL effort, Linux appears to be getting a GetRandom() syscall. As at time of writing, there's no word of when it will be available in a kernel general release. However this would be the preferred interface to get cryptographically secure random data as it removes all pitfalls that access via files provides. See also the LibReSSL possible implementation.

提交回复
热议问题