at the moment I am working on the kernel module of ccn-lite (http://www.ccn-lite.net/).
For that I need some security functionality (sha1 and public/private key authentificaton).
For the user-space I use the openssl library, but I cannot use a library in the kernel module.
It is also hard to pick the functions out of OpenSSL and add them to the kernel module, because most of them have dependencies to libc.
Is there any any security function in the linux kernel, which I could use?
Edit:
I can compute the hash function of the data received over ethernet:
struct scatterlist sg[1];
struct crypto_hash *tfm;
struct hash_desc desc;
tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC);
desc.tfm = tfm;
desc.flags = 0;
crypto_hash_init(&desc);
sg_init_table(sg, ARRAY_SIZE(sg));
sg_set_buf(&sg[0], input, length);
crypto_hash_digest(&desc, sg, length, md);
crypto_free_hash(tfm);
And now I want to verify the signature field of the data by using the function digsig_verify.
verified = digsig_verify(keyring, sig, sig_len, md, md_len);
As far as I can see, the second parameter is the signature, the third the len of the signature, the forth is the hash of the data and the last is the length of the hash.
The first field has the type "struct key", and should contain the publickey, which is needed to verify the signature?
How can I initialize this parameter i.e. how can I get the systems public key?
Is there also a way to sign a char* in the linux kernel?
The linux kernel comes with a bunch of crypto functions.
See: http://lxr.linux.no/#linux+v3.11/Documentation/crypto/
you could use ipc like netlink to send the data from kernel to user-space and let userspace openssl do the security implementation and revert back the data to the kernel.
Related
I want to spawn multiple user-space processes with each one processing packets from a single source (triple of (SRC-IP, DST-IP, DST-Port)).
Because there are going to pass a lot of packets through the AF-XDP kernel program and time is critical, I thought of a separate map in the kernel-program which is populated by a user-space program beforehand.
This map defines a mapping from the previously mentioned triple to an index which is then used in bpf_redirect_map(&xsks_map, index, 0) to send packets to a specific socket in user-space.
My initial idea was to just concatenate src-ip, destination-ip and destination port into a (32 + 32 + 16)-bit value.
Is it possible to define maps with such a large key-size? Which map would be the best fit for this problem? Furthermore, is it possible to fill the map from user-space?
A struct as a key
There are several types of maps that can be used with eBPF. Some of them are generic (hash maps, arrays, ...) and some are very specific (redirect maps, sockmaps, ...).
The case you describes sounds like a perfect use case for a hash maps. Such maps take a struct as a key, and another struct as a value. So you could have something like:
struct my_key {
uint32_t src_ip;
uint32_t dst_ip;
uint16_t dst_port;
};
... and use it as a key. The value, in your case, would be the index for the xskmap, i.e. a simple integer. Hash maps are efficient for retrieving a value from a given key (no linear search as for an array), so you get good performance with that.
Key size for hash maps
There are no specific restrictions for the size of the keys or the values, as long as the size holds on a 32-bit integer :) (Note that there may be size restrictions in the case of hardware offload).
Update from user space
It is perfectly doable to update a hash map from user space (some very specific map types may not allow it, though, but generic maps like are arrays or hash maps are entirely fine). You would do it:
From the command line, with bpftool,
From a C program, with the helpers from libbpf,
In your own language. In all three cases, the update itself is done through a call to the bpf() system call.
I have the following chardev defined:
.h
#define MAJOR_NUM 245
#define MINOR_NUM 0
#define IOCTL_MY_DEV1 _IOW(MAJOR_NUM, 0, unsigned long)
#define IOCTL_MY_DEV2 _IOW(MAJOR_NUM, 1, unsigned long)
#define IOCTL_MY_DEV3 _IOW(MAJOR_NUM, 2, unsigned long)
module .c
static long device_ioctl(
struct file* file,
unsigned int ioctl_num,
unsigned long ioctl_param)
{
...
}
static int device_open(struct inode* inode, struct file* file)
{
...
}
static int device_release(struct inode* inode, struct file* file)
{
...
}
struct file_operations Fops = {
.open=device_open,
.unlocked_ioctl= device_ioctl,
.release=device_release
};
static int __init my_dev_init(void)
{
register_chrdev(MAJOR_NUM, "MY_DEV", &Fops);
...
}
module_init(my_dev_init);
My user code
ioctl(fd, IOCTL_MY_DEV1, 1);
Always fails with same error: ENOTTY
Inappropriate ioctl for device
I've seen similar questions:
i.e
Linux kernel module - IOCTL usage returns ENOTTY
Linux Kernel Module/IOCTL: inappropriate ioctl for device
But their solutions didn't work for me
ENOTTY is issued by the kernel when your device driver has not registered a ioctl function to be called. I'm afraid your function is not well registered, probably because you have registered it in the .unlocked_ioctl field of the struct file_operations structure.
Probably you'll get a different result if you register it in the locked version of the function. The most probable cause is that the inode is locked for the ioctl call (as it should be, to avoid race conditions with simultaneous read or write operations to the same device)
Sorry, I have no access to the linux source tree for the proper name of the field to use, but for sure you'll be able to find it yourself.
NOTE
I observe that you have used macro _IOW, using the major number as the unique identifier. This is probably not what you want. First parameter for _IOW tries to ensure that ioctl calls get unique identifiers. There's no general way to acquire such identifiers, as this is an interface contract you create between application code and kernel code. So using the major number is bad practice, for two reasons:
Several devices (in linux, at least) can share the same major number (minor allocation in linux kernel allows this) making it possible for a clash between devices' ioctls.
In case you change the major number (you configure a kernel where that number is already allocated) you have to recompile all your user level software to cope with the new device ioctl ids (all of them change if you do this)
_IOW is a macro built a long time ago (long ago from the birth of linux kernel) that tried to solve this problem, by allowing you to select a different character for each driver (but not dependant of other kernel parameters, for the reasons pointed above) for a device having ioctl calls not clashing with another device driver's. The probability of such a clash is low, but when it happens you can lead to an incorrect machine state (you have issued a valid, working ioctl call to the wrong device)
Ancient unix (and early linux) kernels used different chars to build these calls, so, for example, tty driver used 'T' as parameter for the _IO* macros, scsi disks used 'S', etc.
I suggest you to select a random number (not appearing elsewhere in the linux kernel listings) and then use it in all your devices (probably there will be less drivers you write than drivers in the kernel) and select a different ioctl id for each ioctl call. Maintaining a local ioctl file with the registered ioctls this way is far better than trying to guess a value that works always.
Also, a look at the definition of the _IO* macros should be very illustrative :)
I want to know as to where IOCTL is defined. I want to flip the state of a GPIO pin from within the IOCTL function call. I am using Yocto linux.
The ioctl requests are defined per driver. For the new chardev GPIO this is defined in <linux/gpio.h>.
The logic these values are encoded is in <asm/ioctl.h>. Please note, that this is platform dependent (e.g. MIPS is different than x86 and x86_64).
If you are interested, here is the logic ported to rust: https://docs.rs/nix/0.11.0/src/nix/sys/ioctl/linux.rs.html
However in practice you shouldn't need to convert these request codes on your own. You would just include <linux/gpio.h> and then you can use the defined IOCTL request codes like GPIOHANDLE_GET_LINE_VALUES_IOCTL. Here are some example implementations: https://github.com/torvalds/linux/tree/master/tools/gpio
ioctl is a c-language kernel function declared in <sys/ioctl.h>. See the linux manual page.
Here's a copy of the upper portion:
NAME
ioctl - control device
SYNOPSIS
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
DESCRIPTION
The ioctl() function manipulates the underlying device parameters of
special files. In particular, many operating characteristics of
character special files (e.g., terminals) may be controlled with
ioctl() requests. The argument fd must be an open file descriptor.
The second argument is a device-dependent request code. The third
argument is an untyped pointer to memory. It's traditionally char
*argp (from the days before void * was valid C), and will be so named
for this discussion.
An ioctl() request has encoded in it whether the argument is an in
parameter or out parameter, and the size of the argument argp in
bytes. Macros and defines used in specifying an ioctl() request are
located in the file <sys/ioctl.h>.
Is there any method in OpenSSL which is an equivalent of Crypto++'s SecByteBlock?
Something that clears the memory before freeing it among other things of securing the memory block with sensitive information. Is there any way of securing the RSA struct in memory?
Is there any method in OpenSSL which is an equivalent of Crypto++'s SecByteBlock?
A SecByteBlock is a class that takes advantage of OOP by combining data with the operations to act on the data (lots of hand waiving). OpenSSL is a C library, and it does not have most of the goodies related to OOP.
In OpenSSL, you would use OPENSSL_cleanse. Here are some one-liner uses of it in OpenSSL:
$ grep -R cleanse * | grep -v doc
...
apps/apps.c: OPENSSL_cleanse(buff, (unsigned int)bufsiz);
apps/apps.c: OPENSSL_cleanse(buf, (unsigned int)bufsiz);
apps/apps.c: OPENSSL_cleanse(buf, (unsigned int)bufsiz);
apps/ca.c: OPENSSL_cleanse(key, strlen(key));
apps/dgst.c: OPENSSL_cleanse(buf, BUFSIZE);
apps/enc.c: OPENSSL_cleanse(str, SIZE);
apps/enc.c: OPENSSL_cleanse(str, strlen(str));
...
Is there any way of securing the RSA struct in memory?
RSA_free calls OPENSSL_cleanse internally. So the structure is zeroized when its discarded. According to the OpenSSL man page on RSA_new and RSA_free:
RSA_free() frees the RSA structure and its components. The key is erased before the memory is returned to the system.
But you should probably to define your requirements for "secure in memory." If your requirements include wrapping, then no, OpenSSL does not provide it. But neither does Crypto++.
I have seen that __iomem is used to store the return type of ioremap(), but I have used u32 in ARM architecture for it and it works well.
So what difference does __iomem make here? And in which circumstances should I use it exactly?
Lots of type casts are going to just "work well". However, this is not very strict. Nothing stops you from casting a u32 to a u32 * and dereference it, but this is not following the kernel API and is prone to errors.
__iomem is a cookie used by Sparse, a tool used to find possible coding faults in the kernel. If you don't compile your kernel code with Sparse enabled, __iomem will be ignored anyway.
Use Sparse by first installing it, and then adding C=1 to your make call. For example, when building a module, use:
make -C $KPATH M=$PWD C=1 modules
__iomem is defined like this:
# define __iomem __attribute__((noderef, address_space(2)))
Adding (and requiring) a cookie like __iomem for all I/O accesses is a way to be stricter and avoid programming errors. You don't want to read/write from/to I/O memory regions with absolute addresses because you're usually using virtual memory. Thus,
void __iomem *ioremap(phys_addr_t offset, unsigned long size);
is usually called to get the virtual address of an I/O physical address offset, for a specified length size in bytes. ioremap() returns a pointer with an __iomem cookie, so this may now be used with inline functions like readl()/writel() (although it's now preferable to use the more explicit macros ioread32()/iowrite32(), for example), which accept __iomem addresses.
Also, the noderef attribute is used by Sparse to make sure you don't dereference an __iomem pointer. Dereferencing should work on some architecture where the I/O is really memory-mapped, but other architectures use special instructions for accessing I/Os and in this case, dereferencing won't work.
Let's look at an example:
void *io = ioremap(42, 4);
Sparse is not happy:
warning: incorrect type in initializer (different address spaces)
expected void *io
got void [noderef] <asn:2>*
Or:
u32 __iomem* io = ioremap(42, 4);
pr_info("%x\n", *io);
Sparse is not happy either:
warning: dereference of noderef expression
In the last example, the first line is correct, because ioremap() returns its value to an __iomem variable. But then, we deference it, and we're not supposed to.
This makes Sparse happy:
void __iomem* io = ioremap(42, 4);
pr_info("%x\n", ioread32(io));
Bottom line: always use __iomem where it's required (as a return type or as a parameter type), and use Sparse to make sure you did so. Also: do not dereference an __iomem pointer.
Edit: Here's a great LWN article about the inception of __iomem and functions using it.
Simple, Straight and Short (S3) Explanation.
There is an article https://lwn.net/Articles/653585/ for more details.