diff --git a/kernel/Makefile b/kernel/Makefile index dce5c0e2..789d3b89 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -95,6 +95,7 @@ fs/full.o \ fsfunc.o \ fs/kram.o \ fs/null.o \ +fs/random.o \ fs/user.o \ fs/util.o \ fs/zero.o \ diff --git a/kernel/fs/random.cpp b/kernel/fs/random.cpp new file mode 100644 index 00000000..fc17b6e1 --- /dev/null +++ b/kernel/fs/random.cpp @@ -0,0 +1,106 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2015. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + fs/random.cpp + Random device. + +*******************************************************************************/ + +#include + +#include +#include +#include + +#include + +#include +#include + +#include "random.h" + +namespace Sortix { + +DevRandom::DevRandom(dev_t dev, ino_t ino, uid_t owner, gid_t group, mode_t mode) +{ + inode_type = INODE_TYPE_STREAM; + if ( !dev ) + dev = (dev_t) this; + if ( !ino ) + ino = (ino_t) this; + this->type = S_IFCHR; + this->stat_uid = owner; + this->stat_gid = group; + this->stat_mode = (mode & S_SETABLE) | this->type; + this->stat_size = 0; + this->stat_blksize = 1; + this->dev = dev; + this->ino = ino; +} + +DevRandom::~DevRandom() +{ +} + +int DevRandom::truncate(ioctx_t* /*ctx*/, off_t /*length*/) +{ + return 0; +} + +off_t DevRandom::lseek(ioctx_t* /*ctx*/, off_t offset, int /*whence*/) +{ + return offset; +} + +ssize_t DevRandom::read(ioctx_t* ctx, uint8_t* buf, size_t count) +{ + size_t sofar = 0; + while ( count ) + { + unsigned char buffer[512]; + size_t amount = count; + if ( sizeof(buffer) < amount ) + amount = sizeof(buffer); + arc4random_buf(buffer, amount); + if ( !ctx->copy_to_dest(buf, buffer, amount) ) + return sofar ? sofar : -1; + buf += amount; + count -= amount; + sofar += amount; + } + return (ssize_t) sofar; +} + +ssize_t DevRandom::pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t /*off*/) +{ + return read(ctx, buf, count); +} + +ssize_t DevRandom::write(ioctx_t* /*ctx*/, const uint8_t* /*buf*/, size_t count) +{ + return count; +} + +ssize_t DevRandom::pwrite(ioctx_t* /*ctx*/, const uint8_t* /*buf*/, size_t count, + off_t /*off*/) +{ + return count; +} + +} // namespace Sortix diff --git a/kernel/fs/random.h b/kernel/fs/random.h new file mode 100644 index 00000000..fa230018 --- /dev/null +++ b/kernel/fs/random.h @@ -0,0 +1,48 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2015. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + fs/random.h + Random device. + +*******************************************************************************/ + +#ifndef SORTIX_FS_RANDOM_H +#define SORTIX_FS_RANDOM_H + +#include + +namespace Sortix { + +class DevRandom : public AbstractInode +{ +public: + DevRandom(dev_t dev, ino_t ino, uid_t owner, gid_t group, mode_t mode); + virtual ~DevRandom(); + virtual int truncate(ioctx_t* ctx, off_t length); + virtual off_t lseek(ioctx_t* ctx, off_t offset, int whence); + virtual ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count); + virtual ssize_t pread(ioctx_t* ctx, uint8_t* buf, size_t count, off_t off); + virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count); + virtual ssize_t pwrite(ioctx_t* ctx, const uint8_t* buf, size_t count, + off_t off); +}; + +} // namespace Sortix + +#endif diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index e6488930..65c21945 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -73,6 +73,7 @@ #include "fs/full.h" #include "fs/kram.h" #include "fs/null.h" +#include "fs/random.h" #include "fs/zero.h" #include "gpu/bga/bga.h" #include "initrd.h" @@ -463,6 +464,16 @@ static void BootThread(void* /*user*/) if ( LinkInodeInDir(&ctx, slashdev, "full", full_device) != 0 ) Panic("Unable to link /dev/full to the full device."); + // Register the random device as /dev/random. + Ref random_device(new DevRandom(slashdev->dev, (ino_t) 0, (uid_t) 0, + (gid_t) 0, (mode_t) 0666)); + if ( !random_device ) + Panic("Could not allocate a random device"); + if ( LinkInodeInDir(&ctx, slashdev, "random", random_device) != 0 ) + Panic("Unable to link /dev/random to the random device."); + if ( LinkInodeInDir(&ctx, slashdev, "urandom", random_device) != 0 ) + Panic("Unable to link /dev/urandom to the random device."); + // Initialize the COM ports. COM::Init("/dev", slashdev);