^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) }