Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2021 Google LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * This file can optionally be built into fips140.ko in order to support certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * types of testing that the FIPS lab has to do to evaluate the module.  It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * should not be included in production builds of the module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * We have to redefine inline to mean always_inline, so that _copy_to_user()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * gets inlined.  This is needed for it to be placed into the correct section.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * See fips140_copy_to_user().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * We also need to undefine BUILD_FIPS140_KO to allow the use of the code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * patching which copy_to_user() requires.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #undef inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define inline inline __attribute__((__always_inline__)) __gnu_inline \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)        __inline_maybe_unused notrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #undef BUILD_FIPS140_KO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "fips140-module.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "fips140-eval-testing-uapi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * This option allows deliberately failing the self-tests for a particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static char *fips140_fail_selftest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) module_param_named(fail_selftest, fips140_fail_selftest, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /* This option allows deliberately failing the integrity check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static bool fips140_fail_integrity_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) module_param_named(fail_integrity_check, fips140_fail_integrity_check, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static dev_t fips140_devnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static struct cdev fips140_cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* Inject a self-test failure (via corrupting the result) if requested. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) void fips140_inject_selftest_failure(const char *impl, u8 *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (fips140_fail_selftest && strcmp(impl, fips140_fail_selftest) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		result[0] ^= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Inject an integrity check failure (via corrupting the text) if requested. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) void fips140_inject_integrity_failure(u8 *textcopy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	if (fips140_fail_integrity_check)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		textcopy[0] ^= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static long fips140_ioctl_is_approved_service(unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	const char *service_name = strndup_user((const char __user *)arg, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	if (IS_ERR(service_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		return PTR_ERR(service_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	ret = fips140_is_approved_service(service_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	kfree(service_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * Code in fips140.ko is covered by an integrity check by default, and this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * check breaks if copy_to_user() is called.  This is because copy_to_user() is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * an inline function that relies on code patching.  However, since this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * "evaluation testing" code which isn't included in the production builds of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * fips140.ko, it's acceptable to just exclude it from the integrity check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static noinline unsigned long __section("text.._fips140_unchecked")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) fips140_copy_to_user(void __user *to, const void *from, unsigned long n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return copy_to_user(to, from, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static long fips140_ioctl_module_version(unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	const char *version = fips140_module_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	size_t len = strlen(version) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (len > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (fips140_copy_to_user((void __user *)arg, version, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static long fips140_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			  unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	case FIPS140_IOCTL_IS_APPROVED_SERVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return fips140_ioctl_is_approved_service(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	case FIPS140_IOCTL_MODULE_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return fips140_ioctl_module_version(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static const struct file_operations fips140_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.unlocked_ioctl = fips140_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bool fips140_eval_testing_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (alloc_chrdev_region(&fips140_devnum, 1, 1, "fips140") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		pr_err("failed to allocate device number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	cdev_init(&fips140_cdev, &fips140_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (cdev_add(&fips140_cdev, fips140_devnum, 1) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		pr_err("failed to add fips140 character device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }