| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* Diffie-Hellman Key Agreement Method [RFC2631] |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (c) 2016, Intel Corporation |
|---|
| 4 | 5 | * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #include <linux/module.h> |
|---|
| 13 | 9 | #include <crypto/internal/kpp.h> |
|---|
| 14 | 10 | #include <crypto/kpp.h> |
|---|
| 15 | 11 | #include <crypto/dh.h> |
|---|
| 12 | +#include <linux/fips.h> |
|---|
| 16 | 13 | #include <linux/mpi.h> |
|---|
| 17 | 14 | |
|---|
| 18 | 15 | struct dh_ctx { |
|---|
| .. | .. |
|---|
| 183 | 180 | if (ret) |
|---|
| 184 | 181 | goto err_free_base; |
|---|
| 185 | 182 | |
|---|
| 183 | + if (fips_enabled) { |
|---|
| 184 | + /* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */ |
|---|
| 185 | + if (req->src) { |
|---|
| 186 | + MPI pone; |
|---|
| 187 | + |
|---|
| 188 | + /* z <= 1 */ |
|---|
| 189 | + if (mpi_cmp_ui(val, 1) < 1) { |
|---|
| 190 | + ret = -EBADMSG; |
|---|
| 191 | + goto err_free_base; |
|---|
| 192 | + } |
|---|
| 193 | + |
|---|
| 194 | + /* z == p - 1 */ |
|---|
| 195 | + pone = mpi_alloc(0); |
|---|
| 196 | + |
|---|
| 197 | + if (!pone) { |
|---|
| 198 | + ret = -ENOMEM; |
|---|
| 199 | + goto err_free_base; |
|---|
| 200 | + } |
|---|
| 201 | + |
|---|
| 202 | + ret = mpi_sub_ui(pone, ctx->p, 1); |
|---|
| 203 | + if (!ret && !mpi_cmp(pone, val)) |
|---|
| 204 | + ret = -EBADMSG; |
|---|
| 205 | + |
|---|
| 206 | + mpi_free(pone); |
|---|
| 207 | + |
|---|
| 208 | + if (ret) |
|---|
| 209 | + goto err_free_base; |
|---|
| 210 | + |
|---|
| 211 | + /* SP800-56A rev 3 5.6.2.1.3 key check */ |
|---|
| 212 | + } else { |
|---|
| 213 | + if (dh_is_pubkey_valid(ctx, val)) { |
|---|
| 214 | + ret = -EAGAIN; |
|---|
| 215 | + goto err_free_val; |
|---|
| 216 | + } |
|---|
| 217 | + } |
|---|
| 218 | + } |
|---|
| 219 | + |
|---|
| 186 | 220 | ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign); |
|---|
| 187 | 221 | if (ret) |
|---|
| 188 | 222 | goto err_free_base; |
|---|
| .. | .. |
|---|
| 236 | 270 | crypto_unregister_kpp(&dh); |
|---|
| 237 | 271 | } |
|---|
| 238 | 272 | |
|---|
| 239 | | -module_init(dh_init); |
|---|
| 273 | +subsys_initcall(dh_init); |
|---|
| 240 | 274 | module_exit(dh_exit); |
|---|
| 241 | 275 | MODULE_ALIAS_CRYPTO("dh"); |
|---|
| 242 | 276 | MODULE_LICENSE("GPL"); |
|---|