diff options
91 files changed, 1924 insertions, 1365 deletions
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index 0a378a88217a..bb0f9a135e21 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy | |||
@@ -27,6 +27,7 @@ Description: | |||
27 | 27 | ||
28 | base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] | 28 | base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] |
29 | [FIRMWARE_CHECK] | 29 | [FIRMWARE_CHECK] |
30 | [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] | ||
30 | mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] | 31 | mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] |
31 | [[^]MAY_EXEC] | 32 | [[^]MAY_EXEC] |
32 | fsmagic:= hex value | 33 | fsmagic:= hex value |
diff --git a/MAINTAINERS b/MAINTAINERS index 99bd725affc6..5e6f388f3c3e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11126,8 +11126,8 @@ M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | |||
11126 | R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | 11126 | R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> |
11127 | W: http://tpmdd.sourceforge.net | 11127 | W: http://tpmdd.sourceforge.net |
11128 | L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) | 11128 | L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) |
11129 | Q: git git://github.com/PeterHuewe/linux-tpmdd.git | 11129 | Q: https://patchwork.kernel.org/project/tpmdd-devel/list/ |
11130 | T: git https://github.com/PeterHuewe/linux-tpmdd | 11130 | T: git git://git.infradead.org/users/jjs/linux-tpmdd.git |
11131 | S: Maintained | 11131 | S: Maintained |
11132 | F: drivers/char/tpm/ | 11132 | F: drivers/char/tpm/ |
11133 | 11133 | ||
diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 18c311ae1113..0b9211b2b73b 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig | |||
@@ -166,7 +166,6 @@ CONFIG_DEBUG_USER=y | |||
166 | CONFIG_DEBUG_ERRORS=y | 166 | CONFIG_DEBUG_ERRORS=y |
167 | CONFIG_DEBUG_LL=y | 167 | CONFIG_DEBUG_LL=y |
168 | CONFIG_KEYS=y | 168 | CONFIG_KEYS=y |
169 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
170 | CONFIG_SECURITY=y | 169 | CONFIG_SECURITY=y |
171 | CONFIG_CRYPTO_PCBC=m | 170 | CONFIG_CRYPTO_PCBC=m |
172 | CONFIG_CRYPTO_SHA1=m | 171 | CONFIG_CRYPTO_SHA1=m |
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig index 4fa94a1f115b..652b7bd9e544 100644 --- a/arch/arm/configs/iop13xx_defconfig +++ b/arch/arm/configs/iop13xx_defconfig | |||
@@ -95,7 +95,6 @@ CONFIG_PARTITION_ADVANCED=y | |||
95 | CONFIG_NLS=y | 95 | CONFIG_NLS=y |
96 | CONFIG_DEBUG_USER=y | 96 | CONFIG_DEBUG_USER=y |
97 | CONFIG_KEYS=y | 97 | CONFIG_KEYS=y |
98 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
99 | CONFIG_CRYPTO_NULL=y | 98 | CONFIG_CRYPTO_NULL=y |
100 | CONFIG_CRYPTO_LRW=y | 99 | CONFIG_CRYPTO_LRW=y |
101 | CONFIG_CRYPTO_PCBC=m | 100 | CONFIG_CRYPTO_PCBC=m |
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index c3058da631da..aa3af0a6b8f7 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig | |||
@@ -108,7 +108,6 @@ CONFIG_DEBUG_USER=y | |||
108 | CONFIG_DEBUG_LL=y | 108 | CONFIG_DEBUG_LL=y |
109 | CONFIG_DEBUG_LL_UART_8250=y | 109 | CONFIG_DEBUG_LL_UART_8250=y |
110 | CONFIG_KEYS=y | 110 | CONFIG_KEYS=y |
111 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
112 | CONFIG_CRYPTO_NULL=y | 111 | CONFIG_CRYPTO_NULL=y |
113 | CONFIG_CRYPTO_LRW=y | 112 | CONFIG_CRYPTO_LRW=y |
114 | CONFIG_CRYPTO_PCBC=m | 113 | CONFIG_CRYPTO_PCBC=m |
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 4bc870028035..0ada29d568ec 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig | |||
@@ -214,7 +214,6 @@ CONFIG_MAGIC_SYSRQ=y | |||
214 | CONFIG_DEBUG_FS=y | 214 | CONFIG_DEBUG_FS=y |
215 | CONFIG_DEBUG_USER=y | 215 | CONFIG_DEBUG_USER=y |
216 | CONFIG_KEYS=y | 216 | CONFIG_KEYS=y |
217 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
218 | CONFIG_SECURITY=y | 217 | CONFIG_SECURITY=y |
219 | CONFIG_CRYPTO_PCBC=m | 218 | CONFIG_CRYPTO_PCBC=m |
220 | CONFIG_CRYPTO_SHA256=m | 219 | CONFIG_CRYPTO_SHA256=m |
diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig index e2f6543b91e7..dc5dd5b69fde 100644 --- a/arch/microblaze/configs/mmu_defconfig +++ b/arch/microblaze/configs/mmu_defconfig | |||
@@ -87,5 +87,4 @@ CONFIG_KGDB_KDB=y | |||
87 | CONFIG_EARLY_PRINTK=y | 87 | CONFIG_EARLY_PRINTK=y |
88 | CONFIG_KEYS=y | 88 | CONFIG_KEYS=y |
89 | CONFIG_ENCRYPTED_KEYS=y | 89 | CONFIG_ENCRYPTED_KEYS=y |
90 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
91 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 90 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig index a29ebd4a9fcb..4cdaf565e638 100644 --- a/arch/microblaze/configs/nommu_defconfig +++ b/arch/microblaze/configs/nommu_defconfig | |||
@@ -92,7 +92,6 @@ CONFIG_DEBUG_INFO=y | |||
92 | CONFIG_EARLY_PRINTK=y | 92 | CONFIG_EARLY_PRINTK=y |
93 | CONFIG_KEYS=y | 93 | CONFIG_KEYS=y |
94 | CONFIG_ENCRYPTED_KEYS=y | 94 | CONFIG_ENCRYPTED_KEYS=y |
95 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
96 | CONFIG_CRYPTO_ECB=y | 95 | CONFIG_CRYPTO_ECB=y |
97 | CONFIG_CRYPTO_MD4=y | 96 | CONFIG_CRYPTO_MD4=y |
98 | CONFIG_CRYPTO_MD5=y | 97 | CONFIG_CRYPTO_MD5=y |
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index b3e7a1b61220..e070dac071c8 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig | |||
@@ -247,7 +247,6 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y | |||
247 | CONFIG_DEBUG_MEMORY_INIT=y | 247 | CONFIG_DEBUG_MEMORY_INIT=y |
248 | CONFIG_DEBUG_LIST=y | 248 | CONFIG_DEBUG_LIST=y |
249 | CONFIG_KEYS=y | 249 | CONFIG_KEYS=y |
250 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
251 | CONFIG_SECURITY=y | 250 | CONFIG_SECURITY=y |
252 | CONFIG_SECURITY_NETWORK=y | 251 | CONFIG_SECURITY_NETWORK=y |
253 | CONFIG_SECURITY_NETWORK_XFRM=y | 252 | CONFIG_SECURITY_NETWORK_XFRM=y |
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 57ed466e00db..6ba9ce9fcdd5 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig | |||
@@ -358,7 +358,6 @@ CONFIG_DLM=m | |||
358 | CONFIG_DEBUG_MEMORY_INIT=y | 358 | CONFIG_DEBUG_MEMORY_INIT=y |
359 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 359 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
360 | CONFIG_KEYS=y | 360 | CONFIG_KEYS=y |
361 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
362 | CONFIG_CRYPTO_FIPS=y | 361 | CONFIG_CRYPTO_FIPS=y |
363 | CONFIG_CRYPTO_NULL=m | 362 | CONFIG_CRYPTO_NULL=m |
364 | CONFIG_CRYPTO_CRYPTD=m | 363 | CONFIG_CRYPTO_CRYPTD=m |
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 48e16d98b2cc..77e9f505f5e4 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig | |||
@@ -346,7 +346,6 @@ CONFIG_PARTITION_ADVANCED=y | |||
346 | CONFIG_DLM=m | 346 | CONFIG_DLM=m |
347 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 347 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
348 | CONFIG_KEYS=y | 348 | CONFIG_KEYS=y |
349 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
350 | CONFIG_SECURITYFS=y | 349 | CONFIG_SECURITYFS=y |
351 | CONFIG_CRYPTO_FIPS=y | 350 | CONFIG_CRYPTO_FIPS=y |
352 | CONFIG_CRYPTO_NULL=m | 351 | CONFIG_CRYPTO_NULL=m |
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index fe48220157a9..f9af98f63cff 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig | |||
@@ -181,7 +181,6 @@ CONFIG_MAGIC_SYSRQ=y | |||
181 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 181 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
182 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 182 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
183 | CONFIG_KEYS=y | 183 | CONFIG_KEYS=y |
184 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
185 | CONFIG_CRYPTO_NULL=y | 184 | CONFIG_CRYPTO_NULL=y |
186 | CONFIG_CRYPTO_CBC=y | 185 | CONFIG_CRYPTO_CBC=y |
187 | CONFIG_CRYPTO_ECB=y | 186 | CONFIG_CRYPTO_ECB=y |
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 4f37a5985459..a5e85e1ee5de 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig | |||
@@ -362,7 +362,6 @@ CONFIG_NLS_KOI8_R=m | |||
362 | CONFIG_NLS_KOI8_U=m | 362 | CONFIG_NLS_KOI8_U=m |
363 | CONFIG_NLS_UTF8=m | 363 | CONFIG_NLS_UTF8=m |
364 | CONFIG_DLM=m | 364 | CONFIG_DLM=m |
365 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
366 | CONFIG_CRYPTO_NULL=m | 365 | CONFIG_CRYPTO_NULL=m |
367 | CONFIG_CRYPTO_ECB=m | 366 | CONFIG_CRYPTO_ECB=m |
368 | CONFIG_CRYPTO_LRW=m | 367 | CONFIG_CRYPTO_LRW=m |
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 004cf52d1b7d..d1f198b072a0 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig | |||
@@ -412,7 +412,6 @@ CONFIG_DEBUG_FS=y | |||
412 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 412 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
413 | CONFIG_SYSCTL_SYSCALL_CHECK=y | 413 | CONFIG_SYSCTL_SYSCALL_CHECK=y |
414 | CONFIG_KEYS=y | 414 | CONFIG_KEYS=y |
415 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
416 | CONFIG_CRYPTO_FIPS=y | 415 | CONFIG_CRYPTO_FIPS=y |
417 | CONFIG_CRYPTO_NULL=m | 416 | CONFIG_CRYPTO_NULL=m |
418 | CONFIG_CRYPTO_CRYPTD=m | 417 | CONFIG_CRYPTO_CRYPTD=m |
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index db029f4ff759..82db4e3e4cf1 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig | |||
@@ -453,7 +453,6 @@ CONFIG_NLS_KOI8_R=m | |||
453 | CONFIG_NLS_KOI8_U=m | 453 | CONFIG_NLS_KOI8_U=m |
454 | CONFIG_NLS_UTF8=m | 454 | CONFIG_NLS_UTF8=m |
455 | CONFIG_DLM=m | 455 | CONFIG_DLM=m |
456 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
457 | CONFIG_CRYPTO_NULL=m | 456 | CONFIG_CRYPTO_NULL=m |
458 | CONFIG_CRYPTO_ECB=m | 457 | CONFIG_CRYPTO_ECB=m |
459 | CONFIG_CRYPTO_LRW=m | 458 | CONFIG_CRYPTO_LRW=m |
diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig index 51bab13ef6f8..7fca09fedb59 100644 --- a/arch/mips/configs/sb1250_swarm_defconfig +++ b/arch/mips/configs/sb1250_swarm_defconfig | |||
@@ -87,7 +87,6 @@ CONFIG_NFS_V3=y | |||
87 | CONFIG_ROOT_NFS=y | 87 | CONFIG_ROOT_NFS=y |
88 | CONFIG_DLM=m | 88 | CONFIG_DLM=m |
89 | CONFIG_KEYS=y | 89 | CONFIG_KEYS=y |
90 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
91 | CONFIG_CRYPTO_NULL=m | 90 | CONFIG_CRYPTO_NULL=m |
92 | CONFIG_CRYPTO_CRYPTD=m | 91 | CONFIG_CRYPTO_CRYPTD=m |
93 | CONFIG_CRYPTO_AUTHENC=m | 92 | CONFIG_CRYPTO_AUTHENC=m |
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 9387cc2693f6..db8f56bf3883 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig | |||
@@ -183,7 +183,6 @@ CONFIG_DEBUG_KERNEL=y | |||
183 | CONFIG_DEBUG_MUTEXES=y | 183 | CONFIG_DEBUG_MUTEXES=y |
184 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 184 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
185 | CONFIG_DEBUG_RODATA=y | 185 | CONFIG_DEBUG_RODATA=y |
186 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
187 | CONFIG_CRYPTO_NULL=m | 186 | CONFIG_CRYPTO_NULL=m |
188 | CONFIG_CRYPTO_TEST=m | 187 | CONFIG_CRYPTO_TEST=m |
189 | CONFIG_CRYPTO_HMAC=y | 188 | CONFIG_CRYPTO_HMAC=y |
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index 0490199d7b15..1a4f776b49b8 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig | |||
@@ -193,7 +193,6 @@ CONFIG_HEADERS_CHECK=y | |||
193 | CONFIG_DEBUG_KERNEL=y | 193 | CONFIG_DEBUG_KERNEL=y |
194 | # CONFIG_DEBUG_BUGVERBOSE is not set | 194 | # CONFIG_DEBUG_BUGVERBOSE is not set |
195 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 195 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
196 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
197 | CONFIG_CRYPTO_NULL=m | 196 | CONFIG_CRYPTO_NULL=m |
198 | CONFIG_CRYPTO_TEST=m | 197 | CONFIG_CRYPTO_TEST=m |
199 | CONFIG_CRYPTO_HMAC=y | 198 | CONFIG_CRYPTO_HMAC=y |
diff --git a/arch/parisc/configs/default_defconfig b/arch/parisc/configs/default_defconfig index 4d8127e8428a..310b6657e4ac 100644 --- a/arch/parisc/configs/default_defconfig +++ b/arch/parisc/configs/default_defconfig | |||
@@ -211,7 +211,6 @@ CONFIG_DEBUG_KERNEL=y | |||
211 | CONFIG_DEBUG_MUTEXES=y | 211 | CONFIG_DEBUG_MUTEXES=y |
212 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 212 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
213 | CONFIG_KEYS=y | 213 | CONFIG_KEYS=y |
214 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
215 | CONFIG_CRYPTO_NULL=m | 214 | CONFIG_CRYPTO_NULL=m |
216 | CONFIG_CRYPTO_TEST=m | 215 | CONFIG_CRYPTO_TEST=m |
217 | CONFIG_CRYPTO_MD4=m | 216 | CONFIG_CRYPTO_MD4=m |
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 0ffb08ff5125..5b04d703a924 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig | |||
@@ -301,7 +301,6 @@ CONFIG_RCU_CPU_STALL_INFO=y | |||
301 | CONFIG_LATENCYTOP=y | 301 | CONFIG_LATENCYTOP=y |
302 | CONFIG_LKDTM=m | 302 | CONFIG_LKDTM=m |
303 | CONFIG_KEYS=y | 303 | CONFIG_KEYS=y |
304 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
305 | CONFIG_CRYPTO_NULL=m | 304 | CONFIG_CRYPTO_NULL=m |
306 | CONFIG_CRYPTO_TEST=m | 305 | CONFIG_CRYPTO_TEST=m |
307 | CONFIG_CRYPTO_HMAC=y | 306 | CONFIG_CRYPTO_HMAC=y |
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 91862292cd55..340685caa7b8 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig | |||
@@ -387,7 +387,6 @@ CONFIG_DETECT_HUNG_TASK=y | |||
387 | CONFIG_DEBUG_SPINLOCK=y | 387 | CONFIG_DEBUG_SPINLOCK=y |
388 | CONFIG_BOOTX_TEXT=y | 388 | CONFIG_BOOTX_TEXT=y |
389 | CONFIG_PPC_EARLY_DEBUG=y | 389 | CONFIG_PPC_EARLY_DEBUG=y |
390 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
391 | CONFIG_SECURITY=y | 390 | CONFIG_SECURITY=y |
392 | CONFIG_SECURITY_NETWORK=y | 391 | CONFIG_SECURITY_NETWORK=y |
393 | CONFIG_SECURITY_SELINUX=y | 392 | CONFIG_SECURITY_SELINUX=y |
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index e5d2c3dc07f1..99ccbebabfd3 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig | |||
@@ -1175,7 +1175,6 @@ CONFIG_BLK_DEV_IO_TRACE=y | |||
1175 | CONFIG_XMON=y | 1175 | CONFIG_XMON=y |
1176 | CONFIG_BOOTX_TEXT=y | 1176 | CONFIG_BOOTX_TEXT=y |
1177 | CONFIG_PPC_EARLY_DEBUG=y | 1177 | CONFIG_PPC_EARLY_DEBUG=y |
1178 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
1179 | CONFIG_SECURITY=y | 1178 | CONFIG_SECURITY=y |
1180 | CONFIG_SECURITY_NETWORK=y | 1179 | CONFIG_SECURITY_NETWORK=y |
1181 | CONFIG_SECURITY_NETWORK_XFRM=y | 1180 | CONFIG_SECURITY_NETWORK_XFRM=y |
diff --git a/arch/score/configs/spct6600_defconfig b/arch/score/configs/spct6600_defconfig index df1edbf507a2..b2d8802f43b4 100644 --- a/arch/score/configs/spct6600_defconfig +++ b/arch/score/configs/spct6600_defconfig | |||
@@ -70,7 +70,6 @@ CONFIG_NFSD=y | |||
70 | CONFIG_NFSD_V3_ACL=y | 70 | CONFIG_NFSD_V3_ACL=y |
71 | CONFIG_NFSD_V4=y | 71 | CONFIG_NFSD_V4=y |
72 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 72 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
73 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
74 | CONFIG_SECURITY=y | 73 | CONFIG_SECURITY=y |
75 | CONFIG_SECURITY_NETWORK=y | 74 | CONFIG_SECURITY_NETWORK=y |
76 | CONFIG_CRYPTO_NULL=y | 75 | CONFIG_CRYPTO_NULL=y |
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 37dc9364c4a1..c1387b7f447d 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig | |||
@@ -374,7 +374,6 @@ CONFIG_DEBUG_CREDENTIALS=y | |||
374 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 374 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
375 | CONFIG_ASYNC_RAID6_TEST=m | 375 | CONFIG_ASYNC_RAID6_TEST=m |
376 | CONFIG_KGDB=y | 376 | CONFIG_KGDB=y |
377 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
378 | CONFIG_SECURITY=y | 377 | CONFIG_SECURITY=y |
379 | CONFIG_SECURITYFS=y | 378 | CONFIG_SECURITYFS=y |
380 | CONFIG_SECURITY_NETWORK=y | 379 | CONFIG_SECURITY_NETWORK=y |
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 76a2781dec2c..6d9ce8af1107 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig | |||
@@ -486,7 +486,6 @@ CONFIG_DEBUG_LIST=y | |||
486 | CONFIG_DEBUG_CREDENTIALS=y | 486 | CONFIG_DEBUG_CREDENTIALS=y |
487 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 487 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
488 | CONFIG_ASYNC_RAID6_TEST=m | 488 | CONFIG_ASYNC_RAID6_TEST=m |
489 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
490 | CONFIG_SECURITY=y | 489 | CONFIG_SECURITY=y |
491 | CONFIG_SECURITYFS=y | 490 | CONFIG_SECURITYFS=y |
492 | CONFIG_SECURITY_NETWORK=y | 491 | CONFIG_SECURITY_NETWORK=y |
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index e25a1630320c..265901a84f3f 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig | |||
@@ -303,7 +303,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y | |||
303 | # CONFIG_DEBUG_RODATA_TEST is not set | 303 | # CONFIG_DEBUG_RODATA_TEST is not set |
304 | CONFIG_DEBUG_BOOT_PARAMS=y | 304 | CONFIG_DEBUG_BOOT_PARAMS=y |
305 | CONFIG_OPTIMIZE_INLINING=y | 305 | CONFIG_OPTIMIZE_INLINING=y |
306 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
307 | CONFIG_SECURITY=y | 306 | CONFIG_SECURITY=y |
308 | CONFIG_SECURITY_NETWORK=y | 307 | CONFIG_SECURITY_NETWORK=y |
309 | CONFIG_SECURITY_SELINUX=y | 308 | CONFIG_SECURITY_SELINUX=y |
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index cb5b3ab5beec..4f404a64681b 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig | |||
@@ -300,7 +300,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y | |||
300 | # CONFIG_DEBUG_RODATA_TEST is not set | 300 | # CONFIG_DEBUG_RODATA_TEST is not set |
301 | CONFIG_DEBUG_BOOT_PARAMS=y | 301 | CONFIG_DEBUG_BOOT_PARAMS=y |
302 | CONFIG_OPTIMIZE_INLINING=y | 302 | CONFIG_OPTIMIZE_INLINING=y |
303 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
304 | CONFIG_SECURITY=y | 303 | CONFIG_SECURITY=y |
305 | CONFIG_SECURITY_NETWORK=y | 304 | CONFIG_SECURITY_NETWORK=y |
306 | CONFIG_SECURITY_SELINUX=y | 305 | CONFIG_SECURITY_SELINUX=y |
diff --git a/certs/Kconfig b/certs/Kconfig index b030b9c7ed34..f0f8a4433685 100644 --- a/certs/Kconfig +++ b/certs/Kconfig | |||
@@ -39,4 +39,20 @@ config SYSTEM_TRUSTED_KEYS | |||
39 | form of DER-encoded *.x509 files in the top-level build directory, | 39 | form of DER-encoded *.x509 files in the top-level build directory, |
40 | those are no longer used. You will need to set this option instead. | 40 | those are no longer used. You will need to set this option instead. |
41 | 41 | ||
42 | config SYSTEM_EXTRA_CERTIFICATE | ||
43 | bool "Reserve area for inserting a certificate without recompiling" | ||
44 | depends on SYSTEM_TRUSTED_KEYRING | ||
45 | help | ||
46 | If set, space for an extra certificate will be reserved in the kernel | ||
47 | image. This allows introducing a trusted certificate to the default | ||
48 | system keyring without recompiling the kernel. | ||
49 | |||
50 | config SYSTEM_EXTRA_CERTIFICATE_SIZE | ||
51 | int "Number of bytes to reserve for the extra certificate" | ||
52 | depends on SYSTEM_EXTRA_CERTIFICATE | ||
53 | default 4096 | ||
54 | help | ||
55 | This is the number of bytes reserved in the kernel image for a | ||
56 | certificate to be inserted. | ||
57 | |||
42 | endmenu | 58 | endmenu |
diff --git a/certs/Makefile b/certs/Makefile index 28ac694dd11a..2773c4afa24c 100644 --- a/certs/Makefile +++ b/certs/Makefile | |||
@@ -36,29 +36,34 @@ ifndef CONFIG_MODULE_SIG_HASH | |||
36 | $(error Could not determine digest type to use from kernel config) | 36 | $(error Could not determine digest type to use from kernel config) |
37 | endif | 37 | endif |
38 | 38 | ||
39 | redirect_openssl = 2>&1 | ||
40 | quiet_redirect_openssl = 2>&1 | ||
41 | silent_redirect_openssl = 2>/dev/null | ||
42 | |||
39 | # We do it this way rather than having a boolean option for enabling an | 43 | # We do it this way rather than having a boolean option for enabling an |
40 | # external private key, because 'make randconfig' might enable such a | 44 | # external private key, because 'make randconfig' might enable such a |
41 | # boolean option and we unfortunately can't make it depend on !RANDCONFIG. | 45 | # boolean option and we unfortunately can't make it depend on !RANDCONFIG. |
42 | ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem") | 46 | ifeq ($(CONFIG_MODULE_SIG_KEY),"certs/signing_key.pem") |
43 | $(obj)/signing_key.pem: $(obj)/x509.genkey | 47 | $(obj)/signing_key.pem: $(obj)/x509.genkey |
44 | @echo "###" | 48 | @$(kecho) "###" |
45 | @echo "### Now generating an X.509 key pair to be used for signing modules." | 49 | @$(kecho) "### Now generating an X.509 key pair to be used for signing modules." |
46 | @echo "###" | 50 | @$(kecho) "###" |
47 | @echo "### If this takes a long time, you might wish to run rngd in the" | 51 | @$(kecho) "### If this takes a long time, you might wish to run rngd in the" |
48 | @echo "### background to keep the supply of entropy topped up. It" | 52 | @$(kecho) "### background to keep the supply of entropy topped up. It" |
49 | @echo "### needs to be run as root, and uses a hardware random" | 53 | @$(kecho) "### needs to be run as root, and uses a hardware random" |
50 | @echo "### number generator if one is available." | 54 | @$(kecho) "### number generator if one is available." |
51 | @echo "###" | 55 | @$(kecho) "###" |
52 | openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ | 56 | $(Q)openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ |
53 | -batch -x509 -config $(obj)/x509.genkey \ | 57 | -batch -x509 -config $(obj)/x509.genkey \ |
54 | -outform PEM -out $(obj)/signing_key.pem \ | 58 | -outform PEM -out $(obj)/signing_key.pem \ |
55 | -keyout $(obj)/signing_key.pem 2>&1 | 59 | -keyout $(obj)/signing_key.pem \ |
56 | @echo "###" | 60 | $($(quiet)redirect_openssl) |
57 | @echo "### Key pair generated." | 61 | @$(kecho) "###" |
58 | @echo "###" | 62 | @$(kecho) "### Key pair generated." |
63 | @$(kecho) "###" | ||
59 | 64 | ||
60 | $(obj)/x509.genkey: | 65 | $(obj)/x509.genkey: |
61 | @echo Generating X.509 key generation config | 66 | @$(kecho) Generating X.509 key generation config |
62 | @echo >$@ "[ req ]" | 67 | @echo >$@ "[ req ]" |
63 | @echo >>$@ "default_bits = 4096" | 68 | @echo >>$@ "default_bits = 4096" |
64 | @echo >>$@ "distinguished_name = req_distinguished_name" | 69 | @echo >>$@ "distinguished_name = req_distinguished_name" |
diff --git a/certs/system_certificates.S b/certs/system_certificates.S index 9216e8c81764..c9ceb71a43fe 100644 --- a/certs/system_certificates.S +++ b/certs/system_certificates.S | |||
@@ -13,6 +13,19 @@ __cert_list_start: | |||
13 | .incbin "certs/x509_certificate_list" | 13 | .incbin "certs/x509_certificate_list" |
14 | __cert_list_end: | 14 | __cert_list_end: |
15 | 15 | ||
16 | #ifdef CONFIG_SYSTEM_EXTRA_CERTIFICATE | ||
17 | .globl VMLINUX_SYMBOL(system_extra_cert) | ||
18 | .size system_extra_cert, CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE | ||
19 | VMLINUX_SYMBOL(system_extra_cert): | ||
20 | .fill CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE, 1, 0 | ||
21 | |||
22 | .align 4 | ||
23 | .globl VMLINUX_SYMBOL(system_extra_cert_used) | ||
24 | VMLINUX_SYMBOL(system_extra_cert_used): | ||
25 | .int 0 | ||
26 | |||
27 | #endif /* CONFIG_SYSTEM_EXTRA_CERTIFICATE */ | ||
28 | |||
16 | .align 8 | 29 | .align 8 |
17 | .globl VMLINUX_SYMBOL(system_certificate_list_size) | 30 | .globl VMLINUX_SYMBOL(system_certificate_list_size) |
18 | VMLINUX_SYMBOL(system_certificate_list_size): | 31 | VMLINUX_SYMBOL(system_certificate_list_size): |
diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 2570598b784d..f4180326c2e1 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c | |||
@@ -84,12 +84,12 @@ static __init int load_system_certificate_list(void) | |||
84 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | | 84 | ((KEY_POS_ALL & ~KEY_POS_SETATTR) | |
85 | KEY_USR_VIEW | KEY_USR_READ), | 85 | KEY_USR_VIEW | KEY_USR_READ), |
86 | KEY_ALLOC_NOT_IN_QUOTA | | 86 | KEY_ALLOC_NOT_IN_QUOTA | |
87 | KEY_ALLOC_TRUSTED); | 87 | KEY_ALLOC_TRUSTED | |
88 | KEY_ALLOC_BUILT_IN); | ||
88 | if (IS_ERR(key)) { | 89 | if (IS_ERR(key)) { |
89 | pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", | 90 | pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", |
90 | PTR_ERR(key)); | 91 | PTR_ERR(key)); |
91 | } else { | 92 | } else { |
92 | set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags); | ||
93 | pr_notice("Loaded X.509 cert '%s'\n", | 93 | pr_notice("Loaded X.509 cert '%s'\n", |
94 | key_ref_to_ptr(key)->description); | 94 | key_ref_to_ptr(key)->description); |
95 | key_ref_put(key); | 95 | key_ref_put(key); |
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 4870f28403f5..91a7e047a765 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig | |||
@@ -12,7 +12,6 @@ if ASYMMETRIC_KEY_TYPE | |||
12 | config ASYMMETRIC_PUBLIC_KEY_SUBTYPE | 12 | config ASYMMETRIC_PUBLIC_KEY_SUBTYPE |
13 | tristate "Asymmetric public-key crypto algorithm subtype" | 13 | tristate "Asymmetric public-key crypto algorithm subtype" |
14 | select MPILIB | 14 | select MPILIB |
15 | select PUBLIC_KEY_ALGO_RSA | ||
16 | select CRYPTO_HASH_INFO | 15 | select CRYPTO_HASH_INFO |
17 | help | 16 | help |
18 | This option provides support for asymmetric public key type handling. | 17 | This option provides support for asymmetric public key type handling. |
@@ -20,12 +19,6 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE | |||
20 | appropriate hash algorithms (such as SHA-1) must be available. | 19 | appropriate hash algorithms (such as SHA-1) must be available. |
21 | ENOPKG will be reported if the requisite algorithm is unavailable. | 20 | ENOPKG will be reported if the requisite algorithm is unavailable. |
22 | 21 | ||
23 | config PUBLIC_KEY_ALGO_RSA | ||
24 | tristate "RSA public-key algorithm" | ||
25 | select MPILIB | ||
26 | help | ||
27 | This option enables support for the RSA algorithm (PKCS#1, RFC3447). | ||
28 | |||
29 | config X509_CERTIFICATE_PARSER | 22 | config X509_CERTIFICATE_PARSER |
30 | tristate "X.509 certificate parser" | 23 | tristate "X.509 certificate parser" |
31 | depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE | 24 | depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE |
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index cd1406f9b14a..f90486256f01 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile | |||
@@ -7,7 +7,6 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o | |||
7 | asymmetric_keys-y := asymmetric_type.o signature.o | 7 | asymmetric_keys-y := asymmetric_type.o signature.o |
8 | 8 | ||
9 | obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o | 9 | obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o |
10 | obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o | ||
11 | 10 | ||
12 | # | 11 | # |
13 | # X.509 Certificate handling | 12 | # X.509 Certificate handling |
@@ -16,21 +15,18 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o | |||
16 | x509_key_parser-y := \ | 15 | x509_key_parser-y := \ |
17 | x509-asn1.o \ | 16 | x509-asn1.o \ |
18 | x509_akid-asn1.o \ | 17 | x509_akid-asn1.o \ |
19 | x509_rsakey-asn1.o \ | ||
20 | x509_cert_parser.o \ | 18 | x509_cert_parser.o \ |
21 | x509_public_key.o | 19 | x509_public_key.o |
22 | 20 | ||
23 | $(obj)/x509_cert_parser.o: \ | 21 | $(obj)/x509_cert_parser.o: \ |
24 | $(obj)/x509-asn1.h \ | 22 | $(obj)/x509-asn1.h \ |
25 | $(obj)/x509_akid-asn1.h \ | 23 | $(obj)/x509_akid-asn1.h |
26 | $(obj)/x509_rsakey-asn1.h | 24 | |
27 | $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h | 25 | $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h |
28 | $(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h | 26 | $(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h |
29 | $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h | ||
30 | 27 | ||
31 | clean-files += x509-asn1.c x509-asn1.h | 28 | clean-files += x509-asn1.c x509-asn1.h |
32 | clean-files += x509_akid-asn1.c x509_akid-asn1.h | 29 | clean-files += x509_akid-asn1.c x509_akid-asn1.h |
33 | clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h | ||
34 | 30 | ||
35 | # | 31 | # |
36 | # PKCS#7 message handling | 32 | # PKCS#7 message handling |
diff --git a/crypto/asymmetric_keys/mscode_parser.c b/crypto/asymmetric_keys/mscode_parser.c index adcef59eec0b..3242cbfaeaa2 100644 --- a/crypto/asymmetric_keys/mscode_parser.c +++ b/crypto/asymmetric_keys/mscode_parser.c | |||
@@ -86,25 +86,25 @@ int mscode_note_digest_algo(void *context, size_t hdrlen, | |||
86 | oid = look_up_OID(value, vlen); | 86 | oid = look_up_OID(value, vlen); |
87 | switch (oid) { | 87 | switch (oid) { |
88 | case OID_md4: | 88 | case OID_md4: |
89 | ctx->digest_algo = HASH_ALGO_MD4; | 89 | ctx->digest_algo = "md4"; |
90 | break; | 90 | break; |
91 | case OID_md5: | 91 | case OID_md5: |
92 | ctx->digest_algo = HASH_ALGO_MD5; | 92 | ctx->digest_algo = "md5"; |
93 | break; | 93 | break; |
94 | case OID_sha1: | 94 | case OID_sha1: |
95 | ctx->digest_algo = HASH_ALGO_SHA1; | 95 | ctx->digest_algo = "sha1"; |
96 | break; | 96 | break; |
97 | case OID_sha256: | 97 | case OID_sha256: |
98 | ctx->digest_algo = HASH_ALGO_SHA256; | 98 | ctx->digest_algo = "sha256"; |
99 | break; | 99 | break; |
100 | case OID_sha384: | 100 | case OID_sha384: |
101 | ctx->digest_algo = HASH_ALGO_SHA384; | 101 | ctx->digest_algo = "sha384"; |
102 | break; | 102 | break; |
103 | case OID_sha512: | 103 | case OID_sha512: |
104 | ctx->digest_algo = HASH_ALGO_SHA512; | 104 | ctx->digest_algo = "sha512"; |
105 | break; | 105 | break; |
106 | case OID_sha224: | 106 | case OID_sha224: |
107 | ctx->digest_algo = HASH_ALGO_SHA224; | 107 | ctx->digest_algo = "sha224"; |
108 | break; | 108 | break; |
109 | 109 | ||
110 | case OID__NR: | 110 | case OID__NR: |
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 8f3056cd0399..40de03f49ff8 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/oid_registry.h> | 17 | #include <linux/oid_registry.h> |
18 | #include "public_key.h" | 18 | #include <crypto/public_key.h> |
19 | #include "pkcs7_parser.h" | 19 | #include "pkcs7_parser.h" |
20 | #include "pkcs7-asn1.h" | 20 | #include "pkcs7-asn1.h" |
21 | 21 | ||
@@ -44,7 +44,7 @@ struct pkcs7_parse_context { | |||
44 | static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo) | 44 | static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo) |
45 | { | 45 | { |
46 | if (sinfo) { | 46 | if (sinfo) { |
47 | mpi_free(sinfo->sig.mpi[0]); | 47 | kfree(sinfo->sig.s); |
48 | kfree(sinfo->sig.digest); | 48 | kfree(sinfo->sig.digest); |
49 | kfree(sinfo->signing_cert_id); | 49 | kfree(sinfo->signing_cert_id); |
50 | kfree(sinfo); | 50 | kfree(sinfo); |
@@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(pkcs7_free_message); | |||
87 | static int pkcs7_check_authattrs(struct pkcs7_message *msg) | 87 | static int pkcs7_check_authattrs(struct pkcs7_message *msg) |
88 | { | 88 | { |
89 | struct pkcs7_signed_info *sinfo; | 89 | struct pkcs7_signed_info *sinfo; |
90 | bool want; | 90 | bool want = false; |
91 | 91 | ||
92 | sinfo = msg->signed_infos; | 92 | sinfo = msg->signed_infos; |
93 | if (sinfo->authattrs) { | 93 | if (sinfo->authattrs) { |
@@ -218,25 +218,25 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen, | |||
218 | 218 | ||
219 | switch (ctx->last_oid) { | 219 | switch (ctx->last_oid) { |
220 | case OID_md4: | 220 | case OID_md4: |
221 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD4; | 221 | ctx->sinfo->sig.hash_algo = "md4"; |
222 | break; | 222 | break; |
223 | case OID_md5: | 223 | case OID_md5: |
224 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_MD5; | 224 | ctx->sinfo->sig.hash_algo = "md5"; |
225 | break; | 225 | break; |
226 | case OID_sha1: | 226 | case OID_sha1: |
227 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA1; | 227 | ctx->sinfo->sig.hash_algo = "sha1"; |
228 | break; | 228 | break; |
229 | case OID_sha256: | 229 | case OID_sha256: |
230 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA256; | 230 | ctx->sinfo->sig.hash_algo = "sha256"; |
231 | break; | 231 | break; |
232 | case OID_sha384: | 232 | case OID_sha384: |
233 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA384; | 233 | ctx->sinfo->sig.hash_algo = "sha384"; |
234 | break; | 234 | break; |
235 | case OID_sha512: | 235 | case OID_sha512: |
236 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA512; | 236 | ctx->sinfo->sig.hash_algo = "sha512"; |
237 | break; | 237 | break; |
238 | case OID_sha224: | 238 | case OID_sha224: |
239 | ctx->sinfo->sig.pkey_hash_algo = HASH_ALGO_SHA224; | 239 | ctx->sinfo->sig.hash_algo = "sha224"; |
240 | default: | 240 | default: |
241 | printk("Unsupported digest algo: %u\n", ctx->last_oid); | 241 | printk("Unsupported digest algo: %u\n", ctx->last_oid); |
242 | return -ENOPKG; | 242 | return -ENOPKG; |
@@ -255,7 +255,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen, | |||
255 | 255 | ||
256 | switch (ctx->last_oid) { | 256 | switch (ctx->last_oid) { |
257 | case OID_rsaEncryption: | 257 | case OID_rsaEncryption: |
258 | ctx->sinfo->sig.pkey_algo = PKEY_ALGO_RSA; | 258 | ctx->sinfo->sig.pkey_algo = "rsa"; |
259 | break; | 259 | break; |
260 | default: | 260 | default: |
261 | printk("Unsupported pkey algo: %u\n", ctx->last_oid); | 261 | printk("Unsupported pkey algo: %u\n", ctx->last_oid); |
@@ -614,16 +614,12 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen, | |||
614 | const void *value, size_t vlen) | 614 | const void *value, size_t vlen) |
615 | { | 615 | { |
616 | struct pkcs7_parse_context *ctx = context; | 616 | struct pkcs7_parse_context *ctx = context; |
617 | MPI mpi; | ||
618 | 617 | ||
619 | BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA); | 618 | ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL); |
620 | 619 | if (!ctx->sinfo->sig.s) | |
621 | mpi = mpi_read_raw_data(value, vlen); | ||
622 | if (!mpi) | ||
623 | return -ENOMEM; | 620 | return -ENOMEM; |
624 | 621 | ||
625 | ctx->sinfo->sig.mpi[0] = mpi; | 622 | ctx->sinfo->sig.s_size = vlen; |
626 | ctx->sinfo->sig.nr_mpi = 1; | ||
627 | return 0; | 623 | return 0; |
628 | } | 624 | } |
629 | 625 | ||
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 90d6d47965b0..3bbdcc79a3d3 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/asn1.h> | 17 | #include <linux/asn1.h> |
18 | #include <linux/key.h> | 18 | #include <linux/key.h> |
19 | #include <keys/asymmetric-type.h> | 19 | #include <keys/asymmetric-type.h> |
20 | #include "public_key.h" | 20 | #include <crypto/public_key.h> |
21 | #include "pkcs7_parser.h" | 21 | #include "pkcs7_parser.h" |
22 | 22 | ||
23 | /** | 23 | /** |
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 325575caf6b4..50be2a15e531 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/asn1.h> | 17 | #include <linux/asn1.h> |
18 | #include <crypto/hash.h> | 18 | #include <crypto/hash.h> |
19 | #include "public_key.h" | 19 | #include <crypto/public_key.h> |
20 | #include "pkcs7_parser.h" | 20 | #include "pkcs7_parser.h" |
21 | 21 | ||
22 | /* | 22 | /* |
@@ -31,17 +31,15 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, | |||
31 | void *digest; | 31 | void *digest; |
32 | int ret; | 32 | int ret; |
33 | 33 | ||
34 | kenter(",%u,%u", sinfo->index, sinfo->sig.pkey_hash_algo); | 34 | kenter(",%u,%s", sinfo->index, sinfo->sig.hash_algo); |
35 | 35 | ||
36 | if (sinfo->sig.pkey_hash_algo >= PKEY_HASH__LAST || | 36 | if (!sinfo->sig.hash_algo) |
37 | !hash_algo_name[sinfo->sig.pkey_hash_algo]) | ||
38 | return -ENOPKG; | 37 | return -ENOPKG; |
39 | 38 | ||
40 | /* Allocate the hashing algorithm we're going to need and find out how | 39 | /* Allocate the hashing algorithm we're going to need and find out how |
41 | * big the hash operational data will be. | 40 | * big the hash operational data will be. |
42 | */ | 41 | */ |
43 | tfm = crypto_alloc_shash(hash_algo_name[sinfo->sig.pkey_hash_algo], | 42 | tfm = crypto_alloc_shash(sinfo->sig.hash_algo, 0, 0); |
44 | 0, 0); | ||
45 | if (IS_ERR(tfm)) | 43 | if (IS_ERR(tfm)) |
46 | return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); | 44 | return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); |
47 | 45 | ||
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 6db4c01c6503..0f8b264b3961 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c | |||
@@ -17,32 +17,13 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/scatterlist.h> | ||
20 | #include <keys/asymmetric-subtype.h> | 21 | #include <keys/asymmetric-subtype.h> |
21 | #include "public_key.h" | 22 | #include <crypto/public_key.h> |
23 | #include <crypto/akcipher.h> | ||
22 | 24 | ||
23 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
24 | 26 | ||
25 | const char *const pkey_algo_name[PKEY_ALGO__LAST] = { | ||
26 | [PKEY_ALGO_DSA] = "DSA", | ||
27 | [PKEY_ALGO_RSA] = "RSA", | ||
28 | }; | ||
29 | EXPORT_SYMBOL_GPL(pkey_algo_name); | ||
30 | |||
31 | const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = { | ||
32 | #if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \ | ||
33 | defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE) | ||
34 | [PKEY_ALGO_RSA] = &RSA_public_key_algorithm, | ||
35 | #endif | ||
36 | }; | ||
37 | EXPORT_SYMBOL_GPL(pkey_algo); | ||
38 | |||
39 | const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { | ||
40 | [PKEY_ID_PGP] = "PGP", | ||
41 | [PKEY_ID_X509] = "X509", | ||
42 | [PKEY_ID_PKCS7] = "PKCS#7", | ||
43 | }; | ||
44 | EXPORT_SYMBOL_GPL(pkey_id_type_name); | ||
45 | |||
46 | /* | 27 | /* |
47 | * Provide a part of a description of the key for /proc/keys. | 28 | * Provide a part of a description of the key for /proc/keys. |
48 | */ | 29 | */ |
@@ -52,8 +33,7 @@ static void public_key_describe(const struct key *asymmetric_key, | |||
52 | struct public_key *key = asymmetric_key->payload.data[asym_crypto]; | 33 | struct public_key *key = asymmetric_key->payload.data[asym_crypto]; |
53 | 34 | ||
54 | if (key) | 35 | if (key) |
55 | seq_printf(m, "%s.%s", | 36 | seq_printf(m, "%s.%s", key->id_type, key->pkey_algo); |
56 | pkey_id_type_name[key->id_type], key->algo->name); | ||
57 | } | 37 | } |
58 | 38 | ||
59 | /* | 39 | /* |
@@ -62,50 +42,116 @@ static void public_key_describe(const struct key *asymmetric_key, | |||
62 | void public_key_destroy(void *payload) | 42 | void public_key_destroy(void *payload) |
63 | { | 43 | { |
64 | struct public_key *key = payload; | 44 | struct public_key *key = payload; |
65 | int i; | ||
66 | 45 | ||
67 | if (key) { | 46 | if (key) |
68 | for (i = 0; i < ARRAY_SIZE(key->mpi); i++) | 47 | kfree(key->key); |
69 | mpi_free(key->mpi[i]); | 48 | kfree(key); |
70 | kfree(key); | ||
71 | } | ||
72 | } | 49 | } |
73 | EXPORT_SYMBOL_GPL(public_key_destroy); | 50 | EXPORT_SYMBOL_GPL(public_key_destroy); |
74 | 51 | ||
52 | struct public_key_completion { | ||
53 | struct completion completion; | ||
54 | int err; | ||
55 | }; | ||
56 | |||
57 | static void public_key_verify_done(struct crypto_async_request *req, int err) | ||
58 | { | ||
59 | struct public_key_completion *compl = req->data; | ||
60 | |||
61 | if (err == -EINPROGRESS) | ||
62 | return; | ||
63 | |||
64 | compl->err = err; | ||
65 | complete(&compl->completion); | ||
66 | } | ||
67 | |||
75 | /* | 68 | /* |
76 | * Verify a signature using a public key. | 69 | * Verify a signature using a public key. |
77 | */ | 70 | */ |
78 | int public_key_verify_signature(const struct public_key *pk, | 71 | int public_key_verify_signature(const struct public_key *pkey, |
79 | const struct public_key_signature *sig) | 72 | const struct public_key_signature *sig) |
80 | { | 73 | { |
81 | const struct public_key_algorithm *algo; | 74 | struct public_key_completion compl; |
82 | 75 | struct crypto_akcipher *tfm; | |
83 | BUG_ON(!pk); | 76 | struct akcipher_request *req; |
84 | BUG_ON(!pk->mpi[0]); | 77 | struct scatterlist sig_sg, digest_sg; |
85 | BUG_ON(!pk->mpi[1]); | 78 | const char *alg_name; |
79 | char alg_name_buf[CRYPTO_MAX_ALG_NAME]; | ||
80 | void *output; | ||
81 | unsigned int outlen; | ||
82 | int ret = -ENOMEM; | ||
83 | |||
84 | pr_devel("==>%s()\n", __func__); | ||
85 | |||
86 | BUG_ON(!pkey); | ||
86 | BUG_ON(!sig); | 87 | BUG_ON(!sig); |
87 | BUG_ON(!sig->digest); | 88 | BUG_ON(!sig->digest); |
88 | BUG_ON(!sig->mpi[0]); | 89 | BUG_ON(!sig->s); |
89 | 90 | ||
90 | algo = pk->algo; | 91 | alg_name = sig->pkey_algo; |
91 | if (!algo) { | 92 | if (strcmp(sig->pkey_algo, "rsa") == 0) { |
92 | if (pk->pkey_algo >= PKEY_ALGO__LAST) | 93 | /* The data wangled by the RSA algorithm is typically padded |
93 | return -ENOPKG; | 94 | * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 |
94 | algo = pkey_algo[pk->pkey_algo]; | 95 | * sec 8.2]. |
95 | if (!algo) | 96 | */ |
96 | return -ENOPKG; | 97 | if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, |
98 | "pkcs1pad(rsa,%s)", sig->hash_algo | ||
99 | ) >= CRYPTO_MAX_ALG_NAME) | ||
100 | return -EINVAL; | ||
101 | alg_name = alg_name_buf; | ||
97 | } | 102 | } |
98 | 103 | ||
99 | if (!algo->verify_signature) | 104 | tfm = crypto_alloc_akcipher(alg_name, 0, 0); |
100 | return -ENOTSUPP; | 105 | if (IS_ERR(tfm)) |
101 | 106 | return PTR_ERR(tfm); | |
102 | if (sig->nr_mpi != algo->n_sig_mpi) { | 107 | |
103 | pr_debug("Signature has %u MPI not %u\n", | 108 | req = akcipher_request_alloc(tfm, GFP_KERNEL); |
104 | sig->nr_mpi, algo->n_sig_mpi); | 109 | if (!req) |
105 | return -EINVAL; | 110 | goto error_free_tfm; |
111 | |||
112 | ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); | ||
113 | if (ret) | ||
114 | goto error_free_req; | ||
115 | |||
116 | outlen = crypto_akcipher_maxsize(tfm); | ||
117 | output = kmalloc(outlen, GFP_KERNEL); | ||
118 | if (!output) | ||
119 | goto error_free_req; | ||
120 | |||
121 | sg_init_one(&sig_sg, sig->s, sig->s_size); | ||
122 | sg_init_one(&digest_sg, output, outlen); | ||
123 | akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig->s_size, | ||
124 | outlen); | ||
125 | init_completion(&compl.completion); | ||
126 | akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | | ||
127 | CRYPTO_TFM_REQ_MAY_SLEEP, | ||
128 | public_key_verify_done, &compl); | ||
129 | |||
130 | /* Perform the verification calculation. This doesn't actually do the | ||
131 | * verification, but rather calculates the hash expected by the | ||
132 | * signature and returns that to us. | ||
133 | */ | ||
134 | ret = crypto_akcipher_verify(req); | ||
135 | if (ret == -EINPROGRESS) { | ||
136 | wait_for_completion(&compl.completion); | ||
137 | ret = compl.err; | ||
106 | } | 138 | } |
107 | 139 | if (ret < 0) | |
108 | return algo->verify_signature(pk, sig); | 140 | goto out_free_output; |
141 | |||
142 | /* Do the actual verification step. */ | ||
143 | if (req->dst_len != sig->digest_size || | ||
144 | memcmp(sig->digest, output, sig->digest_size) != 0) | ||
145 | ret = -EKEYREJECTED; | ||
146 | |||
147 | out_free_output: | ||
148 | kfree(output); | ||
149 | error_free_req: | ||
150 | akcipher_request_free(req); | ||
151 | error_free_tfm: | ||
152 | crypto_free_akcipher(tfm); | ||
153 | pr_devel("<==%s() = %d\n", __func__, ret); | ||
154 | return ret; | ||
109 | } | 155 | } |
110 | EXPORT_SYMBOL_GPL(public_key_verify_signature); | 156 | EXPORT_SYMBOL_GPL(public_key_verify_signature); |
111 | 157 | ||
diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h deleted file mode 100644 index 5c37a22a0637..000000000000 --- a/crypto/asymmetric_keys/public_key.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* Public key algorithm internals | ||
2 | * | ||
3 | * See Documentation/crypto/asymmetric-keys.txt | ||
4 | * | ||
5 | * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
6 | * Written by David Howells (dhowells@redhat.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public Licence | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the Licence, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <crypto/public_key.h> | ||
15 | |||
16 | extern struct asymmetric_key_subtype public_key_subtype; | ||
17 | |||
18 | /* | ||
19 | * Public key algorithm definition. | ||
20 | */ | ||
21 | struct public_key_algorithm { | ||
22 | const char *name; | ||
23 | u8 n_pub_mpi; /* Number of MPIs in public key */ | ||
24 | u8 n_sec_mpi; /* Number of MPIs in secret key */ | ||
25 | u8 n_sig_mpi; /* Number of MPIs in a signature */ | ||
26 | int (*verify_signature)(const struct public_key *key, | ||
27 | const struct public_key_signature *sig); | ||
28 | }; | ||
29 | |||
30 | extern const struct public_key_algorithm RSA_public_key_algorithm; | ||
31 | |||
32 | /* | ||
33 | * public_key.c | ||
34 | */ | ||
35 | extern int public_key_verify_signature(const struct public_key *pk, | ||
36 | const struct public_key_signature *sig); | ||
diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c deleted file mode 100644 index 508b57b77474..000000000000 --- a/crypto/asymmetric_keys/rsa.c +++ /dev/null | |||
@@ -1,278 +0,0 @@ | |||
1 | /* RSA asymmetric public-key algorithm [RFC3447] | ||
2 | * | ||
3 | * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.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 Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define pr_fmt(fmt) "RSA: "fmt | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <crypto/algapi.h> | ||
17 | #include "public_key.h" | ||
18 | |||
19 | MODULE_LICENSE("GPL"); | ||
20 | MODULE_DESCRIPTION("RSA Public Key Algorithm"); | ||
21 | |||
22 | #define kenter(FMT, ...) \ | ||
23 | pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__) | ||
24 | #define kleave(FMT, ...) \ | ||
25 | pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__) | ||
26 | |||
27 | /* | ||
28 | * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2]. | ||
29 | */ | ||
30 | static const u8 RSA_digest_info_MD5[] = { | ||
31 | 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, | ||
32 | 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */ | ||
33 | 0x05, 0x00, 0x04, 0x10 | ||
34 | }; | ||
35 | |||
36 | static const u8 RSA_digest_info_SHA1[] = { | ||
37 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, | ||
38 | 0x2B, 0x0E, 0x03, 0x02, 0x1A, | ||
39 | 0x05, 0x00, 0x04, 0x14 | ||
40 | }; | ||
41 | |||
42 | static const u8 RSA_digest_info_RIPE_MD_160[] = { | ||
43 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, | ||
44 | 0x2B, 0x24, 0x03, 0x02, 0x01, | ||
45 | 0x05, 0x00, 0x04, 0x14 | ||
46 | }; | ||
47 | |||
48 | static const u8 RSA_digest_info_SHA224[] = { | ||
49 | 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, | ||
50 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, | ||
51 | 0x05, 0x00, 0x04, 0x1C | ||
52 | }; | ||
53 | |||
54 | static const u8 RSA_digest_info_SHA256[] = { | ||
55 | 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, | ||
56 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, | ||
57 | 0x05, 0x00, 0x04, 0x20 | ||
58 | }; | ||
59 | |||
60 | static const u8 RSA_digest_info_SHA384[] = { | ||
61 | 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, | ||
62 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, | ||
63 | 0x05, 0x00, 0x04, 0x30 | ||
64 | }; | ||
65 | |||
66 | static const u8 RSA_digest_info_SHA512[] = { | ||
67 | 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, | ||
68 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, | ||
69 | 0x05, 0x00, 0x04, 0x40 | ||
70 | }; | ||
71 | |||
72 | static const struct { | ||
73 | const u8 *data; | ||
74 | size_t size; | ||
75 | } RSA_ASN1_templates[PKEY_HASH__LAST] = { | ||
76 | #define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) } | ||
77 | [HASH_ALGO_MD5] = _(MD5), | ||
78 | [HASH_ALGO_SHA1] = _(SHA1), | ||
79 | [HASH_ALGO_RIPE_MD_160] = _(RIPE_MD_160), | ||
80 | [HASH_ALGO_SHA256] = _(SHA256), | ||
81 | [HASH_ALGO_SHA384] = _(SHA384), | ||
82 | [HASH_ALGO_SHA512] = _(SHA512), | ||
83 | [HASH_ALGO_SHA224] = _(SHA224), | ||
84 | #undef _ | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * RSAVP1() function [RFC3447 sec 5.2.2] | ||
89 | */ | ||
90 | static int RSAVP1(const struct public_key *key, MPI s, MPI *_m) | ||
91 | { | ||
92 | MPI m; | ||
93 | int ret; | ||
94 | |||
95 | /* (1) Validate 0 <= s < n */ | ||
96 | if (mpi_cmp_ui(s, 0) < 0) { | ||
97 | kleave(" = -EBADMSG [s < 0]"); | ||
98 | return -EBADMSG; | ||
99 | } | ||
100 | if (mpi_cmp(s, key->rsa.n) >= 0) { | ||
101 | kleave(" = -EBADMSG [s >= n]"); | ||
102 | return -EBADMSG; | ||
103 | } | ||
104 | |||
105 | m = mpi_alloc(0); | ||
106 | if (!m) | ||
107 | return -ENOMEM; | ||
108 | |||
109 | /* (2) m = s^e mod n */ | ||
110 | ret = mpi_powm(m, s, key->rsa.e, key->rsa.n); | ||
111 | if (ret < 0) { | ||
112 | mpi_free(m); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | *_m = m; | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Integer to Octet String conversion [RFC3447 sec 4.1] | ||
122 | */ | ||
123 | static int RSA_I2OSP(MPI x, size_t xLen, u8 **pX) | ||
124 | { | ||
125 | unsigned X_size, x_size; | ||
126 | int X_sign; | ||
127 | u8 *X; | ||
128 | |||
129 | /* Make sure the string is the right length. The number should begin | ||
130 | * with { 0x00, 0x01, ... } so we have to account for 15 leading zero | ||
131 | * bits not being reported by MPI. | ||
132 | */ | ||
133 | x_size = mpi_get_nbits(x); | ||
134 | pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8); | ||
135 | if (x_size != xLen * 8 - 15) | ||
136 | return -ERANGE; | ||
137 | |||
138 | X = mpi_get_buffer(x, &X_size, &X_sign); | ||
139 | if (!X) | ||
140 | return -ENOMEM; | ||
141 | if (X_sign < 0) { | ||
142 | kfree(X); | ||
143 | return -EBADMSG; | ||
144 | } | ||
145 | if (X_size != xLen - 1) { | ||
146 | kfree(X); | ||
147 | return -EBADMSG; | ||
148 | } | ||
149 | |||
150 | *pX = X; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Perform the RSA signature verification. | ||
156 | * @H: Value of hash of data and metadata | ||
157 | * @EM: The computed signature value | ||
158 | * @k: The size of EM (EM[0] is an invalid location but should hold 0x00) | ||
159 | * @hash_size: The size of H | ||
160 | * @asn1_template: The DigestInfo ASN.1 template | ||
161 | * @asn1_size: Size of asm1_template[] | ||
162 | */ | ||
163 | static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size, | ||
164 | const u8 *asn1_template, size_t asn1_size) | ||
165 | { | ||
166 | unsigned PS_end, T_offset, i; | ||
167 | |||
168 | kenter(",,%zu,%zu,%zu", k, hash_size, asn1_size); | ||
169 | |||
170 | if (k < 2 + 1 + asn1_size + hash_size) | ||
171 | return -EBADMSG; | ||
172 | |||
173 | /* Decode the EMSA-PKCS1-v1_5 */ | ||
174 | if (EM[1] != 0x01) { | ||
175 | kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]); | ||
176 | return -EBADMSG; | ||
177 | } | ||
178 | |||
179 | T_offset = k - (asn1_size + hash_size); | ||
180 | PS_end = T_offset - 1; | ||
181 | if (EM[PS_end] != 0x00) { | ||
182 | kleave(" = -EBADMSG [EM[T-1] == %02u]", EM[PS_end]); | ||
183 | return -EBADMSG; | ||
184 | } | ||
185 | |||
186 | for (i = 2; i < PS_end; i++) { | ||
187 | if (EM[i] != 0xff) { | ||
188 | kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]); | ||
189 | return -EBADMSG; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) { | ||
194 | kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]"); | ||
195 | return -EBADMSG; | ||
196 | } | ||
197 | |||
198 | if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) { | ||
199 | kleave(" = -EKEYREJECTED [EM[T] hash mismatch]"); | ||
200 | return -EKEYREJECTED; | ||
201 | } | ||
202 | |||
203 | kleave(" = 0"); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Perform the verification step [RFC3447 sec 8.2.2]. | ||
209 | */ | ||
210 | static int RSA_verify_signature(const struct public_key *key, | ||
211 | const struct public_key_signature *sig) | ||
212 | { | ||
213 | size_t tsize; | ||
214 | int ret; | ||
215 | |||
216 | /* Variables as per RFC3447 sec 8.2.2 */ | ||
217 | const u8 *H = sig->digest; | ||
218 | u8 *EM = NULL; | ||
219 | MPI m = NULL; | ||
220 | size_t k; | ||
221 | |||
222 | kenter(""); | ||
223 | |||
224 | if (!RSA_ASN1_templates[sig->pkey_hash_algo].data) | ||
225 | return -ENOTSUPP; | ||
226 | |||
227 | /* (1) Check the signature size against the public key modulus size */ | ||
228 | k = mpi_get_nbits(key->rsa.n); | ||
229 | tsize = mpi_get_nbits(sig->rsa.s); | ||
230 | |||
231 | /* According to RFC 4880 sec 3.2, length of MPI is computed starting | ||
232 | * from most significant bit. So the RFC 3447 sec 8.2.2 size check | ||
233 | * must be relaxed to conform with shorter signatures - so we fail here | ||
234 | * only if signature length is longer than modulus size. | ||
235 | */ | ||
236 | pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize); | ||
237 | if (k < tsize) { | ||
238 | ret = -EBADMSG; | ||
239 | goto error; | ||
240 | } | ||
241 | |||
242 | /* Round up and convert to octets */ | ||
243 | k = (k + 7) / 8; | ||
244 | |||
245 | /* (2b) Apply the RSAVP1 verification primitive to the public key */ | ||
246 | ret = RSAVP1(key, sig->rsa.s, &m); | ||
247 | if (ret < 0) | ||
248 | goto error; | ||
249 | |||
250 | /* (2c) Convert the message representative (m) to an encoded message | ||
251 | * (EM) of length k octets. | ||
252 | * | ||
253 | * NOTE! The leading zero byte is suppressed by MPI, so we pass a | ||
254 | * pointer to the _preceding_ byte to RSA_verify()! | ||
255 | */ | ||
256 | ret = RSA_I2OSP(m, k, &EM); | ||
257 | if (ret < 0) | ||
258 | goto error; | ||
259 | |||
260 | ret = RSA_verify(H, EM - 1, k, sig->digest_size, | ||
261 | RSA_ASN1_templates[sig->pkey_hash_algo].data, | ||
262 | RSA_ASN1_templates[sig->pkey_hash_algo].size); | ||
263 | |||
264 | error: | ||
265 | kfree(EM); | ||
266 | mpi_free(m); | ||
267 | kleave(" = %d", ret); | ||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | const struct public_key_algorithm RSA_public_key_algorithm = { | ||
272 | .name = "RSA", | ||
273 | .n_pub_mpi = 2, | ||
274 | .n_sec_mpi = 3, | ||
275 | .n_sig_mpi = 1, | ||
276 | .verify_signature = RSA_verify_signature, | ||
277 | }; | ||
278 | EXPORT_SYMBOL_GPL(RSA_public_key_algorithm); | ||
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 897b734dabf9..7e8c2338ae25 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c | |||
@@ -328,12 +328,12 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, | |||
328 | void *digest; | 328 | void *digest; |
329 | int ret; | 329 | int ret; |
330 | 330 | ||
331 | kenter(",%u", ctx->digest_algo); | 331 | kenter(",%s", ctx->digest_algo); |
332 | 332 | ||
333 | /* Allocate the hashing algorithm we're going to need and find out how | 333 | /* Allocate the hashing algorithm we're going to need and find out how |
334 | * big the hash operational data will be. | 334 | * big the hash operational data will be. |
335 | */ | 335 | */ |
336 | tfm = crypto_alloc_shash(hash_algo_name[ctx->digest_algo], 0, 0); | 336 | tfm = crypto_alloc_shash(ctx->digest_algo, 0, 0); |
337 | if (IS_ERR(tfm)) | 337 | if (IS_ERR(tfm)) |
338 | return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); | 338 | return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); |
339 | 339 | ||
diff --git a/crypto/asymmetric_keys/verify_pefile.h b/crypto/asymmetric_keys/verify_pefile.h index 55d5f7ebc45a..a133eb81a492 100644 --- a/crypto/asymmetric_keys/verify_pefile.h +++ b/crypto/asymmetric_keys/verify_pefile.h | |||
@@ -28,7 +28,7 @@ struct pefile_context { | |||
28 | /* PKCS#7 MS Individual Code Signing content */ | 28 | /* PKCS#7 MS Individual Code Signing content */ |
29 | const void *digest; /* Digest */ | 29 | const void *digest; /* Digest */ |
30 | unsigned digest_len; /* Digest length */ | 30 | unsigned digest_len; /* Digest length */ |
31 | enum hash_algo digest_algo; /* Digest algorithm */ | 31 | const char *digest_algo; /* Digest algorithm */ |
32 | }; | 32 | }; |
33 | 33 | ||
34 | #define kenter(FMT, ...) \ | 34 | #define kenter(FMT, ...) \ |
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 021d39c0ba75..4a29bac70060 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c | |||
@@ -15,11 +15,10 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/oid_registry.h> | 17 | #include <linux/oid_registry.h> |
18 | #include "public_key.h" | 18 | #include <crypto/public_key.h> |
19 | #include "x509_parser.h" | 19 | #include "x509_parser.h" |
20 | #include "x509-asn1.h" | 20 | #include "x509-asn1.h" |
21 | #include "x509_akid-asn1.h" | 21 | #include "x509_akid-asn1.h" |
22 | #include "x509_rsakey-asn1.h" | ||
23 | 22 | ||
24 | struct x509_parse_context { | 23 | struct x509_parse_context { |
25 | struct x509_certificate *cert; /* Certificate being constructed */ | 24 | struct x509_certificate *cert; /* Certificate being constructed */ |
@@ -56,7 +55,7 @@ void x509_free_certificate(struct x509_certificate *cert) | |||
56 | kfree(cert->akid_id); | 55 | kfree(cert->akid_id); |
57 | kfree(cert->akid_skid); | 56 | kfree(cert->akid_skid); |
58 | kfree(cert->sig.digest); | 57 | kfree(cert->sig.digest); |
59 | mpi_free(cert->sig.rsa.s); | 58 | kfree(cert->sig.s); |
60 | kfree(cert); | 59 | kfree(cert); |
61 | } | 60 | } |
62 | } | 61 | } |
@@ -103,12 +102,12 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) | |||
103 | } | 102 | } |
104 | } | 103 | } |
105 | 104 | ||
106 | /* Decode the public key */ | 105 | cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL); |
107 | ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx, | 106 | if (!cert->pub->key) |
108 | ctx->key, ctx->key_size); | ||
109 | if (ret < 0) | ||
110 | goto error_decode; | 107 | goto error_decode; |
111 | 108 | ||
109 | cert->pub->keylen = ctx->key_size; | ||
110 | |||
112 | /* Generate cert issuer + serial number key ID */ | 111 | /* Generate cert issuer + serial number key ID */ |
113 | kid = asymmetric_key_generate_id(cert->raw_serial, | 112 | kid = asymmetric_key_generate_id(cert->raw_serial, |
114 | cert->raw_serial_size, | 113 | cert->raw_serial_size, |
@@ -124,6 +123,7 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) | |||
124 | return cert; | 123 | return cert; |
125 | 124 | ||
126 | error_decode: | 125 | error_decode: |
126 | kfree(cert->pub->key); | ||
127 | kfree(ctx); | 127 | kfree(ctx); |
128 | error_no_ctx: | 128 | error_no_ctx: |
129 | x509_free_certificate(cert); | 129 | x509_free_certificate(cert); |
@@ -188,33 +188,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen, | |||
188 | return -ENOPKG; /* Unsupported combination */ | 188 | return -ENOPKG; /* Unsupported combination */ |
189 | 189 | ||
190 | case OID_md4WithRSAEncryption: | 190 | case OID_md4WithRSAEncryption: |
191 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_MD5; | 191 | ctx->cert->sig.hash_algo = "md4"; |
192 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 192 | ctx->cert->sig.pkey_algo = "rsa"; |
193 | break; | 193 | break; |
194 | 194 | ||
195 | case OID_sha1WithRSAEncryption: | 195 | case OID_sha1WithRSAEncryption: |
196 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA1; | 196 | ctx->cert->sig.hash_algo = "sha1"; |
197 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 197 | ctx->cert->sig.pkey_algo = "rsa"; |
198 | break; | 198 | break; |
199 | 199 | ||
200 | case OID_sha256WithRSAEncryption: | 200 | case OID_sha256WithRSAEncryption: |
201 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA256; | 201 | ctx->cert->sig.hash_algo = "sha256"; |
202 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 202 | ctx->cert->sig.pkey_algo = "rsa"; |
203 | break; | 203 | break; |
204 | 204 | ||
205 | case OID_sha384WithRSAEncryption: | 205 | case OID_sha384WithRSAEncryption: |
206 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA384; | 206 | ctx->cert->sig.hash_algo = "sha384"; |
207 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 207 | ctx->cert->sig.pkey_algo = "rsa"; |
208 | break; | 208 | break; |
209 | 209 | ||
210 | case OID_sha512WithRSAEncryption: | 210 | case OID_sha512WithRSAEncryption: |
211 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA512; | 211 | ctx->cert->sig.hash_algo = "sha512"; |
212 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 212 | ctx->cert->sig.pkey_algo = "rsa"; |
213 | break; | 213 | break; |
214 | 214 | ||
215 | case OID_sha224WithRSAEncryption: | 215 | case OID_sha224WithRSAEncryption: |
216 | ctx->cert->sig.pkey_hash_algo = HASH_ALGO_SHA224; | 216 | ctx->cert->sig.hash_algo = "sha224"; |
217 | ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA; | 217 | ctx->cert->sig.pkey_algo = "rsa"; |
218 | break; | 218 | break; |
219 | } | 219 | } |
220 | 220 | ||
@@ -396,7 +396,7 @@ int x509_extract_key_data(void *context, size_t hdrlen, | |||
396 | if (ctx->last_oid != OID_rsaEncryption) | 396 | if (ctx->last_oid != OID_rsaEncryption) |
397 | return -ENOPKG; | 397 | return -ENOPKG; |
398 | 398 | ||
399 | ctx->cert->pub->pkey_algo = PKEY_ALGO_RSA; | 399 | ctx->cert->pub->pkey_algo = "rsa"; |
400 | 400 | ||
401 | /* Discard the BIT STRING metadata */ | 401 | /* Discard the BIT STRING metadata */ |
402 | ctx->key = value + 1; | 402 | ctx->key = value + 1; |
@@ -404,29 +404,6 @@ int x509_extract_key_data(void *context, size_t hdrlen, | |||
404 | return 0; | 404 | return 0; |
405 | } | 405 | } |
406 | 406 | ||
407 | /* | ||
408 | * Extract a RSA public key value | ||
409 | */ | ||
410 | int rsa_extract_mpi(void *context, size_t hdrlen, | ||
411 | unsigned char tag, | ||
412 | const void *value, size_t vlen) | ||
413 | { | ||
414 | struct x509_parse_context *ctx = context; | ||
415 | MPI mpi; | ||
416 | |||
417 | if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) { | ||
418 | pr_err("Too many public key MPIs in certificate\n"); | ||
419 | return -EBADMSG; | ||
420 | } | ||
421 | |||
422 | mpi = mpi_read_raw_data(value, vlen); | ||
423 | if (!mpi) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi; | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | /* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ | 407 | /* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ |
431 | #define SEQ_TAG_KEYID (ASN1_CONT << 6) | 408 | #define SEQ_TAG_KEYID (ASN1_CONT << 6) |
432 | 409 | ||
@@ -494,7 +471,7 @@ int x509_decode_time(time64_t *_t, size_t hdrlen, | |||
494 | unsigned char tag, | 471 | unsigned char tag, |
495 | const unsigned char *value, size_t vlen) | 472 | const unsigned char *value, size_t vlen) |
496 | { | 473 | { |
497 | static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30, | 474 | static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30, |
498 | 31, 31, 30, 31, 30, 31 }; | 475 | 31, 31, 30, 31, 30, 31 }; |
499 | const unsigned char *p = value; | 476 | const unsigned char *p = value; |
500 | unsigned year, mon, day, hour, min, sec, mon_len; | 477 | unsigned year, mon, day, hour, min, sec, mon_len; |
@@ -540,17 +517,17 @@ int x509_decode_time(time64_t *_t, size_t hdrlen, | |||
540 | if (year % 4 == 0) { | 517 | if (year % 4 == 0) { |
541 | mon_len = 29; | 518 | mon_len = 29; |
542 | if (year % 100 == 0) { | 519 | if (year % 100 == 0) { |
543 | year /= 100; | 520 | mon_len = 28; |
544 | if (year % 4 != 0) | 521 | if (year % 400 == 0) |
545 | mon_len = 28; | 522 | mon_len = 29; |
546 | } | 523 | } |
547 | } | 524 | } |
548 | } | 525 | } |
549 | 526 | ||
550 | if (day < 1 || day > mon_len || | 527 | if (day < 1 || day > mon_len || |
551 | hour > 23 || | 528 | hour > 24 || /* ISO 8601 permits 24:00:00 as midnight tomorrow */ |
552 | min > 59 || | 529 | min > 59 || |
553 | sec > 59) | 530 | sec > 60) /* ISO 8601 permits leap seconds [X.680 46.3] */ |
554 | goto invalid_time; | 531 | goto invalid_time; |
555 | 532 | ||
556 | *_t = mktime64(year, mon, day, hour, min, sec); | 533 | *_t = mktime64(year, mon, day, hour, min, sec); |
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 9e9e5a6a9ed6..733c046aacc6 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c | |||
@@ -13,15 +13,11 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | ||
17 | #include <linux/mpi.h> | ||
18 | #include <linux/asn1_decoder.h> | ||
19 | #include <keys/asymmetric-subtype.h> | 16 | #include <keys/asymmetric-subtype.h> |
20 | #include <keys/asymmetric-parser.h> | 17 | #include <keys/asymmetric-parser.h> |
21 | #include <keys/system_keyring.h> | 18 | #include <keys/system_keyring.h> |
22 | #include <crypto/hash.h> | 19 | #include <crypto/hash.h> |
23 | #include "asymmetric_keys.h" | 20 | #include "asymmetric_keys.h" |
24 | #include "public_key.h" | ||
25 | #include "x509_parser.h" | 21 | #include "x509_parser.h" |
26 | 22 | ||
27 | static bool use_builtin_keys; | 23 | static bool use_builtin_keys; |
@@ -167,18 +163,20 @@ int x509_get_sig_params(struct x509_certificate *cert) | |||
167 | 163 | ||
168 | if (cert->unsupported_crypto) | 164 | if (cert->unsupported_crypto) |
169 | return -ENOPKG; | 165 | return -ENOPKG; |
170 | if (cert->sig.rsa.s) | 166 | if (cert->sig.s) |
171 | return 0; | 167 | return 0; |
172 | 168 | ||
173 | cert->sig.rsa.s = mpi_read_raw_data(cert->raw_sig, cert->raw_sig_size); | 169 | cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size, |
174 | if (!cert->sig.rsa.s) | 170 | GFP_KERNEL); |
171 | if (!cert->sig.s) | ||
175 | return -ENOMEM; | 172 | return -ENOMEM; |
176 | cert->sig.nr_mpi = 1; | 173 | |
174 | cert->sig.s_size = cert->raw_sig_size; | ||
177 | 175 | ||
178 | /* Allocate the hashing algorithm we're going to need and find out how | 176 | /* Allocate the hashing algorithm we're going to need and find out how |
179 | * big the hash operational data will be. | 177 | * big the hash operational data will be. |
180 | */ | 178 | */ |
181 | tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); | 179 | tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0); |
182 | if (IS_ERR(tfm)) { | 180 | if (IS_ERR(tfm)) { |
183 | if (PTR_ERR(tfm) == -ENOENT) { | 181 | if (PTR_ERR(tfm) == -ENOENT) { |
184 | cert->unsupported_crypto = true; | 182 | cert->unsupported_crypto = true; |
@@ -293,24 +291,20 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) | |||
293 | pr_devel("Cert Issuer: %s\n", cert->issuer); | 291 | pr_devel("Cert Issuer: %s\n", cert->issuer); |
294 | pr_devel("Cert Subject: %s\n", cert->subject); | 292 | pr_devel("Cert Subject: %s\n", cert->subject); |
295 | 293 | ||
296 | if (cert->pub->pkey_algo >= PKEY_ALGO__LAST || | 294 | if (!cert->pub->pkey_algo || |
297 | cert->sig.pkey_algo >= PKEY_ALGO__LAST || | 295 | !cert->sig.pkey_algo || |
298 | cert->sig.pkey_hash_algo >= PKEY_HASH__LAST || | 296 | !cert->sig.hash_algo) { |
299 | !pkey_algo[cert->pub->pkey_algo] || | ||
300 | !pkey_algo[cert->sig.pkey_algo] || | ||
301 | !hash_algo_name[cert->sig.pkey_hash_algo]) { | ||
302 | ret = -ENOPKG; | 297 | ret = -ENOPKG; |
303 | goto error_free_cert; | 298 | goto error_free_cert; |
304 | } | 299 | } |
305 | 300 | ||
306 | pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]); | 301 | pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo); |
307 | pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); | 302 | pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); |
308 | pr_devel("Cert Signature: %s + %s\n", | 303 | pr_devel("Cert Signature: %s + %s\n", |
309 | pkey_algo_name[cert->sig.pkey_algo], | 304 | cert->sig.pkey_algo, |
310 | hash_algo_name[cert->sig.pkey_hash_algo]); | 305 | cert->sig.hash_algo); |
311 | 306 | ||
312 | cert->pub->algo = pkey_algo[cert->pub->pkey_algo]; | 307 | cert->pub->id_type = "X509"; |
313 | cert->pub->id_type = PKEY_ID_X509; | ||
314 | 308 | ||
315 | /* Check the signature on the key if it appears to be self-signed */ | 309 | /* Check the signature on the key if it appears to be self-signed */ |
316 | if ((!cert->akid_skid && !cert->akid_id) || | 310 | if ((!cert->akid_skid && !cert->akid_id) || |
diff --git a/crypto/asymmetric_keys/x509_rsakey.asn1 b/crypto/asymmetric_keys/x509_rsakey.asn1 deleted file mode 100644 index 4ec7cc6532c1..000000000000 --- a/crypto/asymmetric_keys/x509_rsakey.asn1 +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | RSAPublicKey ::= SEQUENCE { | ||
2 | modulus INTEGER ({ rsa_extract_mpi }), -- n | ||
3 | publicExponent INTEGER ({ rsa_extract_mpi }) -- e | ||
4 | } | ||
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 50f5c97e1087..1cea67d43e1d 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c | |||
@@ -18,12 +18,89 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/random.h> | 19 | #include <linux/random.h> |
20 | 20 | ||
21 | /* | ||
22 | * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2]. | ||
23 | */ | ||
24 | static const u8 rsa_digest_info_md5[] = { | ||
25 | 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, | ||
26 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */ | ||
27 | 0x05, 0x00, 0x04, 0x10 | ||
28 | }; | ||
29 | |||
30 | static const u8 rsa_digest_info_sha1[] = { | ||
31 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, | ||
32 | 0x2b, 0x0e, 0x03, 0x02, 0x1a, | ||
33 | 0x05, 0x00, 0x04, 0x14 | ||
34 | }; | ||
35 | |||
36 | static const u8 rsa_digest_info_rmd160[] = { | ||
37 | 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, | ||
38 | 0x2b, 0x24, 0x03, 0x02, 0x01, | ||
39 | 0x05, 0x00, 0x04, 0x14 | ||
40 | }; | ||
41 | |||
42 | static const u8 rsa_digest_info_sha224[] = { | ||
43 | 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, | ||
44 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, | ||
45 | 0x05, 0x00, 0x04, 0x1c | ||
46 | }; | ||
47 | |||
48 | static const u8 rsa_digest_info_sha256[] = { | ||
49 | 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, | ||
50 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, | ||
51 | 0x05, 0x00, 0x04, 0x20 | ||
52 | }; | ||
53 | |||
54 | static const u8 rsa_digest_info_sha384[] = { | ||
55 | 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, | ||
56 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, | ||
57 | 0x05, 0x00, 0x04, 0x30 | ||
58 | }; | ||
59 | |||
60 | static const u8 rsa_digest_info_sha512[] = { | ||
61 | 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, | ||
62 | 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, | ||
63 | 0x05, 0x00, 0x04, 0x40 | ||
64 | }; | ||
65 | |||
66 | static const struct rsa_asn1_template { | ||
67 | const char *name; | ||
68 | const u8 *data; | ||
69 | size_t size; | ||
70 | } rsa_asn1_templates[] = { | ||
71 | #define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) } | ||
72 | _(md5), | ||
73 | _(sha1), | ||
74 | _(rmd160), | ||
75 | _(sha256), | ||
76 | _(sha384), | ||
77 | _(sha512), | ||
78 | _(sha224), | ||
79 | { NULL } | ||
80 | #undef _ | ||
81 | }; | ||
82 | |||
83 | static const struct rsa_asn1_template *rsa_lookup_asn1(const char *name) | ||
84 | { | ||
85 | const struct rsa_asn1_template *p; | ||
86 | |||
87 | for (p = rsa_asn1_templates; p->name; p++) | ||
88 | if (strcmp(name, p->name) == 0) | ||
89 | return p; | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
21 | struct pkcs1pad_ctx { | 93 | struct pkcs1pad_ctx { |
22 | struct crypto_akcipher *child; | 94 | struct crypto_akcipher *child; |
23 | 95 | const char *hash_name; | |
24 | unsigned int key_size; | 96 | unsigned int key_size; |
25 | }; | 97 | }; |
26 | 98 | ||
99 | struct pkcs1pad_inst_ctx { | ||
100 | struct crypto_akcipher_spawn spawn; | ||
101 | const char *hash_name; | ||
102 | }; | ||
103 | |||
27 | struct pkcs1pad_request { | 104 | struct pkcs1pad_request { |
28 | struct akcipher_request child_req; | 105 | struct akcipher_request child_req; |
29 | 106 | ||
@@ -339,13 +416,22 @@ static int pkcs1pad_sign(struct akcipher_request *req) | |||
339 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 416 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
340 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 417 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
341 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 418 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
419 | const struct rsa_asn1_template *digest_info = NULL; | ||
342 | int err; | 420 | int err; |
343 | unsigned int ps_end; | 421 | unsigned int ps_end, digest_size = 0; |
344 | 422 | ||
345 | if (!ctx->key_size) | 423 | if (!ctx->key_size) |
346 | return -EINVAL; | 424 | return -EINVAL; |
347 | 425 | ||
348 | if (req->src_len > ctx->key_size - 11) | 426 | if (ctx->hash_name) { |
427 | digest_info = rsa_lookup_asn1(ctx->hash_name); | ||
428 | if (!digest_info) | ||
429 | return -EINVAL; | ||
430 | |||
431 | digest_size = digest_info->size; | ||
432 | } | ||
433 | |||
434 | if (req->src_len + digest_size > ctx->key_size - 11) | ||
349 | return -EOVERFLOW; | 435 | return -EOVERFLOW; |
350 | 436 | ||
351 | if (req->dst_len < ctx->key_size) { | 437 | if (req->dst_len < ctx->key_size) { |
@@ -371,11 +457,16 @@ static int pkcs1pad_sign(struct akcipher_request *req) | |||
371 | if (!req_ctx->in_buf) | 457 | if (!req_ctx->in_buf) |
372 | return -ENOMEM; | 458 | return -ENOMEM; |
373 | 459 | ||
374 | ps_end = ctx->key_size - req->src_len - 2; | 460 | ps_end = ctx->key_size - digest_size - req->src_len - 2; |
375 | req_ctx->in_buf[0] = 0x01; | 461 | req_ctx->in_buf[0] = 0x01; |
376 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); | 462 | memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); |
377 | req_ctx->in_buf[ps_end] = 0x00; | 463 | req_ctx->in_buf[ps_end] = 0x00; |
378 | 464 | ||
465 | if (digest_info) { | ||
466 | memcpy(req_ctx->in_buf + ps_end + 1, digest_info->data, | ||
467 | digest_info->size); | ||
468 | } | ||
469 | |||
379 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, | 470 | pkcs1pad_sg_set_buf(req_ctx->in_sg, req_ctx->in_buf, |
380 | ctx->key_size - 1 - req->src_len, req->src); | 471 | ctx->key_size - 1 - req->src_len, req->src); |
381 | 472 | ||
@@ -408,6 +499,7 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
408 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); | 499 | struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); |
409 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 500 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
410 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 501 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
502 | const struct rsa_asn1_template *digest_info; | ||
411 | unsigned int pos; | 503 | unsigned int pos; |
412 | 504 | ||
413 | if (err == -EOVERFLOW) | 505 | if (err == -EOVERFLOW) |
@@ -422,20 +514,33 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
422 | goto done; | 514 | goto done; |
423 | } | 515 | } |
424 | 516 | ||
425 | if (req_ctx->out_buf[0] != 0x01) { | 517 | err = -EBADMSG; |
426 | err = -EINVAL; | 518 | if (req_ctx->out_buf[0] != 0x01) |
427 | goto done; | 519 | goto done; |
428 | } | 520 | |
429 | for (pos = 1; pos < req_ctx->child_req.dst_len; pos++) | 521 | for (pos = 1; pos < req_ctx->child_req.dst_len; pos++) |
430 | if (req_ctx->out_buf[pos] != 0xff) | 522 | if (req_ctx->out_buf[pos] != 0xff) |
431 | break; | 523 | break; |
524 | |||
432 | if (pos < 9 || pos == req_ctx->child_req.dst_len || | 525 | if (pos < 9 || pos == req_ctx->child_req.dst_len || |
433 | req_ctx->out_buf[pos] != 0x00) { | 526 | req_ctx->out_buf[pos] != 0x00) |
434 | err = -EINVAL; | ||
435 | goto done; | 527 | goto done; |
436 | } | ||
437 | pos++; | 528 | pos++; |
438 | 529 | ||
530 | if (ctx->hash_name) { | ||
531 | digest_info = rsa_lookup_asn1(ctx->hash_name); | ||
532 | if (!digest_info) | ||
533 | goto done; | ||
534 | |||
535 | if (memcmp(req_ctx->out_buf + pos, digest_info->data, | ||
536 | digest_info->size)) | ||
537 | goto done; | ||
538 | |||
539 | pos += digest_info->size; | ||
540 | } | ||
541 | |||
542 | err = 0; | ||
543 | |||
439 | if (req->dst_len < req_ctx->child_req.dst_len - pos) | 544 | if (req->dst_len < req_ctx->child_req.dst_len - pos) |
440 | err = -EOVERFLOW; | 545 | err = -EOVERFLOW; |
441 | req->dst_len = req_ctx->child_req.dst_len - pos; | 546 | req->dst_len = req_ctx->child_req.dst_len - pos; |
@@ -444,7 +549,6 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) | |||
444 | sg_copy_from_buffer(req->dst, | 549 | sg_copy_from_buffer(req->dst, |
445 | sg_nents_for_len(req->dst, req->dst_len), | 550 | sg_nents_for_len(req->dst, req->dst_len), |
446 | req_ctx->out_buf + pos, req->dst_len); | 551 | req_ctx->out_buf + pos, req->dst_len); |
447 | |||
448 | done: | 552 | done: |
449 | kzfree(req_ctx->out_buf); | 553 | kzfree(req_ctx->out_buf); |
450 | 554 | ||
@@ -481,7 +585,7 @@ static int pkcs1pad_verify(struct akcipher_request *req) | |||
481 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); | 585 | struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); |
482 | int err; | 586 | int err; |
483 | 587 | ||
484 | if (!ctx->key_size || req->src_len != ctx->key_size) | 588 | if (!ctx->key_size || req->src_len < ctx->key_size) |
485 | return -EINVAL; | 589 | return -EINVAL; |
486 | 590 | ||
487 | if (ctx->key_size > PAGE_SIZE) | 591 | if (ctx->key_size > PAGE_SIZE) |
@@ -518,6 +622,7 @@ static int pkcs1pad_verify(struct akcipher_request *req) | |||
518 | static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) | 622 | static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) |
519 | { | 623 | { |
520 | struct akcipher_instance *inst = akcipher_alg_instance(tfm); | 624 | struct akcipher_instance *inst = akcipher_alg_instance(tfm); |
625 | struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); | ||
521 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); | 626 | struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); |
522 | struct crypto_akcipher *child_tfm; | 627 | struct crypto_akcipher *child_tfm; |
523 | 628 | ||
@@ -526,7 +631,7 @@ static int pkcs1pad_init_tfm(struct crypto_akcipher *tfm) | |||
526 | return PTR_ERR(child_tfm); | 631 | return PTR_ERR(child_tfm); |
527 | 632 | ||
528 | ctx->child = child_tfm; | 633 | ctx->child = child_tfm; |
529 | 634 | ctx->hash_name = ictx->hash_name; | |
530 | return 0; | 635 | return 0; |
531 | } | 636 | } |
532 | 637 | ||
@@ -539,10 +644,11 @@ static void pkcs1pad_exit_tfm(struct crypto_akcipher *tfm) | |||
539 | 644 | ||
540 | static void pkcs1pad_free(struct akcipher_instance *inst) | 645 | static void pkcs1pad_free(struct akcipher_instance *inst) |
541 | { | 646 | { |
542 | struct crypto_akcipher_spawn *spawn = akcipher_instance_ctx(inst); | 647 | struct pkcs1pad_inst_ctx *ctx = akcipher_instance_ctx(inst); |
648 | struct crypto_akcipher_spawn *spawn = &ctx->spawn; | ||
543 | 649 | ||
544 | crypto_drop_akcipher(spawn); | 650 | crypto_drop_akcipher(spawn); |
545 | 651 | kfree(ctx->hash_name); | |
546 | kfree(inst); | 652 | kfree(inst); |
547 | } | 653 | } |
548 | 654 | ||
@@ -550,9 +656,11 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
550 | { | 656 | { |
551 | struct crypto_attr_type *algt; | 657 | struct crypto_attr_type *algt; |
552 | struct akcipher_instance *inst; | 658 | struct akcipher_instance *inst; |
659 | struct pkcs1pad_inst_ctx *ctx; | ||
553 | struct crypto_akcipher_spawn *spawn; | 660 | struct crypto_akcipher_spawn *spawn; |
554 | struct akcipher_alg *rsa_alg; | 661 | struct akcipher_alg *rsa_alg; |
555 | const char *rsa_alg_name; | 662 | const char *rsa_alg_name; |
663 | const char *hash_name; | ||
556 | int err; | 664 | int err; |
557 | 665 | ||
558 | algt = crypto_get_attr_type(tb); | 666 | algt = crypto_get_attr_type(tb); |
@@ -566,11 +674,18 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
566 | if (IS_ERR(rsa_alg_name)) | 674 | if (IS_ERR(rsa_alg_name)) |
567 | return PTR_ERR(rsa_alg_name); | 675 | return PTR_ERR(rsa_alg_name); |
568 | 676 | ||
569 | inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); | 677 | hash_name = crypto_attr_alg_name(tb[2]); |
678 | if (IS_ERR(hash_name)) | ||
679 | hash_name = NULL; | ||
680 | |||
681 | inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); | ||
570 | if (!inst) | 682 | if (!inst) |
571 | return -ENOMEM; | 683 | return -ENOMEM; |
572 | 684 | ||
573 | spawn = akcipher_instance_ctx(inst); | 685 | ctx = akcipher_instance_ctx(inst); |
686 | spawn = &ctx->spawn; | ||
687 | ctx->hash_name = hash_name ? kstrdup(hash_name, GFP_KERNEL) : NULL; | ||
688 | |||
574 | crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst)); | 689 | crypto_set_spawn(&spawn->base, akcipher_crypto_instance(inst)); |
575 | err = crypto_grab_akcipher(spawn, rsa_alg_name, 0, | 690 | err = crypto_grab_akcipher(spawn, rsa_alg_name, 0, |
576 | crypto_requires_sync(algt->type, algt->mask)); | 691 | crypto_requires_sync(algt->type, algt->mask)); |
@@ -580,15 +695,28 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
580 | rsa_alg = crypto_spawn_akcipher_alg(spawn); | 695 | rsa_alg = crypto_spawn_akcipher_alg(spawn); |
581 | 696 | ||
582 | err = -ENAMETOOLONG; | 697 | err = -ENAMETOOLONG; |
583 | if (snprintf(inst->alg.base.cra_name, | 698 | |
584 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", | 699 | if (!hash_name) { |
585 | rsa_alg->base.cra_name) >= | 700 | if (snprintf(inst->alg.base.cra_name, |
586 | CRYPTO_MAX_ALG_NAME || | 701 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", |
587 | snprintf(inst->alg.base.cra_driver_name, | 702 | rsa_alg->base.cra_name) >= |
588 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", | 703 | CRYPTO_MAX_ALG_NAME || |
589 | rsa_alg->base.cra_driver_name) >= | 704 | snprintf(inst->alg.base.cra_driver_name, |
590 | CRYPTO_MAX_ALG_NAME) | 705 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", |
706 | rsa_alg->base.cra_driver_name) >= | ||
707 | CRYPTO_MAX_ALG_NAME) | ||
591 | goto out_drop_alg; | 708 | goto out_drop_alg; |
709 | } else { | ||
710 | if (snprintf(inst->alg.base.cra_name, | ||
711 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", | ||
712 | rsa_alg->base.cra_name, hash_name) >= | ||
713 | CRYPTO_MAX_ALG_NAME || | ||
714 | snprintf(inst->alg.base.cra_driver_name, | ||
715 | CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", | ||
716 | rsa_alg->base.cra_driver_name, hash_name) >= | ||
717 | CRYPTO_MAX_ALG_NAME) | ||
718 | goto out_free_hash; | ||
719 | } | ||
592 | 720 | ||
593 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; | 721 | inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC; |
594 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; | 722 | inst->alg.base.cra_priority = rsa_alg->base.cra_priority; |
@@ -610,10 +738,12 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
610 | 738 | ||
611 | err = akcipher_register_instance(tmpl, inst); | 739 | err = akcipher_register_instance(tmpl, inst); |
612 | if (err) | 740 | if (err) |
613 | goto out_drop_alg; | 741 | goto out_free_hash; |
614 | 742 | ||
615 | return 0; | 743 | return 0; |
616 | 744 | ||
745 | out_free_hash: | ||
746 | kfree(ctx->hash_name); | ||
617 | out_drop_alg: | 747 | out_drop_alg: |
618 | crypto_drop_akcipher(spawn); | 748 | crypto_drop_akcipher(spawn); |
619 | out_free_inst: | 749 | out_free_inst: |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b9250e564ebf..f3f7215ad378 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/file.h> | 24 | #include <linux/file.h> |
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/fs.h> | ||
26 | #include <linux/async.h> | 27 | #include <linux/async.h> |
27 | #include <linux/pm.h> | 28 | #include <linux/pm.h> |
28 | #include <linux/suspend.h> | 29 | #include <linux/suspend.h> |
@@ -291,40 +292,19 @@ static const char * const fw_path[] = { | |||
291 | module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); | 292 | module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); |
292 | MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); | 293 | MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); |
293 | 294 | ||
294 | static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | 295 | static void fw_finish_direct_load(struct device *device, |
296 | struct firmware_buf *buf) | ||
295 | { | 297 | { |
296 | int size; | 298 | mutex_lock(&fw_lock); |
297 | char *buf; | 299 | set_bit(FW_STATUS_DONE, &buf->status); |
298 | int rc; | 300 | complete_all(&buf->completion); |
299 | 301 | mutex_unlock(&fw_lock); | |
300 | if (!S_ISREG(file_inode(file)->i_mode)) | ||
301 | return -EINVAL; | ||
302 | size = i_size_read(file_inode(file)); | ||
303 | if (size <= 0) | ||
304 | return -EINVAL; | ||
305 | buf = vmalloc(size); | ||
306 | if (!buf) | ||
307 | return -ENOMEM; | ||
308 | rc = kernel_read(file, 0, buf, size); | ||
309 | if (rc != size) { | ||
310 | if (rc > 0) | ||
311 | rc = -EIO; | ||
312 | goto fail; | ||
313 | } | ||
314 | rc = security_kernel_fw_from_file(file, buf, size); | ||
315 | if (rc) | ||
316 | goto fail; | ||
317 | fw_buf->data = buf; | ||
318 | fw_buf->size = size; | ||
319 | return 0; | ||
320 | fail: | ||
321 | vfree(buf); | ||
322 | return rc; | ||
323 | } | 302 | } |
324 | 303 | ||
325 | static int fw_get_filesystem_firmware(struct device *device, | 304 | static int fw_get_filesystem_firmware(struct device *device, |
326 | struct firmware_buf *buf) | 305 | struct firmware_buf *buf) |
327 | { | 306 | { |
307 | loff_t size; | ||
328 | int i, len; | 308 | int i, len; |
329 | int rc = -ENOENT; | 309 | int rc = -ENOENT; |
330 | char *path; | 310 | char *path; |
@@ -334,8 +314,6 @@ static int fw_get_filesystem_firmware(struct device *device, | |||
334 | return -ENOMEM; | 314 | return -ENOMEM; |
335 | 315 | ||
336 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | 316 | for (i = 0; i < ARRAY_SIZE(fw_path); i++) { |
337 | struct file *file; | ||
338 | |||
339 | /* skip the unset customized path */ | 317 | /* skip the unset customized path */ |
340 | if (!fw_path[i][0]) | 318 | if (!fw_path[i][0]) |
341 | continue; | 319 | continue; |
@@ -347,28 +325,25 @@ static int fw_get_filesystem_firmware(struct device *device, | |||
347 | break; | 325 | break; |
348 | } | 326 | } |
349 | 327 | ||
350 | file = filp_open(path, O_RDONLY, 0); | 328 | buf->size = 0; |
351 | if (IS_ERR(file)) | 329 | rc = kernel_read_file_from_path(path, &buf->data, &size, |
330 | INT_MAX, READING_FIRMWARE); | ||
331 | if (rc) { | ||
332 | if (rc == -ENOENT) | ||
333 | dev_dbg(device, "loading %s failed with error %d\n", | ||
334 | path, rc); | ||
335 | else | ||
336 | dev_warn(device, "loading %s failed with error %d\n", | ||
337 | path, rc); | ||
352 | continue; | 338 | continue; |
353 | rc = fw_read_file_contents(file, buf); | 339 | } |
354 | fput(file); | 340 | dev_dbg(device, "direct-loading %s\n", buf->fw_id); |
355 | if (rc) | 341 | buf->size = size; |
356 | dev_warn(device, "firmware, attempted to load %s, but failed with error %d\n", | 342 | fw_finish_direct_load(device, buf); |
357 | path, rc); | 343 | break; |
358 | else | ||
359 | break; | ||
360 | } | 344 | } |
361 | __putname(path); | 345 | __putname(path); |
362 | 346 | ||
363 | if (!rc) { | ||
364 | dev_dbg(device, "firmware: direct-loading firmware %s\n", | ||
365 | buf->fw_id); | ||
366 | mutex_lock(&fw_lock); | ||
367 | set_bit(FW_STATUS_DONE, &buf->status); | ||
368 | complete_all(&buf->completion); | ||
369 | mutex_unlock(&fw_lock); | ||
370 | } | ||
371 | |||
372 | return rc; | 347 | return rc; |
373 | } | 348 | } |
374 | 349 | ||
@@ -685,8 +660,9 @@ static ssize_t firmware_loading_store(struct device *dev, | |||
685 | dev_err(dev, "%s: map pages failed\n", | 660 | dev_err(dev, "%s: map pages failed\n", |
686 | __func__); | 661 | __func__); |
687 | else | 662 | else |
688 | rc = security_kernel_fw_from_file(NULL, | 663 | rc = security_kernel_post_read_file(NULL, |
689 | fw_buf->data, fw_buf->size); | 664 | fw_buf->data, fw_buf->size, |
665 | READING_FIRMWARE); | ||
690 | 666 | ||
691 | /* | 667 | /* |
692 | * Same logic as fw_load_abort, only the DONE bit | 668 | * Same logic as fw_load_abort, only the DONE bit |
@@ -1051,7 +1027,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, | |||
1051 | } | 1027 | } |
1052 | 1028 | ||
1053 | if (fw_get_builtin_firmware(firmware, name)) { | 1029 | if (fw_get_builtin_firmware(firmware, name)) { |
1054 | dev_dbg(device, "firmware: using built-in firmware %s\n", name); | 1030 | dev_dbg(device, "using built-in %s\n", name); |
1055 | return 0; /* assigned */ | 1031 | return 0; /* assigned */ |
1056 | } | 1032 | } |
1057 | 1033 | ||
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 45cc39aabeee..274dd0123237 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
@@ -88,6 +88,7 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, | |||
88 | const struct tpm_class_ops *ops) | 88 | const struct tpm_class_ops *ops) |
89 | { | 89 | { |
90 | struct tpm_chip *chip; | 90 | struct tpm_chip *chip; |
91 | int rc; | ||
91 | 92 | ||
92 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 93 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
93 | if (chip == NULL) | 94 | if (chip == NULL) |
@@ -136,11 +137,17 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev, | |||
136 | chip->cdev.owner = chip->pdev->driver->owner; | 137 | chip->cdev.owner = chip->pdev->driver->owner; |
137 | chip->cdev.kobj.parent = &chip->dev.kobj; | 138 | chip->cdev.kobj.parent = &chip->dev.kobj; |
138 | 139 | ||
140 | rc = devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev); | ||
141 | if (rc) { | ||
142 | put_device(&chip->dev); | ||
143 | return ERR_PTR(rc); | ||
144 | } | ||
145 | |||
139 | return chip; | 146 | return chip; |
140 | } | 147 | } |
141 | EXPORT_SYMBOL_GPL(tpmm_chip_alloc); | 148 | EXPORT_SYMBOL_GPL(tpmm_chip_alloc); |
142 | 149 | ||
143 | static int tpm_dev_add_device(struct tpm_chip *chip) | 150 | static int tpm_add_char_device(struct tpm_chip *chip) |
144 | { | 151 | { |
145 | int rc; | 152 | int rc; |
146 | 153 | ||
@@ -151,7 +158,6 @@ static int tpm_dev_add_device(struct tpm_chip *chip) | |||
151 | chip->devname, MAJOR(chip->dev.devt), | 158 | chip->devname, MAJOR(chip->dev.devt), |
152 | MINOR(chip->dev.devt), rc); | 159 | MINOR(chip->dev.devt), rc); |
153 | 160 | ||
154 | device_unregister(&chip->dev); | ||
155 | return rc; | 161 | return rc; |
156 | } | 162 | } |
157 | 163 | ||
@@ -162,16 +168,17 @@ static int tpm_dev_add_device(struct tpm_chip *chip) | |||
162 | chip->devname, MAJOR(chip->dev.devt), | 168 | chip->devname, MAJOR(chip->dev.devt), |
163 | MINOR(chip->dev.devt), rc); | 169 | MINOR(chip->dev.devt), rc); |
164 | 170 | ||
171 | cdev_del(&chip->cdev); | ||
165 | return rc; | 172 | return rc; |
166 | } | 173 | } |
167 | 174 | ||
168 | return rc; | 175 | return rc; |
169 | } | 176 | } |
170 | 177 | ||
171 | static void tpm_dev_del_device(struct tpm_chip *chip) | 178 | static void tpm_del_char_device(struct tpm_chip *chip) |
172 | { | 179 | { |
173 | cdev_del(&chip->cdev); | 180 | cdev_del(&chip->cdev); |
174 | device_unregister(&chip->dev); | 181 | device_del(&chip->dev); |
175 | } | 182 | } |
176 | 183 | ||
177 | static int tpm1_chip_register(struct tpm_chip *chip) | 184 | static int tpm1_chip_register(struct tpm_chip *chip) |
@@ -222,7 +229,7 @@ int tpm_chip_register(struct tpm_chip *chip) | |||
222 | 229 | ||
223 | tpm_add_ppi(chip); | 230 | tpm_add_ppi(chip); |
224 | 231 | ||
225 | rc = tpm_dev_add_device(chip); | 232 | rc = tpm_add_char_device(chip); |
226 | if (rc) | 233 | if (rc) |
227 | goto out_err; | 234 | goto out_err; |
228 | 235 | ||
@@ -274,6 +281,6 @@ void tpm_chip_unregister(struct tpm_chip *chip) | |||
274 | sysfs_remove_link(&chip->pdev->kobj, "ppi"); | 281 | sysfs_remove_link(&chip->pdev->kobj, "ppi"); |
275 | 282 | ||
276 | tpm1_chip_unregister(chip); | 283 | tpm1_chip_unregister(chip); |
277 | tpm_dev_del_device(chip); | 284 | tpm_del_char_device(chip); |
278 | } | 285 | } |
279 | EXPORT_SYMBOL_GPL(tpm_chip_unregister); | 286 | EXPORT_SYMBOL_GPL(tpm_chip_unregister); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 542a80cbfd9c..28b477e8da6a 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -128,13 +128,6 @@ enum tpm2_startup_types { | |||
128 | TPM2_SU_STATE = 0x0001, | 128 | TPM2_SU_STATE = 0x0001, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | enum tpm2_start_method { | ||
132 | TPM2_START_ACPI = 2, | ||
133 | TPM2_START_FIFO = 6, | ||
134 | TPM2_START_CRB = 7, | ||
135 | TPM2_START_CRB_WITH_ACPI = 8, | ||
136 | }; | ||
137 | |||
138 | struct tpm_chip; | 131 | struct tpm_chip; |
139 | 132 | ||
140 | struct tpm_vendor_specific { | 133 | struct tpm_vendor_specific { |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 45a634016f95..b28e4da3d2cf 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
@@ -20,7 +20,11 @@ | |||
20 | #include <keys/trusted-type.h> | 20 | #include <keys/trusted-type.h> |
21 | 21 | ||
22 | enum tpm2_object_attributes { | 22 | enum tpm2_object_attributes { |
23 | TPM2_ATTR_USER_WITH_AUTH = BIT(6), | 23 | TPM2_OA_USER_WITH_AUTH = BIT(6), |
24 | }; | ||
25 | |||
26 | enum tpm2_session_attributes { | ||
27 | TPM2_SA_CONTINUE_SESSION = BIT(0), | ||
24 | }; | 28 | }; |
25 | 29 | ||
26 | struct tpm2_startup_in { | 30 | struct tpm2_startup_in { |
@@ -478,22 +482,18 @@ int tpm2_seal_trusted(struct tpm_chip *chip, | |||
478 | tpm_buf_append_u8(&buf, payload->migratable); | 482 | tpm_buf_append_u8(&buf, payload->migratable); |
479 | 483 | ||
480 | /* public */ | 484 | /* public */ |
481 | if (options->policydigest) | 485 | tpm_buf_append_u16(&buf, 14 + options->policydigest_len); |
482 | tpm_buf_append_u16(&buf, 14 + options->digest_len); | ||
483 | else | ||
484 | tpm_buf_append_u16(&buf, 14); | ||
485 | |||
486 | tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); | 486 | tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); |
487 | tpm_buf_append_u16(&buf, hash); | 487 | tpm_buf_append_u16(&buf, hash); |
488 | 488 | ||
489 | /* policy */ | 489 | /* policy */ |
490 | if (options->policydigest) { | 490 | if (options->policydigest_len) { |
491 | tpm_buf_append_u32(&buf, 0); | 491 | tpm_buf_append_u32(&buf, 0); |
492 | tpm_buf_append_u16(&buf, options->digest_len); | 492 | tpm_buf_append_u16(&buf, options->policydigest_len); |
493 | tpm_buf_append(&buf, options->policydigest, | 493 | tpm_buf_append(&buf, options->policydigest, |
494 | options->digest_len); | 494 | options->policydigest_len); |
495 | } else { | 495 | } else { |
496 | tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); | 496 | tpm_buf_append_u32(&buf, TPM2_OA_USER_WITH_AUTH); |
497 | tpm_buf_append_u16(&buf, 0); | 497 | tpm_buf_append_u16(&buf, 0); |
498 | } | 498 | } |
499 | 499 | ||
@@ -631,7 +631,7 @@ static int tpm2_unseal(struct tpm_chip *chip, | |||
631 | options->policyhandle ? | 631 | options->policyhandle ? |
632 | options->policyhandle : TPM2_RS_PW, | 632 | options->policyhandle : TPM2_RS_PW, |
633 | NULL /* nonce */, 0, | 633 | NULL /* nonce */, 0, |
634 | 0 /* session_attributes */, | 634 | TPM2_SA_CONTINUE_SESSION, |
635 | options->blobauth /* hmac */, | 635 | options->blobauth /* hmac */, |
636 | TPM_DIGEST_SIZE); | 636 | TPM_DIGEST_SIZE); |
637 | 637 | ||
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 8342cf51ffdc..a12b31940344 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c | |||
@@ -34,14 +34,6 @@ enum crb_defaults { | |||
34 | CRB_ACPI_START_INDEX = 1, | 34 | CRB_ACPI_START_INDEX = 1, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | struct acpi_tpm2 { | ||
38 | struct acpi_table_header hdr; | ||
39 | u16 platform_class; | ||
40 | u16 reserved; | ||
41 | u64 control_area_pa; | ||
42 | u32 start_method; | ||
43 | } __packed; | ||
44 | |||
45 | enum crb_ca_request { | 37 | enum crb_ca_request { |
46 | CRB_CA_REQ_GO_IDLE = BIT(0), | 38 | CRB_CA_REQ_GO_IDLE = BIT(0), |
47 | CRB_CA_REQ_CMD_READY = BIT(1), | 39 | CRB_CA_REQ_CMD_READY = BIT(1), |
@@ -85,6 +77,8 @@ enum crb_flags { | |||
85 | 77 | ||
86 | struct crb_priv { | 78 | struct crb_priv { |
87 | unsigned int flags; | 79 | unsigned int flags; |
80 | struct resource res; | ||
81 | void __iomem *iobase; | ||
88 | struct crb_control_area __iomem *cca; | 82 | struct crb_control_area __iomem *cca; |
89 | u8 __iomem *cmd; | 83 | u8 __iomem *cmd; |
90 | u8 __iomem *rsp; | 84 | u8 __iomem *rsp; |
@@ -97,7 +91,7 @@ static u8 crb_status(struct tpm_chip *chip) | |||
97 | struct crb_priv *priv = chip->vendor.priv; | 91 | struct crb_priv *priv = chip->vendor.priv; |
98 | u8 sts = 0; | 92 | u8 sts = 0; |
99 | 93 | ||
100 | if ((le32_to_cpu(ioread32(&priv->cca->start)) & CRB_START_INVOKE) != | 94 | if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) != |
101 | CRB_START_INVOKE) | 95 | CRB_START_INVOKE) |
102 | sts |= CRB_STS_COMPLETE; | 96 | sts |= CRB_STS_COMPLETE; |
103 | 97 | ||
@@ -113,7 +107,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
113 | if (count < 6) | 107 | if (count < 6) |
114 | return -EIO; | 108 | return -EIO; |
115 | 109 | ||
116 | if (le32_to_cpu(ioread32(&priv->cca->sts)) & CRB_CA_STS_ERROR) | 110 | if (ioread32(&priv->cca->sts) & CRB_CA_STS_ERROR) |
117 | return -EIO; | 111 | return -EIO; |
118 | 112 | ||
119 | memcpy_fromio(buf, priv->rsp, 6); | 113 | memcpy_fromio(buf, priv->rsp, 6); |
@@ -149,11 +143,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len) | |||
149 | struct crb_priv *priv = chip->vendor.priv; | 143 | struct crb_priv *priv = chip->vendor.priv; |
150 | int rc = 0; | 144 | int rc = 0; |
151 | 145 | ||
152 | if (len > le32_to_cpu(ioread32(&priv->cca->cmd_size))) { | 146 | if (len > ioread32(&priv->cca->cmd_size)) { |
153 | dev_err(&chip->dev, | 147 | dev_err(&chip->dev, |
154 | "invalid command count value %x %zx\n", | 148 | "invalid command count value %x %zx\n", |
155 | (unsigned int) len, | 149 | (unsigned int) len, |
156 | (size_t) le32_to_cpu(ioread32(&priv->cca->cmd_size))); | 150 | (size_t) ioread32(&priv->cca->cmd_size)); |
157 | return -E2BIG; | 151 | return -E2BIG; |
158 | } | 152 | } |
159 | 153 | ||
@@ -189,7 +183,7 @@ static void crb_cancel(struct tpm_chip *chip) | |||
189 | static bool crb_req_canceled(struct tpm_chip *chip, u8 status) | 183 | static bool crb_req_canceled(struct tpm_chip *chip, u8 status) |
190 | { | 184 | { |
191 | struct crb_priv *priv = chip->vendor.priv; | 185 | struct crb_priv *priv = chip->vendor.priv; |
192 | u32 cancel = le32_to_cpu(ioread32(&priv->cca->cancel)); | 186 | u32 cancel = ioread32(&priv->cca->cancel); |
193 | 187 | ||
194 | return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; | 188 | return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; |
195 | } | 189 | } |
@@ -204,97 +198,145 @@ static const struct tpm_class_ops tpm_crb = { | |||
204 | .req_complete_val = CRB_STS_COMPLETE, | 198 | .req_complete_val = CRB_STS_COMPLETE, |
205 | }; | 199 | }; |
206 | 200 | ||
207 | static int crb_acpi_add(struct acpi_device *device) | 201 | static int crb_init(struct acpi_device *device, struct crb_priv *priv) |
208 | { | 202 | { |
209 | struct tpm_chip *chip; | 203 | struct tpm_chip *chip; |
210 | struct acpi_tpm2 *buf; | 204 | int rc; |
205 | |||
206 | chip = tpmm_chip_alloc(&device->dev, &tpm_crb); | ||
207 | if (IS_ERR(chip)) | ||
208 | return PTR_ERR(chip); | ||
209 | |||
210 | chip->vendor.priv = priv; | ||
211 | chip->acpi_dev_handle = device->handle; | ||
212 | chip->flags = TPM_CHIP_FLAG_TPM2; | ||
213 | |||
214 | rc = tpm_get_timeouts(chip); | ||
215 | if (rc) | ||
216 | return rc; | ||
217 | |||
218 | rc = tpm2_do_selftest(chip); | ||
219 | if (rc) | ||
220 | return rc; | ||
221 | |||
222 | return tpm_chip_register(chip); | ||
223 | } | ||
224 | |||
225 | static int crb_check_resource(struct acpi_resource *ares, void *data) | ||
226 | { | ||
227 | struct crb_priv *priv = data; | ||
228 | struct resource res; | ||
229 | |||
230 | if (acpi_dev_resource_memory(ares, &res)) { | ||
231 | priv->res = res; | ||
232 | priv->res.name = NULL; | ||
233 | } | ||
234 | |||
235 | return 1; | ||
236 | } | ||
237 | |||
238 | static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv, | ||
239 | u64 start, u32 size) | ||
240 | { | ||
241 | struct resource new_res = { | ||
242 | .start = start, | ||
243 | .end = start + size - 1, | ||
244 | .flags = IORESOURCE_MEM, | ||
245 | }; | ||
246 | |||
247 | /* Detect a 64 bit address on a 32 bit system */ | ||
248 | if (start != new_res.start) | ||
249 | return ERR_PTR(-EINVAL); | ||
250 | |||
251 | if (!resource_contains(&priv->res, &new_res)) | ||
252 | return devm_ioremap_resource(dev, &new_res); | ||
253 | |||
254 | return priv->iobase + (new_res.start - priv->res.start); | ||
255 | } | ||
256 | |||
257 | static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, | ||
258 | struct acpi_table_tpm2 *buf) | ||
259 | { | ||
260 | struct list_head resources; | ||
261 | struct device *dev = &device->dev; | ||
262 | u64 pa; | ||
263 | int ret; | ||
264 | |||
265 | INIT_LIST_HEAD(&resources); | ||
266 | ret = acpi_dev_get_resources(device, &resources, crb_check_resource, | ||
267 | priv); | ||
268 | if (ret < 0) | ||
269 | return ret; | ||
270 | acpi_dev_free_resource_list(&resources); | ||
271 | |||
272 | if (resource_type(&priv->res) != IORESOURCE_MEM) { | ||
273 | dev_err(dev, | ||
274 | FW_BUG "TPM2 ACPI table does not define a memory resource\n"); | ||
275 | return -EINVAL; | ||
276 | } | ||
277 | |||
278 | priv->iobase = devm_ioremap_resource(dev, &priv->res); | ||
279 | if (IS_ERR(priv->iobase)) | ||
280 | return PTR_ERR(priv->iobase); | ||
281 | |||
282 | priv->cca = crb_map_res(dev, priv, buf->control_address, 0x1000); | ||
283 | if (IS_ERR(priv->cca)) | ||
284 | return PTR_ERR(priv->cca); | ||
285 | |||
286 | pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) | | ||
287 | (u64) ioread32(&priv->cca->cmd_pa_low); | ||
288 | priv->cmd = crb_map_res(dev, priv, pa, ioread32(&priv->cca->cmd_size)); | ||
289 | if (IS_ERR(priv->cmd)) | ||
290 | return PTR_ERR(priv->cmd); | ||
291 | |||
292 | memcpy_fromio(&pa, &priv->cca->rsp_pa, 8); | ||
293 | pa = le64_to_cpu(pa); | ||
294 | priv->rsp = crb_map_res(dev, priv, pa, ioread32(&priv->cca->rsp_size)); | ||
295 | return PTR_ERR_OR_ZERO(priv->rsp); | ||
296 | } | ||
297 | |||
298 | static int crb_acpi_add(struct acpi_device *device) | ||
299 | { | ||
300 | struct acpi_table_tpm2 *buf; | ||
211 | struct crb_priv *priv; | 301 | struct crb_priv *priv; |
212 | struct device *dev = &device->dev; | 302 | struct device *dev = &device->dev; |
213 | acpi_status status; | 303 | acpi_status status; |
214 | u32 sm; | 304 | u32 sm; |
215 | u64 pa; | ||
216 | int rc; | 305 | int rc; |
217 | 306 | ||
218 | status = acpi_get_table(ACPI_SIG_TPM2, 1, | 307 | status = acpi_get_table(ACPI_SIG_TPM2, 1, |
219 | (struct acpi_table_header **) &buf); | 308 | (struct acpi_table_header **) &buf); |
220 | if (ACPI_FAILURE(status)) { | 309 | if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) { |
221 | dev_err(dev, "failed to get TPM2 ACPI table\n"); | 310 | dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n"); |
222 | return -ENODEV; | 311 | return -EINVAL; |
223 | } | 312 | } |
224 | 313 | ||
225 | /* Should the FIFO driver handle this? */ | 314 | /* Should the FIFO driver handle this? */ |
226 | if (buf->start_method == TPM2_START_FIFO) | 315 | sm = buf->start_method; |
316 | if (sm == ACPI_TPM2_MEMORY_MAPPED) | ||
227 | return -ENODEV; | 317 | return -ENODEV; |
228 | 318 | ||
229 | chip = tpmm_chip_alloc(dev, &tpm_crb); | 319 | priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL); |
230 | if (IS_ERR(chip)) | 320 | if (!priv) |
231 | return PTR_ERR(chip); | ||
232 | |||
233 | chip->flags = TPM_CHIP_FLAG_TPM2; | ||
234 | |||
235 | if (buf->hdr.length < sizeof(struct acpi_tpm2)) { | ||
236 | dev_err(dev, "TPM2 ACPI table has wrong size"); | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | priv = (struct crb_priv *) devm_kzalloc(dev, sizeof(struct crb_priv), | ||
241 | GFP_KERNEL); | ||
242 | if (!priv) { | ||
243 | dev_err(dev, "failed to devm_kzalloc for private data\n"); | ||
244 | return -ENOMEM; | 321 | return -ENOMEM; |
245 | } | ||
246 | |||
247 | sm = le32_to_cpu(buf->start_method); | ||
248 | 322 | ||
249 | /* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs | 323 | /* The reason for the extra quirk is that the PTT in 4th Gen Core CPUs |
250 | * report only ACPI start but in practice seems to require both | 324 | * report only ACPI start but in practice seems to require both |
251 | * ACPI start and CRB start. | 325 | * ACPI start and CRB start. |
252 | */ | 326 | */ |
253 | if (sm == TPM2_START_CRB || sm == TPM2_START_FIFO || | 327 | if (sm == ACPI_TPM2_COMMAND_BUFFER || sm == ACPI_TPM2_MEMORY_MAPPED || |
254 | !strcmp(acpi_device_hid(device), "MSFT0101")) | 328 | !strcmp(acpi_device_hid(device), "MSFT0101")) |
255 | priv->flags |= CRB_FL_CRB_START; | 329 | priv->flags |= CRB_FL_CRB_START; |
256 | 330 | ||
257 | if (sm == TPM2_START_ACPI || sm == TPM2_START_CRB_WITH_ACPI) | 331 | if (sm == ACPI_TPM2_START_METHOD || |
332 | sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) | ||
258 | priv->flags |= CRB_FL_ACPI_START; | 333 | priv->flags |= CRB_FL_ACPI_START; |
259 | 334 | ||
260 | priv->cca = (struct crb_control_area __iomem *) | 335 | rc = crb_map_io(device, priv, buf); |
261 | devm_ioremap_nocache(dev, buf->control_area_pa, 0x1000); | ||
262 | if (!priv->cca) { | ||
263 | dev_err(dev, "ioremap of the control area failed\n"); | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | pa = ((u64) le32_to_cpu(ioread32(&priv->cca->cmd_pa_high)) << 32) | | ||
268 | (u64) le32_to_cpu(ioread32(&priv->cca->cmd_pa_low)); | ||
269 | priv->cmd = devm_ioremap_nocache(dev, pa, | ||
270 | ioread32(&priv->cca->cmd_size)); | ||
271 | if (!priv->cmd) { | ||
272 | dev_err(dev, "ioremap of the command buffer failed\n"); | ||
273 | return -ENOMEM; | ||
274 | } | ||
275 | |||
276 | memcpy_fromio(&pa, &priv->cca->rsp_pa, 8); | ||
277 | pa = le64_to_cpu(pa); | ||
278 | priv->rsp = devm_ioremap_nocache(dev, pa, | ||
279 | ioread32(&priv->cca->rsp_size)); | ||
280 | if (!priv->rsp) { | ||
281 | dev_err(dev, "ioremap of the response buffer failed\n"); | ||
282 | return -ENOMEM; | ||
283 | } | ||
284 | |||
285 | chip->vendor.priv = priv; | ||
286 | |||
287 | rc = tpm_get_timeouts(chip); | ||
288 | if (rc) | 336 | if (rc) |
289 | return rc; | 337 | return rc; |
290 | 338 | ||
291 | chip->acpi_dev_handle = device->handle; | 339 | return crb_init(device, priv); |
292 | |||
293 | rc = tpm2_do_selftest(chip); | ||
294 | if (rc) | ||
295 | return rc; | ||
296 | |||
297 | return tpm_chip_register(chip); | ||
298 | } | 340 | } |
299 | 341 | ||
300 | static int crb_acpi_remove(struct acpi_device *device) | 342 | static int crb_acpi_remove(struct acpi_device *device) |
@@ -302,11 +344,11 @@ static int crb_acpi_remove(struct acpi_device *device) | |||
302 | struct device *dev = &device->dev; | 344 | struct device *dev = &device->dev; |
303 | struct tpm_chip *chip = dev_get_drvdata(dev); | 345 | struct tpm_chip *chip = dev_get_drvdata(dev); |
304 | 346 | ||
305 | tpm_chip_unregister(chip); | ||
306 | |||
307 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | 347 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
308 | tpm2_shutdown(chip, TPM2_SU_CLEAR); | 348 | tpm2_shutdown(chip, TPM2_SU_CLEAR); |
309 | 349 | ||
350 | tpm_chip_unregister(chip); | ||
351 | |||
310 | return 0; | 352 | return 0; |
311 | } | 353 | } |
312 | 354 | ||
diff --git a/drivers/char/tpm/tpm_eventlog.c b/drivers/char/tpm/tpm_eventlog.c index bd72fb04225e..4e6940acf639 100644 --- a/drivers/char/tpm/tpm_eventlog.c +++ b/drivers/char/tpm/tpm_eventlog.c | |||
@@ -232,7 +232,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) | |||
232 | { | 232 | { |
233 | struct tcpa_event *event = v; | 233 | struct tcpa_event *event = v; |
234 | struct tcpa_event temp_event; | 234 | struct tcpa_event temp_event; |
235 | char *tempPtr; | 235 | char *temp_ptr; |
236 | int i; | 236 | int i; |
237 | 237 | ||
238 | memcpy(&temp_event, event, sizeof(struct tcpa_event)); | 238 | memcpy(&temp_event, event, sizeof(struct tcpa_event)); |
@@ -242,10 +242,16 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) | |||
242 | temp_event.event_type = do_endian_conversion(event->event_type); | 242 | temp_event.event_type = do_endian_conversion(event->event_type); |
243 | temp_event.event_size = do_endian_conversion(event->event_size); | 243 | temp_event.event_size = do_endian_conversion(event->event_size); |
244 | 244 | ||
245 | tempPtr = (char *)&temp_event; | 245 | temp_ptr = (char *) &temp_event; |
246 | 246 | ||
247 | for (i = 0; i < sizeof(struct tcpa_event) + temp_event.event_size; i++) | 247 | for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++) |
248 | seq_putc(m, tempPtr[i]); | 248 | seq_putc(m, temp_ptr[i]); |
249 | |||
250 | temp_ptr = (char *) v; | ||
251 | |||
252 | for (i = (sizeof(struct tcpa_event) - 1); | ||
253 | i < (sizeof(struct tcpa_event) + temp_event.event_size); i++) | ||
254 | seq_putc(m, temp_ptr[i]); | ||
249 | 255 | ||
250 | return 0; | 256 | return 0; |
251 | 257 | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 8a3509cb10da..a507006728e0 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
30 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
31 | #include <acpi/actbl2.h> | ||
32 | #include "tpm.h" | 31 | #include "tpm.h" |
33 | 32 | ||
34 | enum tis_access { | 33 | enum tis_access { |
@@ -60,22 +59,18 @@ enum tis_int_flags { | |||
60 | }; | 59 | }; |
61 | 60 | ||
62 | enum tis_defaults { | 61 | enum tis_defaults { |
63 | TIS_MEM_BASE = 0xFED40000, | ||
64 | TIS_MEM_LEN = 0x5000, | 62 | TIS_MEM_LEN = 0x5000, |
65 | TIS_SHORT_TIMEOUT = 750, /* ms */ | 63 | TIS_SHORT_TIMEOUT = 750, /* ms */ |
66 | TIS_LONG_TIMEOUT = 2000, /* 2 sec */ | 64 | TIS_LONG_TIMEOUT = 2000, /* 2 sec */ |
67 | }; | 65 | }; |
68 | 66 | ||
69 | struct tpm_info { | 67 | struct tpm_info { |
70 | unsigned long start; | 68 | struct resource res; |
71 | unsigned long len; | 69 | /* irq > 0 means: use irq $irq; |
72 | unsigned int irq; | 70 | * irq = 0 means: autoprobe for an irq; |
73 | }; | 71 | * irq = -1 means: no irq support |
74 | 72 | */ | |
75 | static struct tpm_info tis_default_info = { | 73 | int irq; |
76 | .start = TIS_MEM_BASE, | ||
77 | .len = TIS_MEM_LEN, | ||
78 | .irq = 0, | ||
79 | }; | 74 | }; |
80 | 75 | ||
81 | /* Some timeout values are needed before it is known whether the chip is | 76 | /* Some timeout values are needed before it is known whether the chip is |
@@ -118,39 +113,11 @@ static inline int is_itpm(struct acpi_device *dev) | |||
118 | { | 113 | { |
119 | return has_hid(dev, "INTC0102"); | 114 | return has_hid(dev, "INTC0102"); |
120 | } | 115 | } |
121 | |||
122 | static inline int is_fifo(struct acpi_device *dev) | ||
123 | { | ||
124 | struct acpi_table_tpm2 *tbl; | ||
125 | acpi_status st; | ||
126 | |||
127 | /* TPM 1.2 FIFO */ | ||
128 | if (!has_hid(dev, "MSFT0101")) | ||
129 | return 1; | ||
130 | |||
131 | st = acpi_get_table(ACPI_SIG_TPM2, 1, | ||
132 | (struct acpi_table_header **) &tbl); | ||
133 | if (ACPI_FAILURE(st)) { | ||
134 | dev_err(&dev->dev, "failed to get TPM2 ACPI table\n"); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | if (le32_to_cpu(tbl->start_method) != TPM2_START_FIFO) | ||
139 | return 0; | ||
140 | |||
141 | /* TPM 2.0 FIFO */ | ||
142 | return 1; | ||
143 | } | ||
144 | #else | 116 | #else |
145 | static inline int is_itpm(struct acpi_device *dev) | 117 | static inline int is_itpm(struct acpi_device *dev) |
146 | { | 118 | { |
147 | return 0; | 119 | return 0; |
148 | } | 120 | } |
149 | |||
150 | static inline int is_fifo(struct acpi_device *dev) | ||
151 | { | ||
152 | return 1; | ||
153 | } | ||
154 | #endif | 121 | #endif |
155 | 122 | ||
156 | /* Before we attempt to access the TPM we must see that the valid bit is set. | 123 | /* Before we attempt to access the TPM we must see that the valid bit is set. |
@@ -716,9 +683,9 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
716 | chip->acpi_dev_handle = acpi_dev_handle; | 683 | chip->acpi_dev_handle = acpi_dev_handle; |
717 | #endif | 684 | #endif |
718 | 685 | ||
719 | chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len); | 686 | chip->vendor.iobase = devm_ioremap_resource(dev, &tpm_info->res); |
720 | if (!chip->vendor.iobase) | 687 | if (IS_ERR(chip->vendor.iobase)) |
721 | return -EIO; | 688 | return PTR_ERR(chip->vendor.iobase); |
722 | 689 | ||
723 | /* Maximum timeouts */ | 690 | /* Maximum timeouts */ |
724 | chip->vendor.timeout_a = TIS_TIMEOUT_A_MAX; | 691 | chip->vendor.timeout_a = TIS_TIMEOUT_A_MAX; |
@@ -807,7 +774,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, | |||
807 | /* INTERRUPT Setup */ | 774 | /* INTERRUPT Setup */ |
808 | init_waitqueue_head(&chip->vendor.read_queue); | 775 | init_waitqueue_head(&chip->vendor.read_queue); |
809 | init_waitqueue_head(&chip->vendor.int_queue); | 776 | init_waitqueue_head(&chip->vendor.int_queue); |
810 | if (interrupts) { | 777 | if (interrupts && tpm_info->irq != -1) { |
811 | if (tpm_info->irq) { | 778 | if (tpm_info->irq) { |
812 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, | 779 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, |
813 | tpm_info->irq); | 780 | tpm_info->irq); |
@@ -893,29 +860,29 @@ static int tpm_tis_resume(struct device *dev) | |||
893 | 860 | ||
894 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); | 861 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); |
895 | 862 | ||
896 | #ifdef CONFIG_PNP | ||
897 | static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | 863 | static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, |
898 | const struct pnp_device_id *pnp_id) | 864 | const struct pnp_device_id *pnp_id) |
899 | { | 865 | { |
900 | struct tpm_info tpm_info = tis_default_info; | 866 | struct tpm_info tpm_info = {}; |
901 | acpi_handle acpi_dev_handle = NULL; | 867 | acpi_handle acpi_dev_handle = NULL; |
868 | struct resource *res; | ||
902 | 869 | ||
903 | tpm_info.start = pnp_mem_start(pnp_dev, 0); | 870 | res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0); |
904 | tpm_info.len = pnp_mem_len(pnp_dev, 0); | 871 | if (!res) |
872 | return -ENODEV; | ||
873 | tpm_info.res = *res; | ||
905 | 874 | ||
906 | if (pnp_irq_valid(pnp_dev, 0)) | 875 | if (pnp_irq_valid(pnp_dev, 0)) |
907 | tpm_info.irq = pnp_irq(pnp_dev, 0); | 876 | tpm_info.irq = pnp_irq(pnp_dev, 0); |
908 | else | 877 | else |
909 | interrupts = false; | 878 | tpm_info.irq = -1; |
910 | 879 | ||
911 | #ifdef CONFIG_ACPI | ||
912 | if (pnp_acpi_device(pnp_dev)) { | 880 | if (pnp_acpi_device(pnp_dev)) { |
913 | if (is_itpm(pnp_acpi_device(pnp_dev))) | 881 | if (is_itpm(pnp_acpi_device(pnp_dev))) |
914 | itpm = true; | 882 | itpm = true; |
915 | 883 | ||
916 | acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle; | 884 | acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev); |
917 | } | 885 | } |
918 | #endif | ||
919 | 886 | ||
920 | return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle); | 887 | return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle); |
921 | } | 888 | } |
@@ -956,7 +923,6 @@ static struct pnp_driver tis_pnp_driver = { | |||
956 | module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | 923 | module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, |
957 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); | 924 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); |
958 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 925 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
959 | #endif | ||
960 | 926 | ||
961 | #ifdef CONFIG_ACPI | 927 | #ifdef CONFIG_ACPI |
962 | static int tpm_check_resource(struct acpi_resource *ares, void *data) | 928 | static int tpm_check_resource(struct acpi_resource *ares, void *data) |
@@ -964,11 +930,11 @@ static int tpm_check_resource(struct acpi_resource *ares, void *data) | |||
964 | struct tpm_info *tpm_info = (struct tpm_info *) data; | 930 | struct tpm_info *tpm_info = (struct tpm_info *) data; |
965 | struct resource res; | 931 | struct resource res; |
966 | 932 | ||
967 | if (acpi_dev_resource_interrupt(ares, 0, &res)) { | 933 | if (acpi_dev_resource_interrupt(ares, 0, &res)) |
968 | tpm_info->irq = res.start; | 934 | tpm_info->irq = res.start; |
969 | } else if (acpi_dev_resource_memory(ares, &res)) { | 935 | else if (acpi_dev_resource_memory(ares, &res)) { |
970 | tpm_info->start = res.start; | 936 | tpm_info->res = res; |
971 | tpm_info->len = resource_size(&res); | 937 | tpm_info->res.name = NULL; |
972 | } | 938 | } |
973 | 939 | ||
974 | return 1; | 940 | return 1; |
@@ -976,14 +942,25 @@ static int tpm_check_resource(struct acpi_resource *ares, void *data) | |||
976 | 942 | ||
977 | static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) | 943 | static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) |
978 | { | 944 | { |
945 | struct acpi_table_tpm2 *tbl; | ||
946 | acpi_status st; | ||
979 | struct list_head resources; | 947 | struct list_head resources; |
980 | struct tpm_info tpm_info = tis_default_info; | 948 | struct tpm_info tpm_info = {}; |
981 | int ret; | 949 | int ret; |
982 | 950 | ||
983 | if (!is_fifo(acpi_dev)) | 951 | st = acpi_get_table(ACPI_SIG_TPM2, 1, |
952 | (struct acpi_table_header **) &tbl); | ||
953 | if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) { | ||
954 | dev_err(&acpi_dev->dev, | ||
955 | FW_BUG "failed to get TPM2 ACPI table\n"); | ||
956 | return -EINVAL; | ||
957 | } | ||
958 | |||
959 | if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED) | ||
984 | return -ENODEV; | 960 | return -ENODEV; |
985 | 961 | ||
986 | INIT_LIST_HEAD(&resources); | 962 | INIT_LIST_HEAD(&resources); |
963 | tpm_info.irq = -1; | ||
987 | ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource, | 964 | ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource, |
988 | &tpm_info); | 965 | &tpm_info); |
989 | if (ret < 0) | 966 | if (ret < 0) |
@@ -991,8 +968,11 @@ static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) | |||
991 | 968 | ||
992 | acpi_dev_free_resource_list(&resources); | 969 | acpi_dev_free_resource_list(&resources); |
993 | 970 | ||
994 | if (!tpm_info.irq) | 971 | if (resource_type(&tpm_info.res) != IORESOURCE_MEM) { |
995 | interrupts = false; | 972 | dev_err(&acpi_dev->dev, |
973 | FW_BUG "TPM2 ACPI table does not define a memory resource\n"); | ||
974 | return -EINVAL; | ||
975 | } | ||
996 | 976 | ||
997 | if (is_itpm(acpi_dev)) | 977 | if (is_itpm(acpi_dev)) |
998 | itpm = true; | 978 | itpm = true; |
@@ -1031,80 +1011,135 @@ static struct acpi_driver tis_acpi_driver = { | |||
1031 | }; | 1011 | }; |
1032 | #endif | 1012 | #endif |
1033 | 1013 | ||
1014 | static struct platform_device *force_pdev; | ||
1015 | |||
1016 | static int tpm_tis_plat_probe(struct platform_device *pdev) | ||
1017 | { | ||
1018 | struct tpm_info tpm_info = {}; | ||
1019 | struct resource *res; | ||
1020 | |||
1021 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1022 | if (res == NULL) { | ||
1023 | dev_err(&pdev->dev, "no memory resource defined\n"); | ||
1024 | return -ENODEV; | ||
1025 | } | ||
1026 | tpm_info.res = *res; | ||
1027 | |||
1028 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1029 | if (res) { | ||
1030 | tpm_info.irq = res->start; | ||
1031 | } else { | ||
1032 | if (pdev == force_pdev) | ||
1033 | tpm_info.irq = -1; | ||
1034 | else | ||
1035 | /* When forcing auto probe the IRQ */ | ||
1036 | tpm_info.irq = 0; | ||
1037 | } | ||
1038 | |||
1039 | return tpm_tis_init(&pdev->dev, &tpm_info, NULL); | ||
1040 | } | ||
1041 | |||
1042 | static int tpm_tis_plat_remove(struct platform_device *pdev) | ||
1043 | { | ||
1044 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); | ||
1045 | |||
1046 | tpm_chip_unregister(chip); | ||
1047 | tpm_tis_remove(chip); | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1034 | static struct platform_driver tis_drv = { | 1052 | static struct platform_driver tis_drv = { |
1053 | .probe = tpm_tis_plat_probe, | ||
1054 | .remove = tpm_tis_plat_remove, | ||
1035 | .driver = { | 1055 | .driver = { |
1036 | .name = "tpm_tis", | 1056 | .name = "tpm_tis", |
1037 | .pm = &tpm_tis_pm, | 1057 | .pm = &tpm_tis_pm, |
1038 | }, | 1058 | }, |
1039 | }; | 1059 | }; |
1040 | 1060 | ||
1041 | static struct platform_device *pdev; | ||
1042 | |||
1043 | static bool force; | 1061 | static bool force; |
1062 | #ifdef CONFIG_X86 | ||
1044 | module_param(force, bool, 0444); | 1063 | module_param(force, bool, 0444); |
1045 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); | 1064 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); |
1065 | #endif | ||
1066 | |||
1067 | static int tpm_tis_force_device(void) | ||
1068 | { | ||
1069 | struct platform_device *pdev; | ||
1070 | static const struct resource x86_resources[] = { | ||
1071 | { | ||
1072 | .start = 0xFED40000, | ||
1073 | .end = 0xFED40000 + TIS_MEM_LEN - 1, | ||
1074 | .flags = IORESOURCE_MEM, | ||
1075 | }, | ||
1076 | }; | ||
1077 | |||
1078 | if (!force) | ||
1079 | return 0; | ||
1080 | |||
1081 | /* The driver core will match the name tpm_tis of the device to | ||
1082 | * the tpm_tis platform driver and complete the setup via | ||
1083 | * tpm_tis_plat_probe | ||
1084 | */ | ||
1085 | pdev = platform_device_register_simple("tpm_tis", -1, x86_resources, | ||
1086 | ARRAY_SIZE(x86_resources)); | ||
1087 | if (IS_ERR(pdev)) | ||
1088 | return PTR_ERR(pdev); | ||
1089 | force_pdev = pdev; | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1046 | static int __init init_tis(void) | 1094 | static int __init init_tis(void) |
1047 | { | 1095 | { |
1048 | int rc; | 1096 | int rc; |
1049 | #ifdef CONFIG_PNP | 1097 | |
1050 | if (!force) { | 1098 | rc = tpm_tis_force_device(); |
1051 | rc = pnp_register_driver(&tis_pnp_driver); | 1099 | if (rc) |
1052 | if (rc) | 1100 | goto err_force; |
1053 | return rc; | 1101 | |
1054 | } | 1102 | rc = platform_driver_register(&tis_drv); |
1055 | #endif | 1103 | if (rc) |
1104 | goto err_platform; | ||
1105 | |||
1056 | #ifdef CONFIG_ACPI | 1106 | #ifdef CONFIG_ACPI |
1057 | if (!force) { | 1107 | rc = acpi_bus_register_driver(&tis_acpi_driver); |
1058 | rc = acpi_bus_register_driver(&tis_acpi_driver); | 1108 | if (rc) |
1059 | if (rc) { | 1109 | goto err_acpi; |
1060 | #ifdef CONFIG_PNP | ||
1061 | pnp_unregister_driver(&tis_pnp_driver); | ||
1062 | #endif | ||
1063 | return rc; | ||
1064 | } | ||
1065 | } | ||
1066 | #endif | 1110 | #endif |
1067 | if (!force) | ||
1068 | return 0; | ||
1069 | 1111 | ||
1070 | rc = platform_driver_register(&tis_drv); | 1112 | if (IS_ENABLED(CONFIG_PNP)) { |
1071 | if (rc < 0) | 1113 | rc = pnp_register_driver(&tis_pnp_driver); |
1072 | return rc; | 1114 | if (rc) |
1073 | pdev = platform_device_register_simple("tpm_tis", -1, NULL, 0); | 1115 | goto err_pnp; |
1074 | if (IS_ERR(pdev)) { | ||
1075 | rc = PTR_ERR(pdev); | ||
1076 | goto err_dev; | ||
1077 | } | 1116 | } |
1078 | rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL); | 1117 | |
1079 | if (rc) | ||
1080 | goto err_init; | ||
1081 | return 0; | 1118 | return 0; |
1082 | err_init: | 1119 | |
1083 | platform_device_unregister(pdev); | 1120 | err_pnp: |
1084 | err_dev: | 1121 | #ifdef CONFIG_ACPI |
1085 | platform_driver_unregister(&tis_drv); | 1122 | acpi_bus_unregister_driver(&tis_acpi_driver); |
1123 | err_acpi: | ||
1124 | #endif | ||
1125 | platform_device_unregister(force_pdev); | ||
1126 | err_platform: | ||
1127 | if (force_pdev) | ||
1128 | platform_device_unregister(force_pdev); | ||
1129 | err_force: | ||
1086 | return rc; | 1130 | return rc; |
1087 | } | 1131 | } |
1088 | 1132 | ||
1089 | static void __exit cleanup_tis(void) | 1133 | static void __exit cleanup_tis(void) |
1090 | { | 1134 | { |
1091 | struct tpm_chip *chip; | 1135 | pnp_unregister_driver(&tis_pnp_driver); |
1092 | #if defined(CONFIG_PNP) || defined(CONFIG_ACPI) | ||
1093 | if (!force) { | ||
1094 | #ifdef CONFIG_ACPI | 1136 | #ifdef CONFIG_ACPI |
1095 | acpi_bus_unregister_driver(&tis_acpi_driver); | 1137 | acpi_bus_unregister_driver(&tis_acpi_driver); |
1096 | #endif | ||
1097 | #ifdef CONFIG_PNP | ||
1098 | pnp_unregister_driver(&tis_pnp_driver); | ||
1099 | #endif | 1138 | #endif |
1100 | return; | ||
1101 | } | ||
1102 | #endif | ||
1103 | chip = dev_get_drvdata(&pdev->dev); | ||
1104 | tpm_chip_unregister(chip); | ||
1105 | tpm_tis_remove(chip); | ||
1106 | platform_device_unregister(pdev); | ||
1107 | platform_driver_unregister(&tis_drv); | 1139 | platform_driver_unregister(&tis_drv); |
1140 | |||
1141 | if (force_pdev) | ||
1142 | platform_device_unregister(force_pdev); | ||
1108 | } | 1143 | } |
1109 | 1144 | ||
1110 | module_init(init_tis); | 1145 | module_init(init_tis); |
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/pipe_fs_i.h> | 56 | #include <linux/pipe_fs_i.h> |
57 | #include <linux/oom.h> | 57 | #include <linux/oom.h> |
58 | #include <linux/compat.h> | 58 | #include <linux/compat.h> |
59 | #include <linux/vmalloc.h> | ||
59 | 60 | ||
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | #include <asm/mmu_context.h> | 62 | #include <asm/mmu_context.h> |
@@ -831,6 +832,97 @@ int kernel_read(struct file *file, loff_t offset, | |||
831 | 832 | ||
832 | EXPORT_SYMBOL(kernel_read); | 833 | EXPORT_SYMBOL(kernel_read); |
833 | 834 | ||
835 | int kernel_read_file(struct file *file, void **buf, loff_t *size, | ||
836 | loff_t max_size, enum kernel_read_file_id id) | ||
837 | { | ||
838 | loff_t i_size, pos; | ||
839 | ssize_t bytes = 0; | ||
840 | int ret; | ||
841 | |||
842 | if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0) | ||
843 | return -EINVAL; | ||
844 | |||
845 | ret = security_kernel_read_file(file, id); | ||
846 | if (ret) | ||
847 | return ret; | ||
848 | |||
849 | i_size = i_size_read(file_inode(file)); | ||
850 | if (max_size > 0 && i_size > max_size) | ||
851 | return -EFBIG; | ||
852 | if (i_size <= 0) | ||
853 | return -EINVAL; | ||
854 | |||
855 | *buf = vmalloc(i_size); | ||
856 | if (!*buf) | ||
857 | return -ENOMEM; | ||
858 | |||
859 | pos = 0; | ||
860 | while (pos < i_size) { | ||
861 | bytes = kernel_read(file, pos, (char *)(*buf) + pos, | ||
862 | i_size - pos); | ||
863 | if (bytes < 0) { | ||
864 | ret = bytes; | ||
865 | goto out; | ||
866 | } | ||
867 | |||
868 | if (bytes == 0) | ||
869 | break; | ||
870 | pos += bytes; | ||
871 | } | ||
872 | |||
873 | if (pos != i_size) { | ||
874 | ret = -EIO; | ||
875 | goto out; | ||
876 | } | ||
877 | |||
878 | ret = security_kernel_post_read_file(file, *buf, i_size, id); | ||
879 | if (!ret) | ||
880 | *size = pos; | ||
881 | |||
882 | out: | ||
883 | if (ret < 0) { | ||
884 | vfree(*buf); | ||
885 | *buf = NULL; | ||
886 | } | ||
887 | return ret; | ||
888 | } | ||
889 | EXPORT_SYMBOL_GPL(kernel_read_file); | ||
890 | |||
891 | int kernel_read_file_from_path(char *path, void **buf, loff_t *size, | ||
892 | loff_t max_size, enum kernel_read_file_id id) | ||
893 | { | ||
894 | struct file *file; | ||
895 | int ret; | ||
896 | |||
897 | if (!path || !*path) | ||
898 | return -EINVAL; | ||
899 | |||
900 | file = filp_open(path, O_RDONLY, 0); | ||
901 | if (IS_ERR(file)) | ||
902 | return PTR_ERR(file); | ||
903 | |||
904 | ret = kernel_read_file(file, buf, size, max_size, id); | ||
905 | fput(file); | ||
906 | return ret; | ||
907 | } | ||
908 | EXPORT_SYMBOL_GPL(kernel_read_file_from_path); | ||
909 | |||
910 | int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size, | ||
911 | enum kernel_read_file_id id) | ||
912 | { | ||
913 | struct fd f = fdget(fd); | ||
914 | int ret = -EBADF; | ||
915 | |||
916 | if (!f.file) | ||
917 | goto out; | ||
918 | |||
919 | ret = kernel_read_file(f.file, buf, size, max_size, id); | ||
920 | out: | ||
921 | fdput(f); | ||
922 | return ret; | ||
923 | } | ||
924 | EXPORT_SYMBOL_GPL(kernel_read_file_from_fd); | ||
925 | |||
834 | ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len) | 926 | ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len) |
835 | { | 927 | { |
836 | ssize_t res = vfs_read(file, (void __user *)addr, len, &pos); | 928 | ssize_t res = vfs_read(file, (void __user *)addr, len, &pos); |
diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index cc2516df0efa..aa730ea7faf8 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h | |||
@@ -14,30 +14,6 @@ | |||
14 | #ifndef _LINUX_PUBLIC_KEY_H | 14 | #ifndef _LINUX_PUBLIC_KEY_H |
15 | #define _LINUX_PUBLIC_KEY_H | 15 | #define _LINUX_PUBLIC_KEY_H |
16 | 16 | ||
17 | #include <linux/mpi.h> | ||
18 | #include <crypto/hash_info.h> | ||
19 | |||
20 | enum pkey_algo { | ||
21 | PKEY_ALGO_DSA, | ||
22 | PKEY_ALGO_RSA, | ||
23 | PKEY_ALGO__LAST | ||
24 | }; | ||
25 | |||
26 | extern const char *const pkey_algo_name[PKEY_ALGO__LAST]; | ||
27 | extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST]; | ||
28 | |||
29 | /* asymmetric key implementation supports only up to SHA224 */ | ||
30 | #define PKEY_HASH__LAST (HASH_ALGO_SHA224 + 1) | ||
31 | |||
32 | enum pkey_id_type { | ||
33 | PKEY_ID_PGP, /* OpenPGP generated key ID */ | ||
34 | PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ | ||
35 | PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ | ||
36 | PKEY_ID_TYPE__LAST | ||
37 | }; | ||
38 | |||
39 | extern const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST]; | ||
40 | |||
41 | /* | 17 | /* |
42 | * The use to which an asymmetric key is being put. | 18 | * The use to which an asymmetric key is being put. |
43 | */ | 19 | */ |
@@ -59,31 +35,10 @@ extern const char *const key_being_used_for[NR__KEY_BEING_USED_FOR]; | |||
59 | * part. | 35 | * part. |
60 | */ | 36 | */ |
61 | struct public_key { | 37 | struct public_key { |
62 | const struct public_key_algorithm *algo; | 38 | void *key; |
63 | u8 capabilities; | 39 | u32 keylen; |
64 | #define PKEY_CAN_ENCRYPT 0x01 | 40 | const char *id_type; |
65 | #define PKEY_CAN_DECRYPT 0x02 | 41 | const char *pkey_algo; |
66 | #define PKEY_CAN_SIGN 0x04 | ||
67 | #define PKEY_CAN_VERIFY 0x08 | ||
68 | enum pkey_algo pkey_algo : 8; | ||
69 | enum pkey_id_type id_type : 8; | ||
70 | union { | ||
71 | MPI mpi[5]; | ||
72 | struct { | ||
73 | MPI p; /* DSA prime */ | ||
74 | MPI q; /* DSA group order */ | ||
75 | MPI g; /* DSA group generator */ | ||
76 | MPI y; /* DSA public-key value = g^x mod p */ | ||
77 | MPI x; /* DSA secret exponent (if present) */ | ||
78 | } dsa; | ||
79 | struct { | ||
80 | MPI n; /* RSA public modulus */ | ||
81 | MPI e; /* RSA public encryption exponent */ | ||
82 | MPI d; /* RSA secret encryption exponent (if present) */ | ||
83 | MPI p; /* RSA secret prime (if present) */ | ||
84 | MPI q; /* RSA secret prime (if present) */ | ||
85 | } rsa; | ||
86 | }; | ||
87 | }; | 42 | }; |
88 | 43 | ||
89 | extern void public_key_destroy(void *payload); | 44 | extern void public_key_destroy(void *payload); |
@@ -92,23 +47,15 @@ extern void public_key_destroy(void *payload); | |||
92 | * Public key cryptography signature data | 47 | * Public key cryptography signature data |
93 | */ | 48 | */ |
94 | struct public_key_signature { | 49 | struct public_key_signature { |
50 | u8 *s; /* Signature */ | ||
51 | u32 s_size; /* Number of bytes in signature */ | ||
95 | u8 *digest; | 52 | u8 *digest; |
96 | u8 digest_size; /* Number of bytes in digest */ | 53 | u8 digest_size; /* Number of bytes in digest */ |
97 | u8 nr_mpi; /* Occupancy of mpi[] */ | 54 | const char *pkey_algo; |
98 | enum pkey_algo pkey_algo : 8; | 55 | const char *hash_algo; |
99 | enum hash_algo pkey_hash_algo : 8; | ||
100 | union { | ||
101 | MPI mpi[2]; | ||
102 | struct { | ||
103 | MPI s; /* m^d mod n */ | ||
104 | } rsa; | ||
105 | struct { | ||
106 | MPI r; | ||
107 | MPI s; | ||
108 | } dsa; | ||
109 | }; | ||
110 | }; | 56 | }; |
111 | 57 | ||
58 | extern struct asymmetric_key_subtype public_key_subtype; | ||
112 | struct key; | 59 | struct key; |
113 | extern int verify_signature(const struct key *key, | 60 | extern int verify_signature(const struct key *key, |
114 | const struct public_key_signature *sig); | 61 | const struct public_key_signature *sig); |
@@ -119,4 +66,7 @@ extern struct key *x509_request_asymmetric_key(struct key *keyring, | |||
119 | const struct asymmetric_key_id *skid, | 66 | const struct asymmetric_key_id *skid, |
120 | bool partial); | 67 | bool partial); |
121 | 68 | ||
69 | int public_key_verify_signature(const struct public_key *pkey, | ||
70 | const struct public_key_signature *sig); | ||
71 | |||
122 | #endif /* _LINUX_PUBLIC_KEY_H */ | 72 | #endif /* _LINUX_PUBLIC_KEY_H */ |
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h index 42cf2d991bf4..4ea7e55f20b0 100644 --- a/include/keys/trusted-type.h +++ b/include/keys/trusted-type.h | |||
@@ -38,7 +38,7 @@ struct trusted_key_options { | |||
38 | unsigned char pcrinfo[MAX_PCRINFO_SIZE]; | 38 | unsigned char pcrinfo[MAX_PCRINFO_SIZE]; |
39 | int pcrlock; | 39 | int pcrlock; |
40 | uint32_t hash; | 40 | uint32_t hash; |
41 | uint32_t digest_len; | 41 | uint32_t policydigest_len; |
42 | unsigned char policydigest[MAX_DIGEST_SIZE]; | 42 | unsigned char policydigest[MAX_DIGEST_SIZE]; |
43 | uint32_t policyhandle; | 43 | uint32_t policyhandle; |
44 | }; | 44 | }; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index ae681002100a..e514f76db04f 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2576,7 +2576,22 @@ static inline void i_readcount_inc(struct inode *inode) | |||
2576 | #endif | 2576 | #endif |
2577 | extern int do_pipe_flags(int *, int); | 2577 | extern int do_pipe_flags(int *, int); |
2578 | 2578 | ||
2579 | enum kernel_read_file_id { | ||
2580 | READING_FIRMWARE = 1, | ||
2581 | READING_MODULE, | ||
2582 | READING_KEXEC_IMAGE, | ||
2583 | READING_KEXEC_INITRAMFS, | ||
2584 | READING_POLICY, | ||
2585 | READING_MAX_ID | ||
2586 | }; | ||
2587 | |||
2579 | extern int kernel_read(struct file *, loff_t, char *, unsigned long); | 2588 | extern int kernel_read(struct file *, loff_t, char *, unsigned long); |
2589 | extern int kernel_read_file(struct file *, void **, loff_t *, loff_t, | ||
2590 | enum kernel_read_file_id); | ||
2591 | extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t, | ||
2592 | enum kernel_read_file_id); | ||
2593 | extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t, | ||
2594 | enum kernel_read_file_id); | ||
2580 | extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t); | 2595 | extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t); |
2581 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); | 2596 | extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *); |
2582 | extern struct file * open_exec(const char *); | 2597 | extern struct file * open_exec(const char *); |
diff --git a/include/linux/ima.h b/include/linux/ima.h index 120ccc53fcb7..e6516cbbe9bf 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -18,8 +18,9 @@ extern int ima_bprm_check(struct linux_binprm *bprm); | |||
18 | extern int ima_file_check(struct file *file, int mask, int opened); | 18 | extern int ima_file_check(struct file *file, int mask, int opened); |
19 | extern void ima_file_free(struct file *file); | 19 | extern void ima_file_free(struct file *file); |
20 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 20 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
21 | extern int ima_module_check(struct file *file); | 21 | extern int ima_read_file(struct file *file, enum kernel_read_file_id id); |
22 | extern int ima_fw_from_file(struct file *file, char *buf, size_t size); | 22 | extern int ima_post_read_file(struct file *file, void *buf, loff_t size, |
23 | enum kernel_read_file_id id); | ||
23 | 24 | ||
24 | #else | 25 | #else |
25 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 26 | static inline int ima_bprm_check(struct linux_binprm *bprm) |
@@ -42,12 +43,13 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot) | |||
42 | return 0; | 43 | return 0; |
43 | } | 44 | } |
44 | 45 | ||
45 | static inline int ima_module_check(struct file *file) | 46 | static inline int ima_read_file(struct file *file, enum kernel_read_file_id id) |
46 | { | 47 | { |
47 | return 0; | 48 | return 0; |
48 | } | 49 | } |
49 | 50 | ||
50 | static inline int ima_fw_from_file(struct file *file, char *buf, size_t size) | 51 | static inline int ima_post_read_file(struct file *file, void *buf, loff_t size, |
52 | enum kernel_read_file_id id) | ||
51 | { | 53 | { |
52 | return 0; | 54 | return 0; |
53 | } | 55 | } |
diff --git a/include/linux/key.h b/include/linux/key.h index 7321ab8ef949..5f5b1129dc92 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -219,6 +219,7 @@ extern struct key *key_alloc(struct key_type *type, | |||
219 | #define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ | 219 | #define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ |
220 | #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ | 220 | #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ |
221 | #define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ | 221 | #define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ |
222 | #define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */ | ||
222 | 223 | ||
223 | extern void key_revoke(struct key *key); | 224 | extern void key_revoke(struct key *key); |
224 | extern void key_invalidate(struct key *key); | 225 | extern void key_invalidate(struct key *key); |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 71969de4058c..cdee11cbcdf1 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -541,25 +541,24 @@ | |||
541 | * @inode points to the inode to use as a reference. | 541 | * @inode points to the inode to use as a reference. |
542 | * The current task must be the one that nominated @inode. | 542 | * The current task must be the one that nominated @inode. |
543 | * Return 0 if successful. | 543 | * Return 0 if successful. |
544 | * @kernel_fw_from_file: | ||
545 | * Load firmware from userspace (not called for built-in firmware). | ||
546 | * @file contains the file structure pointing to the file containing | ||
547 | * the firmware to load. This argument will be NULL if the firmware | ||
548 | * was loaded via the uevent-triggered blob-based interface exposed | ||
549 | * by CONFIG_FW_LOADER_USER_HELPER. | ||
550 | * @buf pointer to buffer containing firmware contents. | ||
551 | * @size length of the firmware contents. | ||
552 | * Return 0 if permission is granted. | ||
553 | * @kernel_module_request: | 544 | * @kernel_module_request: |
554 | * Ability to trigger the kernel to automatically upcall to userspace for | 545 | * Ability to trigger the kernel to automatically upcall to userspace for |
555 | * userspace to load a kernel module with the given name. | 546 | * userspace to load a kernel module with the given name. |
556 | * @kmod_name name of the module requested by the kernel | 547 | * @kmod_name name of the module requested by the kernel |
557 | * Return 0 if successful. | 548 | * Return 0 if successful. |
558 | * @kernel_module_from_file: | 549 | * @kernel_read_file: |
559 | * Load a kernel module from userspace. | 550 | * Read a file specified by userspace. |
560 | * @file contains the file structure pointing to the file containing | 551 | * @file contains the file structure pointing to the file being read |
561 | * the kernel module to load. If the module is being loaded from a blob, | 552 | * by the kernel. |
562 | * this argument will be NULL. | 553 | * @id kernel read file identifier |
554 | * Return 0 if permission is granted. | ||
555 | * @kernel_post_read_file: | ||
556 | * Read a file specified by userspace. | ||
557 | * @file contains the file structure pointing to the file being read | ||
558 | * by the kernel. | ||
559 | * @buf pointer to buffer containing the file contents. | ||
560 | * @size length of the file contents. | ||
561 | * @id kernel read file identifier | ||
563 | * Return 0 if permission is granted. | 562 | * Return 0 if permission is granted. |
564 | * @task_fix_setuid: | 563 | * @task_fix_setuid: |
565 | * Update the module's state after setting one or more of the user | 564 | * Update the module's state after setting one or more of the user |
@@ -1454,9 +1453,11 @@ union security_list_options { | |||
1454 | void (*cred_transfer)(struct cred *new, const struct cred *old); | 1453 | void (*cred_transfer)(struct cred *new, const struct cred *old); |
1455 | int (*kernel_act_as)(struct cred *new, u32 secid); | 1454 | int (*kernel_act_as)(struct cred *new, u32 secid); |
1456 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); | 1455 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); |
1457 | int (*kernel_fw_from_file)(struct file *file, char *buf, size_t size); | ||
1458 | int (*kernel_module_request)(char *kmod_name); | 1456 | int (*kernel_module_request)(char *kmod_name); |
1459 | int (*kernel_module_from_file)(struct file *file); | 1457 | int (*kernel_module_from_file)(struct file *file); |
1458 | int (*kernel_read_file)(struct file *file, enum kernel_read_file_id id); | ||
1459 | int (*kernel_post_read_file)(struct file *file, char *buf, loff_t size, | ||
1460 | enum kernel_read_file_id id); | ||
1460 | int (*task_fix_setuid)(struct cred *new, const struct cred *old, | 1461 | int (*task_fix_setuid)(struct cred *new, const struct cred *old, |
1461 | int flags); | 1462 | int flags); |
1462 | int (*task_setpgid)(struct task_struct *p, pid_t pgid); | 1463 | int (*task_setpgid)(struct task_struct *p, pid_t pgid); |
@@ -1715,9 +1716,9 @@ struct security_hook_heads { | |||
1715 | struct list_head cred_transfer; | 1716 | struct list_head cred_transfer; |
1716 | struct list_head kernel_act_as; | 1717 | struct list_head kernel_act_as; |
1717 | struct list_head kernel_create_files_as; | 1718 | struct list_head kernel_create_files_as; |
1718 | struct list_head kernel_fw_from_file; | 1719 | struct list_head kernel_read_file; |
1720 | struct list_head kernel_post_read_file; | ||
1719 | struct list_head kernel_module_request; | 1721 | struct list_head kernel_module_request; |
1720 | struct list_head kernel_module_from_file; | ||
1721 | struct list_head task_fix_setuid; | 1722 | struct list_head task_fix_setuid; |
1722 | struct list_head task_setpgid; | 1723 | struct list_head task_setpgid; |
1723 | struct list_head task_getpgid; | 1724 | struct list_head task_getpgid; |
diff --git a/include/linux/security.h b/include/linux/security.h index 4824a4ccaf1c..157f0cb1e4d2 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -24,10 +24,12 @@ | |||
24 | 24 | ||
25 | #include <linux/key.h> | 25 | #include <linux/key.h> |
26 | #include <linux/capability.h> | 26 | #include <linux/capability.h> |
27 | #include <linux/fs.h> | ||
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
30 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
32 | #include <linux/fs.h> | ||
31 | 33 | ||
32 | struct linux_binprm; | 34 | struct linux_binprm; |
33 | struct cred; | 35 | struct cred; |
@@ -298,9 +300,11 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); | |||
298 | void security_transfer_creds(struct cred *new, const struct cred *old); | 300 | void security_transfer_creds(struct cred *new, const struct cred *old); |
299 | int security_kernel_act_as(struct cred *new, u32 secid); | 301 | int security_kernel_act_as(struct cred *new, u32 secid); |
300 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); | 302 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); |
301 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size); | ||
302 | int security_kernel_module_request(char *kmod_name); | 303 | int security_kernel_module_request(char *kmod_name); |
303 | int security_kernel_module_from_file(struct file *file); | 304 | int security_kernel_module_from_file(struct file *file); |
305 | int security_kernel_read_file(struct file *file, enum kernel_read_file_id id); | ||
306 | int security_kernel_post_read_file(struct file *file, char *buf, loff_t size, | ||
307 | enum kernel_read_file_id id); | ||
304 | int security_task_fix_setuid(struct cred *new, const struct cred *old, | 308 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
305 | int flags); | 309 | int flags); |
306 | int security_task_setpgid(struct task_struct *p, pid_t pgid); | 310 | int security_task_setpgid(struct task_struct *p, pid_t pgid); |
@@ -850,18 +854,20 @@ static inline int security_kernel_create_files_as(struct cred *cred, | |||
850 | return 0; | 854 | return 0; |
851 | } | 855 | } |
852 | 856 | ||
853 | static inline int security_kernel_fw_from_file(struct file *file, | 857 | static inline int security_kernel_module_request(char *kmod_name) |
854 | char *buf, size_t size) | ||
855 | { | 858 | { |
856 | return 0; | 859 | return 0; |
857 | } | 860 | } |
858 | 861 | ||
859 | static inline int security_kernel_module_request(char *kmod_name) | 862 | static inline int security_kernel_read_file(struct file *file, |
863 | enum kernel_read_file_id id) | ||
860 | { | 864 | { |
861 | return 0; | 865 | return 0; |
862 | } | 866 | } |
863 | 867 | ||
864 | static inline int security_kernel_module_from_file(struct file *file) | 868 | static inline int security_kernel_post_read_file(struct file *file, |
869 | char *buf, loff_t size, | ||
870 | enum kernel_read_file_id id) | ||
865 | { | 871 | { |
866 | return 0; | 872 | return 0; |
867 | } | 873 | } |
diff --git a/init/Kconfig b/init/Kconfig index fd664b3ab99e..2d70c8c4b1d8 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1779,9 +1779,9 @@ config SYSTEM_DATA_VERIFICATION | |||
1779 | select SYSTEM_TRUSTED_KEYRING | 1779 | select SYSTEM_TRUSTED_KEYRING |
1780 | select KEYS | 1780 | select KEYS |
1781 | select CRYPTO | 1781 | select CRYPTO |
1782 | select CRYPTO_RSA | ||
1782 | select ASYMMETRIC_KEY_TYPE | 1783 | select ASYMMETRIC_KEY_TYPE |
1783 | select ASYMMETRIC_PUBLIC_KEY_SUBTYPE | 1784 | select ASYMMETRIC_PUBLIC_KEY_SUBTYPE |
1784 | select PUBLIC_KEY_ALGO_RSA | ||
1785 | select ASN1 | 1785 | select ASN1 |
1786 | select OID_REGISTRY | 1786 | select OID_REGISTRY |
1787 | select X509_CERTIFICATE_PARSER | 1787 | select X509_CERTIFICATE_PARSER |
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index 56b18eb1f001..c72d2ff5896e 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/kexec.h> | 18 | #include <linux/kexec.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/fs.h> | ||
21 | #include <crypto/hash.h> | 22 | #include <crypto/hash.h> |
22 | #include <crypto/sha.h> | 23 | #include <crypto/sha.h> |
23 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
@@ -33,65 +34,6 @@ size_t __weak kexec_purgatory_size = 0; | |||
33 | 34 | ||
34 | static int kexec_calculate_store_digests(struct kimage *image); | 35 | static int kexec_calculate_store_digests(struct kimage *image); |
35 | 36 | ||
36 | static int copy_file_from_fd(int fd, void **buf, unsigned long *buf_len) | ||
37 | { | ||
38 | struct fd f = fdget(fd); | ||
39 | int ret; | ||
40 | struct kstat stat; | ||
41 | loff_t pos; | ||
42 | ssize_t bytes = 0; | ||
43 | |||
44 | if (!f.file) | ||
45 | return -EBADF; | ||
46 | |||
47 | ret = vfs_getattr(&f.file->f_path, &stat); | ||
48 | if (ret) | ||
49 | goto out; | ||
50 | |||
51 | if (stat.size > INT_MAX) { | ||
52 | ret = -EFBIG; | ||
53 | goto out; | ||
54 | } | ||
55 | |||
56 | /* Don't hand 0 to vmalloc, it whines. */ | ||
57 | if (stat.size == 0) { | ||
58 | ret = -EINVAL; | ||
59 | goto out; | ||
60 | } | ||
61 | |||
62 | *buf = vmalloc(stat.size); | ||
63 | if (!*buf) { | ||
64 | ret = -ENOMEM; | ||
65 | goto out; | ||
66 | } | ||
67 | |||
68 | pos = 0; | ||
69 | while (pos < stat.size) { | ||
70 | bytes = kernel_read(f.file, pos, (char *)(*buf) + pos, | ||
71 | stat.size - pos); | ||
72 | if (bytes < 0) { | ||
73 | vfree(*buf); | ||
74 | ret = bytes; | ||
75 | goto out; | ||
76 | } | ||
77 | |||
78 | if (bytes == 0) | ||
79 | break; | ||
80 | pos += bytes; | ||
81 | } | ||
82 | |||
83 | if (pos != stat.size) { | ||
84 | ret = -EBADF; | ||
85 | vfree(*buf); | ||
86 | goto out; | ||
87 | } | ||
88 | |||
89 | *buf_len = pos; | ||
90 | out: | ||
91 | fdput(f); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | /* Architectures can provide this probe function */ | 37 | /* Architectures can provide this probe function */ |
96 | int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, | 38 | int __weak arch_kexec_kernel_image_probe(struct kimage *image, void *buf, |
97 | unsigned long buf_len) | 39 | unsigned long buf_len) |
@@ -182,16 +124,17 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, | |||
182 | { | 124 | { |
183 | int ret = 0; | 125 | int ret = 0; |
184 | void *ldata; | 126 | void *ldata; |
127 | loff_t size; | ||
185 | 128 | ||
186 | ret = copy_file_from_fd(kernel_fd, &image->kernel_buf, | 129 | ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf, |
187 | &image->kernel_buf_len); | 130 | &size, INT_MAX, READING_KEXEC_IMAGE); |
188 | if (ret) | 131 | if (ret) |
189 | return ret; | 132 | return ret; |
133 | image->kernel_buf_len = size; | ||
190 | 134 | ||
191 | /* Call arch image probe handlers */ | 135 | /* Call arch image probe handlers */ |
192 | ret = arch_kexec_kernel_image_probe(image, image->kernel_buf, | 136 | ret = arch_kexec_kernel_image_probe(image, image->kernel_buf, |
193 | image->kernel_buf_len); | 137 | image->kernel_buf_len); |
194 | |||
195 | if (ret) | 138 | if (ret) |
196 | goto out; | 139 | goto out; |
197 | 140 | ||
@@ -206,10 +149,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, | |||
206 | #endif | 149 | #endif |
207 | /* It is possible that there no initramfs is being loaded */ | 150 | /* It is possible that there no initramfs is being loaded */ |
208 | if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { | 151 | if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { |
209 | ret = copy_file_from_fd(initrd_fd, &image->initrd_buf, | 152 | ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf, |
210 | &image->initrd_buf_len); | 153 | &size, INT_MAX, |
154 | READING_KEXEC_INITRAMFS); | ||
211 | if (ret) | 155 | if (ret) |
212 | goto out; | 156 | goto out; |
157 | image->initrd_buf_len = size; | ||
213 | } | 158 | } |
214 | 159 | ||
215 | if (cmdline_len) { | 160 | if (cmdline_len) { |
diff --git a/kernel/module.c b/kernel/module.c index 794ebe8e878d..87cfeb25cf65 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2675,7 +2675,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len, | |||
2675 | if (info->len < sizeof(*(info->hdr))) | 2675 | if (info->len < sizeof(*(info->hdr))) |
2676 | return -ENOEXEC; | 2676 | return -ENOEXEC; |
2677 | 2677 | ||
2678 | err = security_kernel_module_from_file(NULL); | 2678 | err = security_kernel_read_file(NULL, READING_MODULE); |
2679 | if (err) | 2679 | if (err) |
2680 | return err; | 2680 | return err; |
2681 | 2681 | ||
@@ -2693,63 +2693,6 @@ static int copy_module_from_user(const void __user *umod, unsigned long len, | |||
2693 | return 0; | 2693 | return 0; |
2694 | } | 2694 | } |
2695 | 2695 | ||
2696 | /* Sets info->hdr and info->len. */ | ||
2697 | static int copy_module_from_fd(int fd, struct load_info *info) | ||
2698 | { | ||
2699 | struct fd f = fdget(fd); | ||
2700 | int err; | ||
2701 | struct kstat stat; | ||
2702 | loff_t pos; | ||
2703 | ssize_t bytes = 0; | ||
2704 | |||
2705 | if (!f.file) | ||
2706 | return -ENOEXEC; | ||
2707 | |||
2708 | err = security_kernel_module_from_file(f.file); | ||
2709 | if (err) | ||
2710 | goto out; | ||
2711 | |||
2712 | err = vfs_getattr(&f.file->f_path, &stat); | ||
2713 | if (err) | ||
2714 | goto out; | ||
2715 | |||
2716 | if (stat.size > INT_MAX) { | ||
2717 | err = -EFBIG; | ||
2718 | goto out; | ||
2719 | } | ||
2720 | |||
2721 | /* Don't hand 0 to vmalloc, it whines. */ | ||
2722 | if (stat.size == 0) { | ||
2723 | err = -EINVAL; | ||
2724 | goto out; | ||
2725 | } | ||
2726 | |||
2727 | info->hdr = vmalloc(stat.size); | ||
2728 | if (!info->hdr) { | ||
2729 | err = -ENOMEM; | ||
2730 | goto out; | ||
2731 | } | ||
2732 | |||
2733 | pos = 0; | ||
2734 | while (pos < stat.size) { | ||
2735 | bytes = kernel_read(f.file, pos, (char *)(info->hdr) + pos, | ||
2736 | stat.size - pos); | ||
2737 | if (bytes < 0) { | ||
2738 | vfree(info->hdr); | ||
2739 | err = bytes; | ||
2740 | goto out; | ||
2741 | } | ||
2742 | if (bytes == 0) | ||
2743 | break; | ||
2744 | pos += bytes; | ||
2745 | } | ||
2746 | info->len = pos; | ||
2747 | |||
2748 | out: | ||
2749 | fdput(f); | ||
2750 | return err; | ||
2751 | } | ||
2752 | |||
2753 | static void free_copy(struct load_info *info) | 2696 | static void free_copy(struct load_info *info) |
2754 | { | 2697 | { |
2755 | vfree(info->hdr); | 2698 | vfree(info->hdr); |
@@ -3611,8 +3554,10 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, | |||
3611 | 3554 | ||
3612 | SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) | 3555 | SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) |
3613 | { | 3556 | { |
3614 | int err; | ||
3615 | struct load_info info = { }; | 3557 | struct load_info info = { }; |
3558 | loff_t size; | ||
3559 | void *hdr; | ||
3560 | int err; | ||
3616 | 3561 | ||
3617 | err = may_init_module(); | 3562 | err = may_init_module(); |
3618 | if (err) | 3563 | if (err) |
@@ -3624,9 +3569,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) | |||
3624 | |MODULE_INIT_IGNORE_VERMAGIC)) | 3569 | |MODULE_INIT_IGNORE_VERMAGIC)) |
3625 | return -EINVAL; | 3570 | return -EINVAL; |
3626 | 3571 | ||
3627 | err = copy_module_from_fd(fd, &info); | 3572 | err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX, |
3573 | READING_MODULE); | ||
3628 | if (err) | 3574 | if (err) |
3629 | return err; | 3575 | return err; |
3576 | info.hdr = hdr; | ||
3577 | info.len = size; | ||
3630 | 3578 | ||
3631 | return load_module(&info, uargs, flags); | 3579 | return load_module(&info, uargs, flags); |
3632 | } | 3580 | } |
diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 6528a79d998d..64b9dead4a07 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c | |||
@@ -11,10 +11,17 @@ | |||
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/string.h> | ||
14 | #include <keys/system_keyring.h> | 15 | #include <keys/system_keyring.h> |
15 | #include <crypto/public_key.h> | 16 | #include <crypto/public_key.h> |
16 | #include "module-internal.h" | 17 | #include "module-internal.h" |
17 | 18 | ||
19 | enum pkey_id_type { | ||
20 | PKEY_ID_PGP, /* OpenPGP generated key ID */ | ||
21 | PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ | ||
22 | PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ | ||
23 | }; | ||
24 | |||
18 | /* | 25 | /* |
19 | * Module signature information block. | 26 | * Module signature information block. |
20 | * | 27 | * |
diff --git a/kernel/time/time.c b/kernel/time/time.c index 86751c68e08d..be115b020d27 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c | |||
@@ -322,6 +322,13 @@ EXPORT_SYMBOL(timespec_trunc); | |||
322 | * -year/100+year/400 terms, and add 10.] | 322 | * -year/100+year/400 terms, and add 10.] |
323 | * | 323 | * |
324 | * This algorithm was first published by Gauss (I think). | 324 | * This algorithm was first published by Gauss (I think). |
325 | * | ||
326 | * A leap second can be indicated by calling this function with sec as | ||
327 | * 60 (allowable under ISO 8601). The leap second is treated the same | ||
328 | * as the following second since they don't exist in UNIX time. | ||
329 | * | ||
330 | * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight | ||
331 | * tomorrow - (allowable under ISO 8601) is supported. | ||
325 | */ | 332 | */ |
326 | time64_t mktime64(const unsigned int year0, const unsigned int mon0, | 333 | time64_t mktime64(const unsigned int year0, const unsigned int mon0, |
327 | const unsigned int day, const unsigned int hour, | 334 | const unsigned int day, const unsigned int hour, |
@@ -338,7 +345,7 @@ time64_t mktime64(const unsigned int year0, const unsigned int mon0, | |||
338 | return ((((time64_t) | 345 | return ((((time64_t) |
339 | (year/4 - year/100 + year/400 + 367*mon/12 + day) + | 346 | (year/4 - year/100 + year/400 + 367*mon/12 + day) + |
340 | year*365 - 719499 | 347 | year*365 - 719499 |
341 | )*24 + hour /* now have hours */ | 348 | )*24 + hour /* now have hours - midnight tomorrow handled here */ |
342 | )*60 + min /* now have minutes */ | 349 | )*60 + min /* now have minutes */ |
343 | )*60 + sec; /* finally seconds */ | 350 | )*60 + sec; /* finally seconds */ |
344 | } | 351 | } |
diff --git a/scripts/.gitignore b/scripts/.gitignore index 1f78169d4254..e063daa3ec4a 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore | |||
@@ -13,3 +13,4 @@ sortextable | |||
13 | asn1_compiler | 13 | asn1_compiler |
14 | extract-cert | 14 | extract-cert |
15 | sign-file | 15 | sign-file |
16 | insert-sys-cert | ||
diff --git a/scripts/Makefile b/scripts/Makefile index fd0d53d4a234..822ab4a6a4aa 100644 --- a/scripts/Makefile +++ b/scripts/Makefile | |||
@@ -19,6 +19,7 @@ hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable | |||
19 | hostprogs-$(CONFIG_ASN1) += asn1_compiler | 19 | hostprogs-$(CONFIG_ASN1) += asn1_compiler |
20 | hostprogs-$(CONFIG_MODULE_SIG) += sign-file | 20 | hostprogs-$(CONFIG_MODULE_SIG) += sign-file |
21 | hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert | 21 | hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert |
22 | hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert | ||
22 | 23 | ||
23 | HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include | 24 | HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include |
24 | HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include | 25 | HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include |
diff --git a/scripts/extract-sys-certs.pl b/scripts/extract-sys-certs.pl index d476e7d1fd88..8227ca10a494 100755 --- a/scripts/extract-sys-certs.pl +++ b/scripts/extract-sys-certs.pl | |||
@@ -91,13 +91,15 @@ print "Have $nr_symbols symbols\n"; | |||
91 | 91 | ||
92 | die "Can't find system certificate list" | 92 | die "Can't find system certificate list" |
93 | unless (exists($symbols{"__cert_list_start"}) && | 93 | unless (exists($symbols{"__cert_list_start"}) && |
94 | exists($symbols{"__cert_list_end"})); | 94 | exists($symbols{"system_certificate_list_size"})); |
95 | 95 | ||
96 | my $start = Math::BigInt->new($symbols{"__cert_list_start"}); | 96 | my $start = Math::BigInt->new($symbols{"__cert_list_start"}); |
97 | my $end = Math::BigInt->new($symbols{"__cert_list_end"}); | 97 | my $end; |
98 | my $size = $end - $start; | 98 | my $size; |
99 | my $size_sym = Math::BigInt->new($symbols{"system_certificate_list_size"}); | ||
99 | 100 | ||
100 | printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start; | 101 | open FD, "<$vmlinux" || die $vmlinux; |
102 | binmode(FD); | ||
101 | 103 | ||
102 | my $s = undef; | 104 | my $s = undef; |
103 | foreach my $sec (@sections) { | 105 | foreach my $sec (@sections) { |
@@ -110,11 +112,24 @@ foreach my $sec (@sections) { | |||
110 | next unless ($start >= $s_vma); | 112 | next unless ($start >= $s_vma); |
111 | next if ($start >= $s_vend); | 113 | next if ($start >= $s_vend); |
112 | 114 | ||
113 | die "Cert object partially overflows section $s_name\n" | 115 | die "Certificate list size was not found on the same section\n" |
114 | if ($end > $s_vend); | 116 | if ($size_sym < $s_vma || $size_sym > $s_vend); |
115 | 117 | ||
116 | die "Cert object in multiple sections: ", $s_name, " and ", $s->{name}, "\n" | 118 | die "Cert object in multiple sections: ", $s_name, " and ", $s->{name}, "\n" |
117 | if ($s); | 119 | if ($s); |
120 | |||
121 | my $size_off = $size_sym -$s_vma + $s_foff; | ||
122 | my $packed; | ||
123 | die $vmlinux if (!defined(sysseek(FD, $size_off, SEEK_SET))); | ||
124 | sysread(FD, $packed, 8); | ||
125 | $size = unpack 'L!', $packed; | ||
126 | $end = $start + $size; | ||
127 | |||
128 | printf "Have %u bytes of certs at VMA 0x%x\n", $size, $start; | ||
129 | |||
130 | die "Cert object partially overflows section $s_name\n" | ||
131 | if ($end > $s_vend); | ||
132 | |||
118 | $s = $sec; | 133 | $s = $sec; |
119 | } | 134 | } |
120 | 135 | ||
@@ -127,8 +142,6 @@ my $foff = $start - $s->{vma} + $s->{foff}; | |||
127 | 142 | ||
128 | printf "Certificate list at file offset 0x%x\n", $foff; | 143 | printf "Certificate list at file offset 0x%x\n", $foff; |
129 | 144 | ||
130 | open FD, "<$vmlinux" || die $vmlinux; | ||
131 | binmode(FD); | ||
132 | die $vmlinux if (!defined(sysseek(FD, $foff, SEEK_SET))); | 145 | die $vmlinux if (!defined(sysseek(FD, $foff, SEEK_SET))); |
133 | my $buf = ""; | 146 | my $buf = ""; |
134 | my $len = sysread(FD, $buf, $size); | 147 | my $len = sysread(FD, $buf, $size); |
diff --git a/scripts/insert-sys-cert.c b/scripts/insert-sys-cert.c new file mode 100644 index 000000000000..8902836c2342 --- /dev/null +++ b/scripts/insert-sys-cert.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /* Write the contents of the <certfile> into kernel symbol system_extra_cert | ||
2 | * | ||
3 | * Copyright (C) IBM Corporation, 2015 | ||
4 | * | ||
5 | * Author: Mehmet Kayaalp <mkayaalp@linux.vnet.ibm.com> | ||
6 | * | ||
7 | * This software may be used and distributed according to the terms | ||
8 | * of the GNU General Public License, incorporated herein by reference. | ||
9 | * | ||
10 | * Usage: insert-sys-cert [-s <System.map> -b <vmlinux> -c <certfile> | ||
11 | */ | ||
12 | |||
13 | #define _GNU_SOURCE | ||
14 | #include <stdio.h> | ||
15 | #include <ctype.h> | ||
16 | #include <string.h> | ||
17 | #include <limits.h> | ||
18 | #include <stdbool.h> | ||
19 | #include <errno.h> | ||
20 | #include <stdlib.h> | ||
21 | #include <stdarg.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <sys/mman.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <unistd.h> | ||
27 | #include <elf.h> | ||
28 | |||
29 | #define CERT_SYM "system_extra_cert" | ||
30 | #define USED_SYM "system_extra_cert_used" | ||
31 | #define LSIZE_SYM "system_certificate_list_size" | ||
32 | |||
33 | #define info(format, args...) fprintf(stderr, "INFO: " format, ## args) | ||
34 | #define warn(format, args...) fprintf(stdout, "WARNING: " format, ## args) | ||
35 | #define err(format, args...) fprintf(stderr, "ERROR: " format, ## args) | ||
36 | |||
37 | #if UINTPTR_MAX == 0xffffffff | ||
38 | #define CURRENT_ELFCLASS ELFCLASS32 | ||
39 | #define Elf_Ehdr Elf32_Ehdr | ||
40 | #define Elf_Shdr Elf32_Shdr | ||
41 | #define Elf_Sym Elf32_Sym | ||
42 | #else | ||
43 | #define CURRENT_ELFCLASS ELFCLASS64 | ||
44 | #define Elf_Ehdr Elf64_Ehdr | ||
45 | #define Elf_Shdr Elf64_Shdr | ||
46 | #define Elf_Sym Elf64_Sym | ||
47 | #endif | ||
48 | |||
49 | static unsigned char endianness(void) | ||
50 | { | ||
51 | uint16_t two_byte = 0x00FF; | ||
52 | uint8_t low_address = *((uint8_t *)&two_byte); | ||
53 | |||
54 | if (low_address == 0) | ||
55 | return ELFDATA2MSB; | ||
56 | else | ||
57 | return ELFDATA2LSB; | ||
58 | } | ||
59 | |||
60 | struct sym { | ||
61 | char *name; | ||
62 | unsigned long address; | ||
63 | unsigned long offset; | ||
64 | void *content; | ||
65 | int size; | ||
66 | }; | ||
67 | |||
68 | static unsigned long get_offset_from_address(Elf_Ehdr *hdr, unsigned long addr) | ||
69 | { | ||
70 | Elf_Shdr *x; | ||
71 | unsigned int i, num_sections; | ||
72 | |||
73 | x = (void *)hdr + hdr->e_shoff; | ||
74 | if (hdr->e_shnum == SHN_UNDEF) | ||
75 | num_sections = x[0].sh_size; | ||
76 | else | ||
77 | num_sections = hdr->e_shnum; | ||
78 | |||
79 | for (i = 1; i < num_sections; i++) { | ||
80 | unsigned long start = x[i].sh_addr; | ||
81 | unsigned long end = start + x[i].sh_size; | ||
82 | unsigned long offset = x[i].sh_offset; | ||
83 | |||
84 | if (addr >= start && addr <= end) | ||
85 | return addr - start + offset; | ||
86 | } | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | |||
91 | #define LINE_SIZE 100 | ||
92 | |||
93 | static void get_symbol_from_map(Elf_Ehdr *hdr, FILE *f, char *name, | ||
94 | struct sym *s) | ||
95 | { | ||
96 | char l[LINE_SIZE]; | ||
97 | char *w, *p, *n; | ||
98 | |||
99 | s->size = 0; | ||
100 | s->address = 0; | ||
101 | s->offset = 0; | ||
102 | if (fseek(f, 0, SEEK_SET) != 0) { | ||
103 | perror("File seek failed"); | ||
104 | exit(EXIT_FAILURE); | ||
105 | } | ||
106 | while (fgets(l, LINE_SIZE, f)) { | ||
107 | p = strchr(l, '\n'); | ||
108 | if (!p) { | ||
109 | err("Missing line ending.\n"); | ||
110 | return; | ||
111 | } | ||
112 | n = strstr(l, name); | ||
113 | if (n) | ||
114 | break; | ||
115 | } | ||
116 | if (!n) { | ||
117 | err("Unable to find symbol: %s\n", name); | ||
118 | return; | ||
119 | } | ||
120 | w = strchr(l, ' '); | ||
121 | if (!w) | ||
122 | return; | ||
123 | |||
124 | *w = '\0'; | ||
125 | s->address = strtoul(l, NULL, 16); | ||
126 | if (s->address == 0) | ||
127 | return; | ||
128 | s->offset = get_offset_from_address(hdr, s->address); | ||
129 | s->name = name; | ||
130 | s->content = (void *)hdr + s->offset; | ||
131 | } | ||
132 | |||
133 | static Elf_Sym *find_elf_symbol(Elf_Ehdr *hdr, Elf_Shdr *symtab, char *name) | ||
134 | { | ||
135 | Elf_Sym *sym, *symtab_start; | ||
136 | char *strtab, *symname; | ||
137 | unsigned int link; | ||
138 | Elf_Shdr *x; | ||
139 | int i, n; | ||
140 | |||
141 | x = (void *)hdr + hdr->e_shoff; | ||
142 | link = symtab->sh_link; | ||
143 | symtab_start = (void *)hdr + symtab->sh_offset; | ||
144 | n = symtab->sh_size / symtab->sh_entsize; | ||
145 | strtab = (void *)hdr + x[link].sh_offset; | ||
146 | |||
147 | for (i = 0; i < n; i++) { | ||
148 | sym = &symtab_start[i]; | ||
149 | symname = strtab + sym->st_name; | ||
150 | if (strcmp(symname, name) == 0) | ||
151 | return sym; | ||
152 | } | ||
153 | err("Unable to find symbol: %s\n", name); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
157 | static void get_symbol_from_table(Elf_Ehdr *hdr, Elf_Shdr *symtab, | ||
158 | char *name, struct sym *s) | ||
159 | { | ||
160 | Elf_Shdr *sec; | ||
161 | int secndx; | ||
162 | Elf_Sym *elf_sym; | ||
163 | Elf_Shdr *x; | ||
164 | |||
165 | x = (void *)hdr + hdr->e_shoff; | ||
166 | s->size = 0; | ||
167 | s->address = 0; | ||
168 | s->offset = 0; | ||
169 | elf_sym = find_elf_symbol(hdr, symtab, name); | ||
170 | if (!elf_sym) | ||
171 | return; | ||
172 | secndx = elf_sym->st_shndx; | ||
173 | if (!secndx) | ||
174 | return; | ||
175 | sec = &x[secndx]; | ||
176 | s->size = elf_sym->st_size; | ||
177 | s->address = elf_sym->st_value; | ||
178 | s->offset = s->address - sec->sh_addr | ||
179 | + sec->sh_offset; | ||
180 | s->name = name; | ||
181 | s->content = (void *)hdr + s->offset; | ||
182 | } | ||
183 | |||
184 | static Elf_Shdr *get_symbol_table(Elf_Ehdr *hdr) | ||
185 | { | ||
186 | Elf_Shdr *x; | ||
187 | unsigned int i, num_sections; | ||
188 | |||
189 | x = (void *)hdr + hdr->e_shoff; | ||
190 | if (hdr->e_shnum == SHN_UNDEF) | ||
191 | num_sections = x[0].sh_size; | ||
192 | else | ||
193 | num_sections = hdr->e_shnum; | ||
194 | |||
195 | for (i = 1; i < num_sections; i++) | ||
196 | if (x[i].sh_type == SHT_SYMTAB) | ||
197 | return &x[i]; | ||
198 | return NULL; | ||
199 | } | ||
200 | |||
201 | static void *map_file(char *file_name, int *size) | ||
202 | { | ||
203 | struct stat st; | ||
204 | void *map; | ||
205 | int fd; | ||
206 | |||
207 | fd = open(file_name, O_RDWR); | ||
208 | if (fd < 0) { | ||
209 | perror(file_name); | ||
210 | return NULL; | ||
211 | } | ||
212 | if (fstat(fd, &st)) { | ||
213 | perror("Could not determine file size"); | ||
214 | close(fd); | ||
215 | return NULL; | ||
216 | } | ||
217 | *size = st.st_size; | ||
218 | map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
219 | if (map == MAP_FAILED) { | ||
220 | perror("Mapping to memory failed"); | ||
221 | close(fd); | ||
222 | return NULL; | ||
223 | } | ||
224 | close(fd); | ||
225 | return map; | ||
226 | } | ||
227 | |||
228 | static char *read_file(char *file_name, int *size) | ||
229 | { | ||
230 | struct stat st; | ||
231 | char *buf; | ||
232 | int fd; | ||
233 | |||
234 | fd = open(file_name, O_RDONLY); | ||
235 | if (fd < 0) { | ||
236 | perror(file_name); | ||
237 | return NULL; | ||
238 | } | ||
239 | if (fstat(fd, &st)) { | ||
240 | perror("Could not determine file size"); | ||
241 | close(fd); | ||
242 | return NULL; | ||
243 | } | ||
244 | *size = st.st_size; | ||
245 | buf = malloc(*size); | ||
246 | if (!buf) { | ||
247 | perror("Allocating memory failed"); | ||
248 | close(fd); | ||
249 | return NULL; | ||
250 | } | ||
251 | if (read(fd, buf, *size) != *size) { | ||
252 | perror("File read failed"); | ||
253 | close(fd); | ||
254 | return NULL; | ||
255 | } | ||
256 | close(fd); | ||
257 | return buf; | ||
258 | } | ||
259 | |||
260 | static void print_sym(Elf_Ehdr *hdr, struct sym *s) | ||
261 | { | ||
262 | info("sym: %s\n", s->name); | ||
263 | info("addr: 0x%lx\n", s->address); | ||
264 | info("size: %d\n", s->size); | ||
265 | info("offset: 0x%lx\n", (unsigned long)s->offset); | ||
266 | } | ||
267 | |||
268 | static void print_usage(char *e) | ||
269 | { | ||
270 | printf("Usage %s [-s <System.map>] -b <vmlinux> -c <certfile>\n", e); | ||
271 | } | ||
272 | |||
273 | int main(int argc, char **argv) | ||
274 | { | ||
275 | char *system_map_file = NULL; | ||
276 | char *vmlinux_file = NULL; | ||
277 | char *cert_file = NULL; | ||
278 | int vmlinux_size; | ||
279 | int cert_size; | ||
280 | Elf_Ehdr *hdr; | ||
281 | char *cert; | ||
282 | FILE *system_map; | ||
283 | unsigned long *lsize; | ||
284 | int *used; | ||
285 | int opt; | ||
286 | Elf_Shdr *symtab = NULL; | ||
287 | struct sym cert_sym, lsize_sym, used_sym; | ||
288 | |||
289 | while ((opt = getopt(argc, argv, "b:c:s:")) != -1) { | ||
290 | switch (opt) { | ||
291 | case 's': | ||
292 | system_map_file = optarg; | ||
293 | break; | ||
294 | case 'b': | ||
295 | vmlinux_file = optarg; | ||
296 | break; | ||
297 | case 'c': | ||
298 | cert_file = optarg; | ||
299 | break; | ||
300 | default: | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | if (!vmlinux_file || !cert_file) { | ||
306 | print_usage(argv[0]); | ||
307 | exit(EXIT_FAILURE); | ||
308 | } | ||
309 | |||
310 | cert = read_file(cert_file, &cert_size); | ||
311 | if (!cert) | ||
312 | exit(EXIT_FAILURE); | ||
313 | |||
314 | hdr = map_file(vmlinux_file, &vmlinux_size); | ||
315 | if (!hdr) | ||
316 | exit(EXIT_FAILURE); | ||
317 | |||
318 | if (vmlinux_size < sizeof(*hdr)) { | ||
319 | err("Invalid ELF file.\n"); | ||
320 | exit(EXIT_FAILURE); | ||
321 | } | ||
322 | |||
323 | if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || | ||
324 | (hdr->e_ident[EI_MAG1] != ELFMAG1) || | ||
325 | (hdr->e_ident[EI_MAG2] != ELFMAG2) || | ||
326 | (hdr->e_ident[EI_MAG3] != ELFMAG3)) { | ||
327 | err("Invalid ELF magic.\n"); | ||
328 | exit(EXIT_FAILURE); | ||
329 | } | ||
330 | |||
331 | if (hdr->e_ident[EI_CLASS] != CURRENT_ELFCLASS) { | ||
332 | err("ELF class mismatch.\n"); | ||
333 | exit(EXIT_FAILURE); | ||
334 | } | ||
335 | |||
336 | if (hdr->e_ident[EI_DATA] != endianness()) { | ||
337 | err("ELF endian mismatch.\n"); | ||
338 | exit(EXIT_FAILURE); | ||
339 | } | ||
340 | |||
341 | if (hdr->e_shoff > vmlinux_size) { | ||
342 | err("Could not find section header.\n"); | ||
343 | exit(EXIT_FAILURE); | ||
344 | } | ||
345 | |||
346 | symtab = get_symbol_table(hdr); | ||
347 | if (!symtab) { | ||
348 | warn("Could not find the symbol table.\n"); | ||
349 | if (!system_map_file) { | ||
350 | err("Please provide a System.map file.\n"); | ||
351 | print_usage(argv[0]); | ||
352 | exit(EXIT_FAILURE); | ||
353 | } | ||
354 | |||
355 | system_map = fopen(system_map_file, "r"); | ||
356 | if (!system_map) { | ||
357 | perror(system_map_file); | ||
358 | exit(EXIT_FAILURE); | ||
359 | } | ||
360 | get_symbol_from_map(hdr, system_map, CERT_SYM, &cert_sym); | ||
361 | get_symbol_from_map(hdr, system_map, USED_SYM, &used_sym); | ||
362 | get_symbol_from_map(hdr, system_map, LSIZE_SYM, &lsize_sym); | ||
363 | cert_sym.size = used_sym.address - cert_sym.address; | ||
364 | } else { | ||
365 | info("Symbol table found.\n"); | ||
366 | if (system_map_file) | ||
367 | warn("System.map is ignored.\n"); | ||
368 | get_symbol_from_table(hdr, symtab, CERT_SYM, &cert_sym); | ||
369 | get_symbol_from_table(hdr, symtab, USED_SYM, &used_sym); | ||
370 | get_symbol_from_table(hdr, symtab, LSIZE_SYM, &lsize_sym); | ||
371 | } | ||
372 | |||
373 | if (!cert_sym.offset || !lsize_sym.offset || !used_sym.offset) | ||
374 | exit(EXIT_FAILURE); | ||
375 | |||
376 | print_sym(hdr, &cert_sym); | ||
377 | print_sym(hdr, &used_sym); | ||
378 | print_sym(hdr, &lsize_sym); | ||
379 | |||
380 | lsize = (unsigned long *)lsize_sym.content; | ||
381 | used = (int *)used_sym.content; | ||
382 | |||
383 | if (cert_sym.size < cert_size) { | ||
384 | err("Certificate is larger than the reserved area!\n"); | ||
385 | exit(EXIT_FAILURE); | ||
386 | } | ||
387 | |||
388 | /* If the existing cert is the same, don't overwrite */ | ||
389 | if (cert_size == *used && | ||
390 | strncmp(cert_sym.content, cert, cert_size) == 0) { | ||
391 | warn("Certificate was already inserted.\n"); | ||
392 | exit(EXIT_SUCCESS); | ||
393 | } | ||
394 | |||
395 | if (*used > 0) | ||
396 | warn("Replacing previously inserted certificate.\n"); | ||
397 | |||
398 | memcpy(cert_sym.content, cert, cert_size); | ||
399 | if (cert_size < cert_sym.size) | ||
400 | memset(cert_sym.content + cert_size, | ||
401 | 0, cert_sym.size - cert_size); | ||
402 | |||
403 | *lsize = *lsize + cert_size - *used; | ||
404 | *used = cert_size; | ||
405 | info("Inserted the contents of %s into %lx.\n", cert_file, | ||
406 | cert_sym.address); | ||
407 | info("Used %d bytes out of %d bytes reserved.\n", *used, | ||
408 | cert_sym.size); | ||
409 | exit(EXIT_SUCCESS); | ||
410 | } | ||
diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 250a7a645033..d912d5a56a5e 100755 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c | |||
@@ -2,9 +2,11 @@ | |||
2 | * | 2 | * |
3 | * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved. |
4 | * Copyright © 2015 Intel Corporation. | 4 | * Copyright © 2015 Intel Corporation. |
5 | * Copyright © 2016 Hewlett Packard Enterprise Development LP | ||
5 | * | 6 | * |
6 | * Authors: David Howells <dhowells@redhat.com> | 7 | * Authors: David Howells <dhowells@redhat.com> |
7 | * David Woodhouse <dwmw2@infradead.org> | 8 | * David Woodhouse <dwmw2@infradead.org> |
9 | * Juerg Haefliger <juerg.haefliger@hpe.com> | ||
8 | * | 10 | * |
9 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Lesser General Public License | 12 | * modify it under the terms of the GNU Lesser General Public License |
@@ -39,7 +41,7 @@ | |||
39 | * signing with anything other than SHA1 - so we're stuck with that if such is | 41 | * signing with anything other than SHA1 - so we're stuck with that if such is |
40 | * the case. | 42 | * the case. |
41 | */ | 43 | */ |
42 | #if OPENSSL_VERSION_NUMBER < 0x10000000L | 44 | #if OPENSSL_VERSION_NUMBER < 0x10000000L || defined(OPENSSL_NO_CMS) |
43 | #define USE_PKCS7 | 45 | #define USE_PKCS7 |
44 | #endif | 46 | #endif |
45 | #ifndef USE_PKCS7 | 47 | #ifndef USE_PKCS7 |
@@ -67,6 +69,8 @@ void format(void) | |||
67 | { | 69 | { |
68 | fprintf(stderr, | 70 | fprintf(stderr, |
69 | "Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n"); | 71 | "Usage: scripts/sign-file [-dp] <hash algo> <key> <x509> <module> [<dest>]\n"); |
72 | fprintf(stderr, | ||
73 | " scripts/sign-file -s <raw sig> <hash algo> <x509> <module> [<dest>]\n"); | ||
70 | exit(2); | 74 | exit(2); |
71 | } | 75 | } |
72 | 76 | ||
@@ -126,26 +130,84 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) | |||
126 | return pwlen; | 130 | return pwlen; |
127 | } | 131 | } |
128 | 132 | ||
133 | static EVP_PKEY *read_private_key(const char *private_key_name) | ||
134 | { | ||
135 | EVP_PKEY *private_key; | ||
136 | |||
137 | if (!strncmp(private_key_name, "pkcs11:", 7)) { | ||
138 | ENGINE *e; | ||
139 | |||
140 | ENGINE_load_builtin_engines(); | ||
141 | drain_openssl_errors(); | ||
142 | e = ENGINE_by_id("pkcs11"); | ||
143 | ERR(!e, "Load PKCS#11 ENGINE"); | ||
144 | if (ENGINE_init(e)) | ||
145 | drain_openssl_errors(); | ||
146 | else | ||
147 | ERR(1, "ENGINE_init"); | ||
148 | if (key_pass) | ||
149 | ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), | ||
150 | "Set PKCS#11 PIN"); | ||
151 | private_key = ENGINE_load_private_key(e, private_key_name, | ||
152 | NULL, NULL); | ||
153 | ERR(!private_key, "%s", private_key_name); | ||
154 | } else { | ||
155 | BIO *b; | ||
156 | |||
157 | b = BIO_new_file(private_key_name, "rb"); | ||
158 | ERR(!b, "%s", private_key_name); | ||
159 | private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, | ||
160 | NULL); | ||
161 | ERR(!private_key, "%s", private_key_name); | ||
162 | BIO_free(b); | ||
163 | } | ||
164 | |||
165 | return private_key; | ||
166 | } | ||
167 | |||
168 | static X509 *read_x509(const char *x509_name) | ||
169 | { | ||
170 | X509 *x509; | ||
171 | BIO *b; | ||
172 | |||
173 | b = BIO_new_file(x509_name, "rb"); | ||
174 | ERR(!b, "%s", x509_name); | ||
175 | x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */ | ||
176 | if (!x509) { | ||
177 | ERR(BIO_reset(b) != 1, "%s", x509_name); | ||
178 | x509 = PEM_read_bio_X509(b, NULL, NULL, | ||
179 | NULL); /* PEM encoded X.509 */ | ||
180 | if (x509) | ||
181 | drain_openssl_errors(); | ||
182 | } | ||
183 | BIO_free(b); | ||
184 | ERR(!x509, "%s", x509_name); | ||
185 | |||
186 | return x509; | ||
187 | } | ||
188 | |||
129 | int main(int argc, char **argv) | 189 | int main(int argc, char **argv) |
130 | { | 190 | { |
131 | struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; | 191 | struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; |
132 | char *hash_algo = NULL; | 192 | char *hash_algo = NULL; |
133 | char *private_key_name, *x509_name, *module_name, *dest_name; | 193 | char *private_key_name = NULL, *raw_sig_name = NULL; |
194 | char *x509_name, *module_name, *dest_name; | ||
134 | bool save_sig = false, replace_orig; | 195 | bool save_sig = false, replace_orig; |
135 | bool sign_only = false; | 196 | bool sign_only = false; |
197 | bool raw_sig = false; | ||
136 | unsigned char buf[4096]; | 198 | unsigned char buf[4096]; |
137 | unsigned long module_size, sig_size; | 199 | unsigned long module_size, sig_size; |
138 | unsigned int use_signed_attrs; | 200 | unsigned int use_signed_attrs; |
139 | const EVP_MD *digest_algo; | 201 | const EVP_MD *digest_algo; |
140 | EVP_PKEY *private_key; | 202 | EVP_PKEY *private_key; |
141 | #ifndef USE_PKCS7 | 203 | #ifndef USE_PKCS7 |
142 | CMS_ContentInfo *cms; | 204 | CMS_ContentInfo *cms = NULL; |
143 | unsigned int use_keyid = 0; | 205 | unsigned int use_keyid = 0; |
144 | #else | 206 | #else |
145 | PKCS7 *pkcs7; | 207 | PKCS7 *pkcs7 = NULL; |
146 | #endif | 208 | #endif |
147 | X509 *x509; | 209 | X509 *x509; |
148 | BIO *b, *bd = NULL, *bm; | 210 | BIO *bd, *bm; |
149 | int opt, n; | 211 | int opt, n; |
150 | OpenSSL_add_all_algorithms(); | 212 | OpenSSL_add_all_algorithms(); |
151 | ERR_load_crypto_strings(); | 213 | ERR_load_crypto_strings(); |
@@ -160,8 +222,9 @@ int main(int argc, char **argv) | |||
160 | #endif | 222 | #endif |
161 | 223 | ||
162 | do { | 224 | do { |
163 | opt = getopt(argc, argv, "dpk"); | 225 | opt = getopt(argc, argv, "sdpk"); |
164 | switch (opt) { | 226 | switch (opt) { |
227 | case 's': raw_sig = true; break; | ||
165 | case 'p': save_sig = true; break; | 228 | case 'p': save_sig = true; break; |
166 | case 'd': sign_only = true; save_sig = true; break; | 229 | case 'd': sign_only = true; save_sig = true; break; |
167 | #ifndef USE_PKCS7 | 230 | #ifndef USE_PKCS7 |
@@ -177,8 +240,13 @@ int main(int argc, char **argv) | |||
177 | if (argc < 4 || argc > 5) | 240 | if (argc < 4 || argc > 5) |
178 | format(); | 241 | format(); |
179 | 242 | ||
180 | hash_algo = argv[0]; | 243 | if (raw_sig) { |
181 | private_key_name = argv[1]; | 244 | raw_sig_name = argv[0]; |
245 | hash_algo = argv[1]; | ||
246 | } else { | ||
247 | hash_algo = argv[0]; | ||
248 | private_key_name = argv[1]; | ||
249 | } | ||
182 | x509_name = argv[2]; | 250 | x509_name = argv[2]; |
183 | module_name = argv[3]; | 251 | module_name = argv[3]; |
184 | if (argc == 5) { | 252 | if (argc == 5) { |
@@ -198,101 +266,74 @@ int main(int argc, char **argv) | |||
198 | } | 266 | } |
199 | #endif | 267 | #endif |
200 | 268 | ||
201 | /* Read the private key and the X.509 cert the PKCS#7 message | 269 | /* Open the module file */ |
202 | * will point to. | ||
203 | */ | ||
204 | if (!strncmp(private_key_name, "pkcs11:", 7)) { | ||
205 | ENGINE *e; | ||
206 | |||
207 | ENGINE_load_builtin_engines(); | ||
208 | drain_openssl_errors(); | ||
209 | e = ENGINE_by_id("pkcs11"); | ||
210 | ERR(!e, "Load PKCS#11 ENGINE"); | ||
211 | if (ENGINE_init(e)) | ||
212 | drain_openssl_errors(); | ||
213 | else | ||
214 | ERR(1, "ENGINE_init"); | ||
215 | if (key_pass) | ||
216 | ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); | ||
217 | private_key = ENGINE_load_private_key(e, private_key_name, NULL, | ||
218 | NULL); | ||
219 | ERR(!private_key, "%s", private_key_name); | ||
220 | } else { | ||
221 | b = BIO_new_file(private_key_name, "rb"); | ||
222 | ERR(!b, "%s", private_key_name); | ||
223 | private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL); | ||
224 | ERR(!private_key, "%s", private_key_name); | ||
225 | BIO_free(b); | ||
226 | } | ||
227 | |||
228 | b = BIO_new_file(x509_name, "rb"); | ||
229 | ERR(!b, "%s", x509_name); | ||
230 | x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */ | ||
231 | if (!x509) { | ||
232 | ERR(BIO_reset(b) != 1, "%s", x509_name); | ||
233 | x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); /* PEM encoded X.509 */ | ||
234 | if (x509) | ||
235 | drain_openssl_errors(); | ||
236 | } | ||
237 | BIO_free(b); | ||
238 | ERR(!x509, "%s", x509_name); | ||
239 | |||
240 | /* Open the destination file now so that we can shovel the module data | ||
241 | * across as we read it. | ||
242 | */ | ||
243 | if (!sign_only) { | ||
244 | bd = BIO_new_file(dest_name, "wb"); | ||
245 | ERR(!bd, "%s", dest_name); | ||
246 | } | ||
247 | |||
248 | /* Digest the module data. */ | ||
249 | OpenSSL_add_all_digests(); | ||
250 | display_openssl_errors(__LINE__); | ||
251 | digest_algo = EVP_get_digestbyname(hash_algo); | ||
252 | ERR(!digest_algo, "EVP_get_digestbyname"); | ||
253 | |||
254 | bm = BIO_new_file(module_name, "rb"); | 270 | bm = BIO_new_file(module_name, "rb"); |
255 | ERR(!bm, "%s", module_name); | 271 | ERR(!bm, "%s", module_name); |
256 | 272 | ||
273 | if (!raw_sig) { | ||
274 | /* Read the private key and the X.509 cert the PKCS#7 message | ||
275 | * will point to. | ||
276 | */ | ||
277 | private_key = read_private_key(private_key_name); | ||
278 | x509 = read_x509(x509_name); | ||
279 | |||
280 | /* Digest the module data. */ | ||
281 | OpenSSL_add_all_digests(); | ||
282 | display_openssl_errors(__LINE__); | ||
283 | digest_algo = EVP_get_digestbyname(hash_algo); | ||
284 | ERR(!digest_algo, "EVP_get_digestbyname"); | ||
285 | |||
257 | #ifndef USE_PKCS7 | 286 | #ifndef USE_PKCS7 |
258 | /* Load the signature message from the digest buffer. */ | 287 | /* Load the signature message from the digest buffer. */ |
259 | cms = CMS_sign(NULL, NULL, NULL, NULL, | 288 | cms = CMS_sign(NULL, NULL, NULL, NULL, |
260 | CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED | CMS_STREAM); | 289 | CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | |
261 | ERR(!cms, "CMS_sign"); | 290 | CMS_DETACHED | CMS_STREAM); |
262 | 291 | ERR(!cms, "CMS_sign"); | |
263 | ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo, | 292 | |
264 | CMS_NOCERTS | CMS_BINARY | CMS_NOSMIMECAP | | 293 | ERR(!CMS_add1_signer(cms, x509, private_key, digest_algo, |
265 | use_keyid | use_signed_attrs), | 294 | CMS_NOCERTS | CMS_BINARY | |
266 | "CMS_add1_signer"); | 295 | CMS_NOSMIMECAP | use_keyid | |
267 | ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0, | 296 | use_signed_attrs), |
268 | "CMS_final"); | 297 | "CMS_add1_signer"); |
298 | ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0, | ||
299 | "CMS_final"); | ||
269 | 300 | ||
270 | #else | 301 | #else |
271 | pkcs7 = PKCS7_sign(x509, private_key, NULL, bm, | 302 | pkcs7 = PKCS7_sign(x509, private_key, NULL, bm, |
272 | PKCS7_NOCERTS | PKCS7_BINARY | | 303 | PKCS7_NOCERTS | PKCS7_BINARY | |
273 | PKCS7_DETACHED | use_signed_attrs); | 304 | PKCS7_DETACHED | use_signed_attrs); |
274 | ERR(!pkcs7, "PKCS7_sign"); | 305 | ERR(!pkcs7, "PKCS7_sign"); |
275 | #endif | 306 | #endif |
276 | 307 | ||
277 | if (save_sig) { | 308 | if (save_sig) { |
278 | char *sig_file_name; | 309 | char *sig_file_name; |
310 | BIO *b; | ||
279 | 311 | ||
280 | ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0, | 312 | ERR(asprintf(&sig_file_name, "%s.p7s", module_name) < 0, |
281 | "asprintf"); | 313 | "asprintf"); |
282 | b = BIO_new_file(sig_file_name, "wb"); | 314 | b = BIO_new_file(sig_file_name, "wb"); |
283 | ERR(!b, "%s", sig_file_name); | 315 | ERR(!b, "%s", sig_file_name); |
284 | #ifndef USE_PKCS7 | 316 | #ifndef USE_PKCS7 |
285 | ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0, | 317 | ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0, |
286 | "%s", sig_file_name); | 318 | "%s", sig_file_name); |
287 | #else | 319 | #else |
288 | ERR(i2d_PKCS7_bio(b, pkcs7) < 0, | 320 | ERR(i2d_PKCS7_bio(b, pkcs7) < 0, |
289 | "%s", sig_file_name); | 321 | "%s", sig_file_name); |
290 | #endif | 322 | #endif |
291 | BIO_free(b); | 323 | BIO_free(b); |
324 | } | ||
325 | |||
326 | if (sign_only) { | ||
327 | BIO_free(bm); | ||
328 | return 0; | ||
329 | } | ||
292 | } | 330 | } |
293 | 331 | ||
294 | if (sign_only) | 332 | /* Open the destination file now so that we can shovel the module data |
295 | return 0; | 333 | * across as we read it. |
334 | */ | ||
335 | bd = BIO_new_file(dest_name, "wb"); | ||
336 | ERR(!bd, "%s", dest_name); | ||
296 | 337 | ||
297 | /* Append the marker and the PKCS#7 message to the destination file */ | 338 | /* Append the marker and the PKCS#7 message to the destination file */ |
298 | ERR(BIO_reset(bm) < 0, "%s", module_name); | 339 | ERR(BIO_reset(bm) < 0, "%s", module_name); |
@@ -300,14 +341,29 @@ int main(int argc, char **argv) | |||
300 | n > 0) { | 341 | n > 0) { |
301 | ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name); | 342 | ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name); |
302 | } | 343 | } |
344 | BIO_free(bm); | ||
303 | ERR(n < 0, "%s", module_name); | 345 | ERR(n < 0, "%s", module_name); |
304 | module_size = BIO_number_written(bd); | 346 | module_size = BIO_number_written(bd); |
305 | 347 | ||
348 | if (!raw_sig) { | ||
306 | #ifndef USE_PKCS7 | 349 | #ifndef USE_PKCS7 |
307 | ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name); | 350 | ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name); |
308 | #else | 351 | #else |
309 | ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name); | 352 | ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name); |
310 | #endif | 353 | #endif |
354 | } else { | ||
355 | BIO *b; | ||
356 | |||
357 | /* Read the raw signature file and write the data to the | ||
358 | * destination file | ||
359 | */ | ||
360 | b = BIO_new_file(raw_sig_name, "rb"); | ||
361 | ERR(!b, "%s", raw_sig_name); | ||
362 | while ((n = BIO_read(b, buf, sizeof(buf))), n > 0) | ||
363 | ERR(BIO_write(bd, buf, n) < 0, "%s", dest_name); | ||
364 | BIO_free(b); | ||
365 | } | ||
366 | |||
311 | sig_size = BIO_number_written(bd) - module_size; | 367 | sig_size = BIO_number_written(bd) - module_size; |
312 | sig_info.sig_len = htonl(sig_size); | 368 | sig_info.sig_len = htonl(sig_size); |
313 | ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); | 369 | ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); |
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 21d756832b75..979be65d22c4 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig | |||
@@ -36,6 +36,7 @@ config INTEGRITY_ASYMMETRIC_KEYS | |||
36 | select ASYMMETRIC_KEY_TYPE | 36 | select ASYMMETRIC_KEY_TYPE |
37 | select ASYMMETRIC_PUBLIC_KEY_SUBTYPE | 37 | select ASYMMETRIC_PUBLIC_KEY_SUBTYPE |
38 | select PUBLIC_KEY_ALGO_RSA | 38 | select PUBLIC_KEY_ALGO_RSA |
39 | select CRYPTO_RSA | ||
39 | select X509_CERTIFICATE_PARSER | 40 | select X509_CERTIFICATE_PARSER |
40 | help | 41 | help |
41 | This option enables digital signature verification using | 42 | This option enables digital signature verification using |
@@ -45,7 +46,6 @@ config INTEGRITY_TRUSTED_KEYRING | |||
45 | bool "Require all keys on the integrity keyrings be signed" | 46 | bool "Require all keys on the integrity keyrings be signed" |
46 | depends on SYSTEM_TRUSTED_KEYRING | 47 | depends on SYSTEM_TRUSTED_KEYRING |
47 | depends on INTEGRITY_ASYMMETRIC_KEYS | 48 | depends on INTEGRITY_ASYMMETRIC_KEYS |
48 | select KEYS_DEBUG_PROC_KEYS | ||
49 | default y | 49 | default y |
50 | help | 50 | help |
51 | This option requires that all keys added to the .ima and | 51 | This option requires that all keys added to the .ima and |
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 5ade2a7517a6..80052ed8d467 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/ratelimit.h> | 16 | #include <linux/ratelimit.h> |
17 | #include <linux/key-type.h> | 17 | #include <linux/key-type.h> |
18 | #include <crypto/public_key.h> | 18 | #include <crypto/public_key.h> |
19 | #include <crypto/hash_info.h> | ||
19 | #include <keys/asymmetric-type.h> | 20 | #include <keys/asymmetric-type.h> |
20 | #include <keys/system_keyring.h> | 21 | #include <keys/system_keyring.h> |
21 | 22 | ||
@@ -94,7 +95,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, | |||
94 | if (siglen != __be16_to_cpu(hdr->sig_size)) | 95 | if (siglen != __be16_to_cpu(hdr->sig_size)) |
95 | return -EBADMSG; | 96 | return -EBADMSG; |
96 | 97 | ||
97 | if (hdr->hash_algo >= PKEY_HASH__LAST) | 98 | if (hdr->hash_algo >= HASH_ALGO__LAST) |
98 | return -ENOPKG; | 99 | return -ENOPKG; |
99 | 100 | ||
100 | key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); | 101 | key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); |
@@ -103,16 +104,13 @@ int asymmetric_verify(struct key *keyring, const char *sig, | |||
103 | 104 | ||
104 | memset(&pks, 0, sizeof(pks)); | 105 | memset(&pks, 0, sizeof(pks)); |
105 | 106 | ||
106 | pks.pkey_hash_algo = hdr->hash_algo; | 107 | pks.pkey_algo = "rsa"; |
108 | pks.hash_algo = hash_algo_name[hdr->hash_algo]; | ||
107 | pks.digest = (u8 *)data; | 109 | pks.digest = (u8 *)data; |
108 | pks.digest_size = datalen; | 110 | pks.digest_size = datalen; |
109 | pks.nr_mpi = 1; | 111 | pks.s = hdr->sig; |
110 | pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen); | 112 | pks.s_size = siglen; |
111 | 113 | ret = verify_signature(key, &pks); | |
112 | if (pks.rsa.s) | ||
113 | ret = verify_signature(key, &pks); | ||
114 | |||
115 | mpi_free(pks.rsa.s); | ||
116 | key_put(key); | 114 | key_put(key); |
117 | pr_debug("%s() = %d\n", __func__, ret); | 115 | pr_debug("%s() = %d\n", __func__, ret); |
118 | return ret; | 116 | return ret; |
diff --git a/security/integrity/iint.c b/security/integrity/iint.c index 8f1ab37f2897..345b75997e4c 100644 --- a/security/integrity/iint.c +++ b/security/integrity/iint.c | |||
@@ -77,7 +77,7 @@ static void iint_free(struct integrity_iint_cache *iint) | |||
77 | iint->ima_file_status = INTEGRITY_UNKNOWN; | 77 | iint->ima_file_status = INTEGRITY_UNKNOWN; |
78 | iint->ima_mmap_status = INTEGRITY_UNKNOWN; | 78 | iint->ima_mmap_status = INTEGRITY_UNKNOWN; |
79 | iint->ima_bprm_status = INTEGRITY_UNKNOWN; | 79 | iint->ima_bprm_status = INTEGRITY_UNKNOWN; |
80 | iint->ima_module_status = INTEGRITY_UNKNOWN; | 80 | iint->ima_read_status = INTEGRITY_UNKNOWN; |
81 | iint->evm_status = INTEGRITY_UNKNOWN; | 81 | iint->evm_status = INTEGRITY_UNKNOWN; |
82 | kmem_cache_free(iint_cache, iint); | 82 | kmem_cache_free(iint_cache, iint); |
83 | } | 83 | } |
@@ -157,7 +157,7 @@ static void init_once(void *foo) | |||
157 | iint->ima_file_status = INTEGRITY_UNKNOWN; | 157 | iint->ima_file_status = INTEGRITY_UNKNOWN; |
158 | iint->ima_mmap_status = INTEGRITY_UNKNOWN; | 158 | iint->ima_mmap_status = INTEGRITY_UNKNOWN; |
159 | iint->ima_bprm_status = INTEGRITY_UNKNOWN; | 159 | iint->ima_bprm_status = INTEGRITY_UNKNOWN; |
160 | iint->ima_module_status = INTEGRITY_UNKNOWN; | 160 | iint->ima_read_status = INTEGRITY_UNKNOWN; |
161 | iint->evm_status = INTEGRITY_UNKNOWN; | 161 | iint->evm_status = INTEGRITY_UNKNOWN; |
162 | } | 162 | } |
163 | 163 | ||
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 585af61ed399..5d0f61163d98 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h | |||
@@ -19,10 +19,12 @@ | |||
19 | 19 | ||
20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
21 | #include <linux/crypto.h> | 21 | #include <linux/crypto.h> |
22 | #include <linux/fs.h> | ||
22 | #include <linux/security.h> | 23 | #include <linux/security.h> |
23 | #include <linux/hash.h> | 24 | #include <linux/hash.h> |
24 | #include <linux/tpm.h> | 25 | #include <linux/tpm.h> |
25 | #include <linux/audit.h> | 26 | #include <linux/audit.h> |
27 | #include <crypto/hash_info.h> | ||
26 | 28 | ||
27 | #include "../integrity.h" | 29 | #include "../integrity.h" |
28 | 30 | ||
@@ -106,6 +108,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, | |||
106 | const char *op, struct inode *inode, | 108 | const char *op, struct inode *inode, |
107 | const unsigned char *filename); | 109 | const unsigned char *filename); |
108 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); | 110 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); |
111 | int ima_calc_buffer_hash(const void *buf, loff_t len, | ||
112 | struct ima_digest_data *hash); | ||
109 | int ima_calc_field_array_hash(struct ima_field_data *field_data, | 113 | int ima_calc_field_array_hash(struct ima_field_data *field_data, |
110 | struct ima_template_desc *desc, int num_fields, | 114 | struct ima_template_desc *desc, int num_fields, |
111 | struct ima_digest_data *hash); | 115 | struct ima_digest_data *hash); |
@@ -136,13 +140,25 @@ static inline unsigned long ima_hash_key(u8 *digest) | |||
136 | return hash_long(*digest, IMA_HASH_BITS); | 140 | return hash_long(*digest, IMA_HASH_BITS); |
137 | } | 141 | } |
138 | 142 | ||
143 | enum ima_hooks { | ||
144 | FILE_CHECK = 1, | ||
145 | MMAP_CHECK, | ||
146 | BPRM_CHECK, | ||
147 | POST_SETATTR, | ||
148 | MODULE_CHECK, | ||
149 | FIRMWARE_CHECK, | ||
150 | KEXEC_KERNEL_CHECK, | ||
151 | KEXEC_INITRAMFS_CHECK, | ||
152 | POLICY_CHECK, | ||
153 | MAX_CHECK | ||
154 | }; | ||
155 | |||
139 | /* LIM API function definitions */ | 156 | /* LIM API function definitions */ |
140 | int ima_get_action(struct inode *inode, int mask, int function); | 157 | int ima_get_action(struct inode *inode, int mask, enum ima_hooks func); |
141 | int ima_must_measure(struct inode *inode, int mask, int function); | 158 | int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); |
142 | int ima_collect_measurement(struct integrity_iint_cache *iint, | 159 | int ima_collect_measurement(struct integrity_iint_cache *iint, |
143 | struct file *file, | 160 | struct file *file, void *buf, loff_t size, |
144 | struct evm_ima_xattr_data **xattr_value, | 161 | enum hash_algo algo); |
145 | int *xattr_len); | ||
146 | void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, | 162 | void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, |
147 | const unsigned char *filename, | 163 | const unsigned char *filename, |
148 | struct evm_ima_xattr_data *xattr_value, | 164 | struct evm_ima_xattr_data *xattr_value, |
@@ -157,8 +173,6 @@ void ima_free_template_entry(struct ima_template_entry *entry); | |||
157 | const char *ima_d_path(struct path *path, char **pathbuf); | 173 | const char *ima_d_path(struct path *path, char **pathbuf); |
158 | 174 | ||
159 | /* IMA policy related functions */ | 175 | /* IMA policy related functions */ |
160 | enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR }; | ||
161 | |||
162 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, | 176 | int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, |
163 | int flags); | 177 | int flags); |
164 | void ima_init_policy(void); | 178 | void ima_init_policy(void); |
@@ -178,23 +192,25 @@ int ima_policy_show(struct seq_file *m, void *v); | |||
178 | #define IMA_APPRAISE_LOG 0x04 | 192 | #define IMA_APPRAISE_LOG 0x04 |
179 | #define IMA_APPRAISE_MODULES 0x08 | 193 | #define IMA_APPRAISE_MODULES 0x08 |
180 | #define IMA_APPRAISE_FIRMWARE 0x10 | 194 | #define IMA_APPRAISE_FIRMWARE 0x10 |
195 | #define IMA_APPRAISE_POLICY 0x20 | ||
181 | 196 | ||
182 | #ifdef CONFIG_IMA_APPRAISE | 197 | #ifdef CONFIG_IMA_APPRAISE |
183 | int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, | 198 | int ima_appraise_measurement(enum ima_hooks func, |
199 | struct integrity_iint_cache *iint, | ||
184 | struct file *file, const unsigned char *filename, | 200 | struct file *file, const unsigned char *filename, |
185 | struct evm_ima_xattr_data *xattr_value, | 201 | struct evm_ima_xattr_data *xattr_value, |
186 | int xattr_len, int opened); | 202 | int xattr_len, int opened); |
187 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); | 203 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); |
188 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); | 204 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); |
189 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, | 205 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, |
190 | int func); | 206 | enum ima_hooks func); |
191 | void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, | 207 | enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, |
192 | struct ima_digest_data *hash); | 208 | int xattr_len); |
193 | int ima_read_xattr(struct dentry *dentry, | 209 | int ima_read_xattr(struct dentry *dentry, |
194 | struct evm_ima_xattr_data **xattr_value); | 210 | struct evm_ima_xattr_data **xattr_value); |
195 | 211 | ||
196 | #else | 212 | #else |
197 | static inline int ima_appraise_measurement(int func, | 213 | static inline int ima_appraise_measurement(enum ima_hooks func, |
198 | struct integrity_iint_cache *iint, | 214 | struct integrity_iint_cache *iint, |
199 | struct file *file, | 215 | struct file *file, |
200 | const unsigned char *filename, | 216 | const unsigned char *filename, |
@@ -216,15 +232,16 @@ static inline void ima_update_xattr(struct integrity_iint_cache *iint, | |||
216 | } | 232 | } |
217 | 233 | ||
218 | static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache | 234 | static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache |
219 | *iint, int func) | 235 | *iint, |
236 | enum ima_hooks func) | ||
220 | { | 237 | { |
221 | return INTEGRITY_UNKNOWN; | 238 | return INTEGRITY_UNKNOWN; |
222 | } | 239 | } |
223 | 240 | ||
224 | static inline void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, | 241 | static inline enum hash_algo |
225 | int xattr_len, | 242 | ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len) |
226 | struct ima_digest_data *hash) | ||
227 | { | 243 | { |
244 | return ima_hash_algo; | ||
228 | } | 245 | } |
229 | 246 | ||
230 | static inline int ima_read_xattr(struct dentry *dentry, | 247 | static inline int ima_read_xattr(struct dentry *dentry, |
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 1d950fbb2aec..370e42dfc5c5 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/xattr.h> | 19 | #include <linux/xattr.h> |
20 | #include <linux/evm.h> | 20 | #include <linux/evm.h> |
21 | #include <crypto/hash_info.h> | 21 | |
22 | #include "ima.h" | 22 | #include "ima.h" |
23 | 23 | ||
24 | /* | 24 | /* |
@@ -156,7 +156,7 @@ err_out: | |||
156 | * ima_get_action - appraise & measure decision based on policy. | 156 | * ima_get_action - appraise & measure decision based on policy. |
157 | * @inode: pointer to inode to measure | 157 | * @inode: pointer to inode to measure |
158 | * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) | 158 | * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) |
159 | * @function: calling function (FILE_CHECK, BPRM_CHECK, MMAP_CHECK, MODULE_CHECK) | 159 | * @func: caller identifier |
160 | * | 160 | * |
161 | * The policy is defined in terms of keypairs: | 161 | * The policy is defined in terms of keypairs: |
162 | * subj=, obj=, type=, func=, mask=, fsmagic= | 162 | * subj=, obj=, type=, func=, mask=, fsmagic= |
@@ -168,13 +168,13 @@ err_out: | |||
168 | * Returns IMA_MEASURE, IMA_APPRAISE mask. | 168 | * Returns IMA_MEASURE, IMA_APPRAISE mask. |
169 | * | 169 | * |
170 | */ | 170 | */ |
171 | int ima_get_action(struct inode *inode, int mask, int function) | 171 | int ima_get_action(struct inode *inode, int mask, enum ima_hooks func) |
172 | { | 172 | { |
173 | int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; | 173 | int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE; |
174 | 174 | ||
175 | flags &= ima_policy_flag; | 175 | flags &= ima_policy_flag; |
176 | 176 | ||
177 | return ima_match_policy(inode, function, mask, flags); | 177 | return ima_match_policy(inode, func, mask, flags); |
178 | } | 178 | } |
179 | 179 | ||
180 | /* | 180 | /* |
@@ -188,9 +188,8 @@ int ima_get_action(struct inode *inode, int mask, int function) | |||
188 | * Return 0 on success, error code otherwise | 188 | * Return 0 on success, error code otherwise |
189 | */ | 189 | */ |
190 | int ima_collect_measurement(struct integrity_iint_cache *iint, | 190 | int ima_collect_measurement(struct integrity_iint_cache *iint, |
191 | struct file *file, | 191 | struct file *file, void *buf, loff_t size, |
192 | struct evm_ima_xattr_data **xattr_value, | 192 | enum hash_algo algo) |
193 | int *xattr_len) | ||
194 | { | 193 | { |
195 | const char *audit_cause = "failed"; | 194 | const char *audit_cause = "failed"; |
196 | struct inode *inode = file_inode(file); | 195 | struct inode *inode = file_inode(file); |
@@ -201,9 +200,6 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, | |||
201 | char digest[IMA_MAX_DIGEST_SIZE]; | 200 | char digest[IMA_MAX_DIGEST_SIZE]; |
202 | } hash; | 201 | } hash; |
203 | 202 | ||
204 | if (xattr_value) | ||
205 | *xattr_len = ima_read_xattr(file->f_path.dentry, xattr_value); | ||
206 | |||
207 | if (!(iint->flags & IMA_COLLECTED)) { | 203 | if (!(iint->flags & IMA_COLLECTED)) { |
208 | u64 i_version = file_inode(file)->i_version; | 204 | u64 i_version = file_inode(file)->i_version; |
209 | 205 | ||
@@ -213,13 +209,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint, | |||
213 | goto out; | 209 | goto out; |
214 | } | 210 | } |
215 | 211 | ||
216 | /* use default hash algorithm */ | 212 | hash.hdr.algo = algo; |
217 | hash.hdr.algo = ima_hash_algo; | ||
218 | |||
219 | if (xattr_value) | ||
220 | ima_get_hash_algo(*xattr_value, *xattr_len, &hash.hdr); | ||
221 | 213 | ||
222 | result = ima_calc_file_hash(file, &hash.hdr); | 214 | result = (!buf) ? ima_calc_file_hash(file, &hash.hdr) : |
215 | ima_calc_buffer_hash(buf, size, &hash.hdr); | ||
223 | if (!result) { | 216 | if (!result) { |
224 | int length = sizeof(hash.hdr) + hash.hdr.length; | 217 | int length = sizeof(hash.hdr) + hash.hdr.length; |
225 | void *tmpbuf = krealloc(iint->ima_hash, length, | 218 | void *tmpbuf = krealloc(iint->ima_hash, length, |
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 1873b5536f80..6b4694aedae8 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/magic.h> | 15 | #include <linux/magic.h> |
16 | #include <linux/ima.h> | 16 | #include <linux/ima.h> |
17 | #include <linux/evm.h> | 17 | #include <linux/evm.h> |
18 | #include <crypto/hash_info.h> | ||
19 | 18 | ||
20 | #include "ima.h" | 19 | #include "ima.h" |
21 | 20 | ||
@@ -68,25 +67,25 @@ static int ima_fix_xattr(struct dentry *dentry, | |||
68 | 67 | ||
69 | /* Return specific func appraised cached result */ | 68 | /* Return specific func appraised cached result */ |
70 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, | 69 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, |
71 | int func) | 70 | enum ima_hooks func) |
72 | { | 71 | { |
73 | switch (func) { | 72 | switch (func) { |
74 | case MMAP_CHECK: | 73 | case MMAP_CHECK: |
75 | return iint->ima_mmap_status; | 74 | return iint->ima_mmap_status; |
76 | case BPRM_CHECK: | 75 | case BPRM_CHECK: |
77 | return iint->ima_bprm_status; | 76 | return iint->ima_bprm_status; |
78 | case MODULE_CHECK: | ||
79 | return iint->ima_module_status; | ||
80 | case FIRMWARE_CHECK: | ||
81 | return iint->ima_firmware_status; | ||
82 | case FILE_CHECK: | 77 | case FILE_CHECK: |
83 | default: | 78 | case POST_SETATTR: |
84 | return iint->ima_file_status; | 79 | return iint->ima_file_status; |
80 | case MODULE_CHECK ... MAX_CHECK - 1: | ||
81 | default: | ||
82 | return iint->ima_read_status; | ||
85 | } | 83 | } |
86 | } | 84 | } |
87 | 85 | ||
88 | static void ima_set_cache_status(struct integrity_iint_cache *iint, | 86 | static void ima_set_cache_status(struct integrity_iint_cache *iint, |
89 | int func, enum integrity_status status) | 87 | enum ima_hooks func, |
88 | enum integrity_status status) | ||
90 | { | 89 | { |
91 | switch (func) { | 90 | switch (func) { |
92 | case MMAP_CHECK: | 91 | case MMAP_CHECK: |
@@ -95,20 +94,19 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint, | |||
95 | case BPRM_CHECK: | 94 | case BPRM_CHECK: |
96 | iint->ima_bprm_status = status; | 95 | iint->ima_bprm_status = status; |
97 | break; | 96 | break; |
98 | case MODULE_CHECK: | ||
99 | iint->ima_module_status = status; | ||
100 | break; | ||
101 | case FIRMWARE_CHECK: | ||
102 | iint->ima_firmware_status = status; | ||
103 | break; | ||
104 | case FILE_CHECK: | 97 | case FILE_CHECK: |
105 | default: | 98 | case POST_SETATTR: |
106 | iint->ima_file_status = status; | 99 | iint->ima_file_status = status; |
107 | break; | 100 | break; |
101 | case MODULE_CHECK ... MAX_CHECK - 1: | ||
102 | default: | ||
103 | iint->ima_read_status = status; | ||
104 | break; | ||
108 | } | 105 | } |
109 | } | 106 | } |
110 | 107 | ||
111 | static void ima_cache_flags(struct integrity_iint_cache *iint, int func) | 108 | static void ima_cache_flags(struct integrity_iint_cache *iint, |
109 | enum ima_hooks func) | ||
112 | { | 110 | { |
113 | switch (func) { | 111 | switch (func) { |
114 | case MMAP_CHECK: | 112 | case MMAP_CHECK: |
@@ -117,49 +115,51 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func) | |||
117 | case BPRM_CHECK: | 115 | case BPRM_CHECK: |
118 | iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED); | 116 | iint->flags |= (IMA_BPRM_APPRAISED | IMA_APPRAISED); |
119 | break; | 117 | break; |
120 | case MODULE_CHECK: | ||
121 | iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED); | ||
122 | break; | ||
123 | case FIRMWARE_CHECK: | ||
124 | iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED); | ||
125 | break; | ||
126 | case FILE_CHECK: | 118 | case FILE_CHECK: |
127 | default: | 119 | case POST_SETATTR: |
128 | iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); | 120 | iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED); |
129 | break; | 121 | break; |
122 | case MODULE_CHECK ... MAX_CHECK - 1: | ||
123 | default: | ||
124 | iint->flags |= (IMA_READ_APPRAISED | IMA_APPRAISED); | ||
125 | break; | ||
130 | } | 126 | } |
131 | } | 127 | } |
132 | 128 | ||
133 | void ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len, | 129 | enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, |
134 | struct ima_digest_data *hash) | 130 | int xattr_len) |
135 | { | 131 | { |
136 | struct signature_v2_hdr *sig; | 132 | struct signature_v2_hdr *sig; |
137 | 133 | ||
138 | if (!xattr_value || xattr_len < 2) | 134 | if (!xattr_value || xattr_len < 2) |
139 | return; | 135 | /* return default hash algo */ |
136 | return ima_hash_algo; | ||
140 | 137 | ||
141 | switch (xattr_value->type) { | 138 | switch (xattr_value->type) { |
142 | case EVM_IMA_XATTR_DIGSIG: | 139 | case EVM_IMA_XATTR_DIGSIG: |
143 | sig = (typeof(sig))xattr_value; | 140 | sig = (typeof(sig))xattr_value; |
144 | if (sig->version != 2 || xattr_len <= sizeof(*sig)) | 141 | if (sig->version != 2 || xattr_len <= sizeof(*sig)) |
145 | return; | 142 | return ima_hash_algo; |
146 | hash->algo = sig->hash_algo; | 143 | return sig->hash_algo; |
147 | break; | 144 | break; |
148 | case IMA_XATTR_DIGEST_NG: | 145 | case IMA_XATTR_DIGEST_NG: |
149 | hash->algo = xattr_value->digest[0]; | 146 | return xattr_value->digest[0]; |
150 | break; | 147 | break; |
151 | case IMA_XATTR_DIGEST: | 148 | case IMA_XATTR_DIGEST: |
152 | /* this is for backward compatibility */ | 149 | /* this is for backward compatibility */ |
153 | if (xattr_len == 21) { | 150 | if (xattr_len == 21) { |
154 | unsigned int zero = 0; | 151 | unsigned int zero = 0; |
155 | if (!memcmp(&xattr_value->digest[16], &zero, 4)) | 152 | if (!memcmp(&xattr_value->digest[16], &zero, 4)) |
156 | hash->algo = HASH_ALGO_MD5; | 153 | return HASH_ALGO_MD5; |
157 | else | 154 | else |
158 | hash->algo = HASH_ALGO_SHA1; | 155 | return HASH_ALGO_SHA1; |
159 | } else if (xattr_len == 17) | 156 | } else if (xattr_len == 17) |
160 | hash->algo = HASH_ALGO_MD5; | 157 | return HASH_ALGO_MD5; |
161 | break; | 158 | break; |
162 | } | 159 | } |
160 | |||
161 | /* return default hash algo */ | ||
162 | return ima_hash_algo; | ||
163 | } | 163 | } |
164 | 164 | ||
165 | int ima_read_xattr(struct dentry *dentry, | 165 | int ima_read_xattr(struct dentry *dentry, |
@@ -182,7 +182,8 @@ int ima_read_xattr(struct dentry *dentry, | |||
182 | * | 182 | * |
183 | * Return 0 on success, error code otherwise | 183 | * Return 0 on success, error code otherwise |
184 | */ | 184 | */ |
185 | int ima_appraise_measurement(int func, struct integrity_iint_cache *iint, | 185 | int ima_appraise_measurement(enum ima_hooks func, |
186 | struct integrity_iint_cache *iint, | ||
186 | struct file *file, const unsigned char *filename, | 187 | struct file *file, const unsigned char *filename, |
187 | struct evm_ima_xattr_data *xattr_value, | 188 | struct evm_ima_xattr_data *xattr_value, |
188 | int xattr_len, int opened) | 189 | int xattr_len, int opened) |
@@ -296,7 +297,7 @@ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file) | |||
296 | if (iint->flags & IMA_DIGSIG) | 297 | if (iint->flags & IMA_DIGSIG) |
297 | return; | 298 | return; |
298 | 299 | ||
299 | rc = ima_collect_measurement(iint, file, NULL, NULL); | 300 | rc = ima_collect_measurement(iint, file, NULL, 0, ima_hash_algo); |
300 | if (rc < 0) | 301 | if (rc < 0) |
301 | return; | 302 | return; |
302 | 303 | ||
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 6eb62936c672..38f2ed830dd6 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <crypto/hash.h> | 26 | #include <crypto/hash.h> |
27 | #include <crypto/hash_info.h> | 27 | |
28 | #include "ima.h" | 28 | #include "ima.h" |
29 | 29 | ||
30 | struct ahash_completion { | 30 | struct ahash_completion { |
@@ -519,6 +519,124 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data, | |||
519 | return rc; | 519 | return rc; |
520 | } | 520 | } |
521 | 521 | ||
522 | static int calc_buffer_ahash_atfm(const void *buf, loff_t len, | ||
523 | struct ima_digest_data *hash, | ||
524 | struct crypto_ahash *tfm) | ||
525 | { | ||
526 | struct ahash_request *req; | ||
527 | struct scatterlist sg; | ||
528 | struct ahash_completion res; | ||
529 | int rc, ahash_rc = 0; | ||
530 | |||
531 | hash->length = crypto_ahash_digestsize(tfm); | ||
532 | |||
533 | req = ahash_request_alloc(tfm, GFP_KERNEL); | ||
534 | if (!req) | ||
535 | return -ENOMEM; | ||
536 | |||
537 | init_completion(&res.completion); | ||
538 | ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | | ||
539 | CRYPTO_TFM_REQ_MAY_SLEEP, | ||
540 | ahash_complete, &res); | ||
541 | |||
542 | rc = ahash_wait(crypto_ahash_init(req), &res); | ||
543 | if (rc) | ||
544 | goto out; | ||
545 | |||
546 | sg_init_one(&sg, buf, len); | ||
547 | ahash_request_set_crypt(req, &sg, NULL, len); | ||
548 | |||
549 | ahash_rc = crypto_ahash_update(req); | ||
550 | |||
551 | /* wait for the update request to complete */ | ||
552 | rc = ahash_wait(ahash_rc, &res); | ||
553 | if (!rc) { | ||
554 | ahash_request_set_crypt(req, NULL, hash->digest, 0); | ||
555 | rc = ahash_wait(crypto_ahash_final(req), &res); | ||
556 | } | ||
557 | out: | ||
558 | ahash_request_free(req); | ||
559 | return rc; | ||
560 | } | ||
561 | |||
562 | static int calc_buffer_ahash(const void *buf, loff_t len, | ||
563 | struct ima_digest_data *hash) | ||
564 | { | ||
565 | struct crypto_ahash *tfm; | ||
566 | int rc; | ||
567 | |||
568 | tfm = ima_alloc_atfm(hash->algo); | ||
569 | if (IS_ERR(tfm)) | ||
570 | return PTR_ERR(tfm); | ||
571 | |||
572 | rc = calc_buffer_ahash_atfm(buf, len, hash, tfm); | ||
573 | |||
574 | ima_free_atfm(tfm); | ||
575 | |||
576 | return rc; | ||
577 | } | ||
578 | |||
579 | static int calc_buffer_shash_tfm(const void *buf, loff_t size, | ||
580 | struct ima_digest_data *hash, | ||
581 | struct crypto_shash *tfm) | ||
582 | { | ||
583 | SHASH_DESC_ON_STACK(shash, tfm); | ||
584 | unsigned int len; | ||
585 | int rc; | ||
586 | |||
587 | shash->tfm = tfm; | ||
588 | shash->flags = 0; | ||
589 | |||
590 | hash->length = crypto_shash_digestsize(tfm); | ||
591 | |||
592 | rc = crypto_shash_init(shash); | ||
593 | if (rc != 0) | ||
594 | return rc; | ||
595 | |||
596 | while (size) { | ||
597 | len = size < PAGE_SIZE ? size : PAGE_SIZE; | ||
598 | rc = crypto_shash_update(shash, buf, len); | ||
599 | if (rc) | ||
600 | break; | ||
601 | buf += len; | ||
602 | size -= len; | ||
603 | } | ||
604 | |||
605 | if (!rc) | ||
606 | rc = crypto_shash_final(shash, hash->digest); | ||
607 | return rc; | ||
608 | } | ||
609 | |||
610 | static int calc_buffer_shash(const void *buf, loff_t len, | ||
611 | struct ima_digest_data *hash) | ||
612 | { | ||
613 | struct crypto_shash *tfm; | ||
614 | int rc; | ||
615 | |||
616 | tfm = ima_alloc_tfm(hash->algo); | ||
617 | if (IS_ERR(tfm)) | ||
618 | return PTR_ERR(tfm); | ||
619 | |||
620 | rc = calc_buffer_shash_tfm(buf, len, hash, tfm); | ||
621 | |||
622 | ima_free_tfm(tfm); | ||
623 | return rc; | ||
624 | } | ||
625 | |||
626 | int ima_calc_buffer_hash(const void *buf, loff_t len, | ||
627 | struct ima_digest_data *hash) | ||
628 | { | ||
629 | int rc; | ||
630 | |||
631 | if (ima_ahash_minsize && len >= ima_ahash_minsize) { | ||
632 | rc = calc_buffer_ahash(buf, len, hash); | ||
633 | if (!rc) | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | return calc_buffer_shash(buf, len, hash); | ||
638 | } | ||
639 | |||
522 | static void __init ima_pcrread(int idx, u8 *pcr) | 640 | static void __init ima_pcrread(int idx, u8 *pcr) |
523 | { | 641 | { |
524 | if (!ima_used_chip) | 642 | if (!ima_used_chip) |
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index f355231997b4..60d011aaec38 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/rculist.h> | 22 | #include <linux/rculist.h> |
23 | #include <linux/rcupdate.h> | 23 | #include <linux/rcupdate.h> |
24 | #include <linux/parser.h> | 24 | #include <linux/parser.h> |
25 | #include <linux/vmalloc.h> | ||
25 | 26 | ||
26 | #include "ima.h" | 27 | #include "ima.h" |
27 | 28 | ||
@@ -258,6 +259,43 @@ static const struct file_operations ima_ascii_measurements_ops = { | |||
258 | .release = seq_release, | 259 | .release = seq_release, |
259 | }; | 260 | }; |
260 | 261 | ||
262 | static ssize_t ima_read_policy(char *path) | ||
263 | { | ||
264 | void *data; | ||
265 | char *datap; | ||
266 | loff_t size; | ||
267 | int rc, pathlen = strlen(path); | ||
268 | |||
269 | char *p; | ||
270 | |||
271 | /* remove \n */ | ||
272 | datap = path; | ||
273 | strsep(&datap, "\n"); | ||
274 | |||
275 | rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY); | ||
276 | if (rc < 0) { | ||
277 | pr_err("Unable to open file: %s (%d)", path, rc); | ||
278 | return rc; | ||
279 | } | ||
280 | |||
281 | datap = data; | ||
282 | while (size > 0 && (p = strsep(&datap, "\n"))) { | ||
283 | pr_debug("rule: %s\n", p); | ||
284 | rc = ima_parse_add_rule(p); | ||
285 | if (rc < 0) | ||
286 | break; | ||
287 | size -= rc; | ||
288 | } | ||
289 | |||
290 | vfree(data); | ||
291 | if (rc < 0) | ||
292 | return rc; | ||
293 | else if (size) | ||
294 | return -EINVAL; | ||
295 | else | ||
296 | return pathlen; | ||
297 | } | ||
298 | |||
261 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, | 299 | static ssize_t ima_write_policy(struct file *file, const char __user *buf, |
262 | size_t datalen, loff_t *ppos) | 300 | size_t datalen, loff_t *ppos) |
263 | { | 301 | { |
@@ -286,9 +324,20 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, | |||
286 | result = mutex_lock_interruptible(&ima_write_mutex); | 324 | result = mutex_lock_interruptible(&ima_write_mutex); |
287 | if (result < 0) | 325 | if (result < 0) |
288 | goto out_free; | 326 | goto out_free; |
289 | result = ima_parse_add_rule(data); | ||
290 | mutex_unlock(&ima_write_mutex); | ||
291 | 327 | ||
328 | if (data[0] == '/') { | ||
329 | result = ima_read_policy(data); | ||
330 | } else if (ima_appraise & IMA_APPRAISE_POLICY) { | ||
331 | pr_err("IMA: signed policy file (specified as an absolute pathname) required\n"); | ||
332 | integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, | ||
333 | "policy_update", "signed policy required", | ||
334 | 1, 0); | ||
335 | if (ima_appraise & IMA_APPRAISE_ENFORCE) | ||
336 | result = -EACCES; | ||
337 | } else { | ||
338 | result = ima_parse_add_rule(data); | ||
339 | } | ||
340 | mutex_unlock(&ima_write_mutex); | ||
292 | out_free: | 341 | out_free: |
293 | kfree(data); | 342 | kfree(data); |
294 | out: | 343 | out: |
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index bd79f254d204..5d679a685616 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <crypto/hash_info.h> | 24 | |
25 | #include "ima.h" | 25 | #include "ima.h" |
26 | 26 | ||
27 | /* name for boot aggregate entry */ | 27 | /* name for boot aggregate entry */ |
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 9d96551d0196..391f41751021 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/xattr.h> | 25 | #include <linux/xattr.h> |
26 | #include <linux/ima.h> | 26 | #include <linux/ima.h> |
27 | #include <crypto/hash_info.h> | ||
28 | 27 | ||
29 | #include "ima.h" | 28 | #include "ima.h" |
30 | 29 | ||
@@ -154,8 +153,8 @@ void ima_file_free(struct file *file) | |||
154 | ima_check_last_writer(iint, inode, file); | 153 | ima_check_last_writer(iint, inode, file); |
155 | } | 154 | } |
156 | 155 | ||
157 | static int process_measurement(struct file *file, int mask, int function, | 156 | static int process_measurement(struct file *file, char *buf, loff_t size, |
158 | int opened) | 157 | int mask, enum ima_hooks func, int opened) |
159 | { | 158 | { |
160 | struct inode *inode = file_inode(file); | 159 | struct inode *inode = file_inode(file); |
161 | struct integrity_iint_cache *iint = NULL; | 160 | struct integrity_iint_cache *iint = NULL; |
@@ -163,9 +162,10 @@ static int process_measurement(struct file *file, int mask, int function, | |||
163 | char *pathbuf = NULL; | 162 | char *pathbuf = NULL; |
164 | const char *pathname = NULL; | 163 | const char *pathname = NULL; |
165 | int rc = -ENOMEM, action, must_appraise; | 164 | int rc = -ENOMEM, action, must_appraise; |
166 | struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; | 165 | struct evm_ima_xattr_data *xattr_value = NULL; |
167 | int xattr_len = 0; | 166 | int xattr_len = 0; |
168 | bool violation_check; | 167 | bool violation_check; |
168 | enum hash_algo hash_algo; | ||
169 | 169 | ||
170 | if (!ima_policy_flag || !S_ISREG(inode->i_mode)) | 170 | if (!ima_policy_flag || !S_ISREG(inode->i_mode)) |
171 | return 0; | 171 | return 0; |
@@ -174,8 +174,8 @@ static int process_measurement(struct file *file, int mask, int function, | |||
174 | * bitmask based on the appraise/audit/measurement policy. | 174 | * bitmask based on the appraise/audit/measurement policy. |
175 | * Included is the appraise submask. | 175 | * Included is the appraise submask. |
176 | */ | 176 | */ |
177 | action = ima_get_action(inode, mask, function); | 177 | action = ima_get_action(inode, mask, func); |
178 | violation_check = ((function == FILE_CHECK || function == MMAP_CHECK) && | 178 | violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) && |
179 | (ima_policy_flag & IMA_MEASURE)); | 179 | (ima_policy_flag & IMA_MEASURE)); |
180 | if (!action && !violation_check) | 180 | if (!action && !violation_check) |
181 | return 0; | 181 | return 0; |
@@ -184,7 +184,7 @@ static int process_measurement(struct file *file, int mask, int function, | |||
184 | 184 | ||
185 | /* Is the appraise rule hook specific? */ | 185 | /* Is the appraise rule hook specific? */ |
186 | if (action & IMA_FILE_APPRAISE) | 186 | if (action & IMA_FILE_APPRAISE) |
187 | function = FILE_CHECK; | 187 | func = FILE_CHECK; |
188 | 188 | ||
189 | inode_lock(inode); | 189 | inode_lock(inode); |
190 | 190 | ||
@@ -214,16 +214,19 @@ static int process_measurement(struct file *file, int mask, int function, | |||
214 | /* Nothing to do, just return existing appraised status */ | 214 | /* Nothing to do, just return existing appraised status */ |
215 | if (!action) { | 215 | if (!action) { |
216 | if (must_appraise) | 216 | if (must_appraise) |
217 | rc = ima_get_cache_status(iint, function); | 217 | rc = ima_get_cache_status(iint, func); |
218 | goto out_digsig; | 218 | goto out_digsig; |
219 | } | 219 | } |
220 | 220 | ||
221 | template_desc = ima_template_desc_current(); | 221 | template_desc = ima_template_desc_current(); |
222 | if ((action & IMA_APPRAISE_SUBMASK) || | 222 | if ((action & IMA_APPRAISE_SUBMASK) || |
223 | strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) | 223 | strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0) |
224 | xattr_ptr = &xattr_value; | 224 | /* read 'security.ima' */ |
225 | xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value); | ||
225 | 226 | ||
226 | rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); | 227 | hash_algo = ima_get_hash_algo(xattr_value, xattr_len); |
228 | |||
229 | rc = ima_collect_measurement(iint, file, buf, size, hash_algo); | ||
227 | if (rc != 0) { | 230 | if (rc != 0) { |
228 | if (file->f_flags & O_DIRECT) | 231 | if (file->f_flags & O_DIRECT) |
229 | rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES; | 232 | rc = (iint->flags & IMA_PERMIT_DIRECTIO) ? 0 : -EACCES; |
@@ -237,7 +240,7 @@ static int process_measurement(struct file *file, int mask, int function, | |||
237 | ima_store_measurement(iint, file, pathname, | 240 | ima_store_measurement(iint, file, pathname, |
238 | xattr_value, xattr_len); | 241 | xattr_value, xattr_len); |
239 | if (action & IMA_APPRAISE_SUBMASK) | 242 | if (action & IMA_APPRAISE_SUBMASK) |
240 | rc = ima_appraise_measurement(function, iint, file, pathname, | 243 | rc = ima_appraise_measurement(func, iint, file, pathname, |
241 | xattr_value, xattr_len, opened); | 244 | xattr_value, xattr_len, opened); |
242 | if (action & IMA_AUDIT) | 245 | if (action & IMA_AUDIT) |
243 | ima_audit_measurement(iint, pathname); | 246 | ima_audit_measurement(iint, pathname); |
@@ -270,7 +273,8 @@ out: | |||
270 | int ima_file_mmap(struct file *file, unsigned long prot) | 273 | int ima_file_mmap(struct file *file, unsigned long prot) |
271 | { | 274 | { |
272 | if (file && (prot & PROT_EXEC)) | 275 | if (file && (prot & PROT_EXEC)) |
273 | return process_measurement(file, MAY_EXEC, MMAP_CHECK, 0); | 276 | return process_measurement(file, NULL, 0, MAY_EXEC, |
277 | MMAP_CHECK, 0); | ||
274 | return 0; | 278 | return 0; |
275 | } | 279 | } |
276 | 280 | ||
@@ -289,7 +293,8 @@ int ima_file_mmap(struct file *file, unsigned long prot) | |||
289 | */ | 293 | */ |
290 | int ima_bprm_check(struct linux_binprm *bprm) | 294 | int ima_bprm_check(struct linux_binprm *bprm) |
291 | { | 295 | { |
292 | return process_measurement(bprm->file, MAY_EXEC, BPRM_CHECK, 0); | 296 | return process_measurement(bprm->file, NULL, 0, MAY_EXEC, |
297 | BPRM_CHECK, 0); | ||
293 | } | 298 | } |
294 | 299 | ||
295 | /** | 300 | /** |
@@ -304,24 +309,26 @@ int ima_bprm_check(struct linux_binprm *bprm) | |||
304 | */ | 309 | */ |
305 | int ima_file_check(struct file *file, int mask, int opened) | 310 | int ima_file_check(struct file *file, int mask, int opened) |
306 | { | 311 | { |
307 | return process_measurement(file, | 312 | return process_measurement(file, NULL, 0, |
308 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), | 313 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), |
309 | FILE_CHECK, opened); | 314 | FILE_CHECK, opened); |
310 | } | 315 | } |
311 | EXPORT_SYMBOL_GPL(ima_file_check); | 316 | EXPORT_SYMBOL_GPL(ima_file_check); |
312 | 317 | ||
313 | /** | 318 | /** |
314 | * ima_module_check - based on policy, collect/store/appraise measurement. | 319 | * ima_read_file - pre-measure/appraise hook decision based on policy |
315 | * @file: pointer to the file to be measured/appraised | 320 | * @file: pointer to the file to be measured/appraised/audit |
321 | * @read_id: caller identifier | ||
316 | * | 322 | * |
317 | * Measure/appraise kernel modules based on policy. | 323 | * Permit reading a file based on policy. The policy rules are written |
324 | * in terms of the policy identifier. Appraising the integrity of | ||
325 | * a file requires a file descriptor. | ||
318 | * | 326 | * |
319 | * On success return 0. On integrity appraisal error, assuming the file | 327 | * For permission return 0, otherwise return -EACCES. |
320 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. | ||
321 | */ | 328 | */ |
322 | int ima_module_check(struct file *file) | 329 | int ima_read_file(struct file *file, enum kernel_read_file_id read_id) |
323 | { | 330 | { |
324 | if (!file) { | 331 | if (!file && read_id == READING_MODULE) { |
325 | #ifndef CONFIG_MODULE_SIG_FORCE | 332 | #ifndef CONFIG_MODULE_SIG_FORCE |
326 | if ((ima_appraise & IMA_APPRAISE_MODULES) && | 333 | if ((ima_appraise & IMA_APPRAISE_MODULES) && |
327 | (ima_appraise & IMA_APPRAISE_ENFORCE)) | 334 | (ima_appraise & IMA_APPRAISE_ENFORCE)) |
@@ -329,18 +336,53 @@ int ima_module_check(struct file *file) | |||
329 | #endif | 336 | #endif |
330 | return 0; /* We rely on module signature checking */ | 337 | return 0; /* We rely on module signature checking */ |
331 | } | 338 | } |
332 | return process_measurement(file, MAY_EXEC, MODULE_CHECK, 0); | 339 | return 0; |
333 | } | 340 | } |
334 | 341 | ||
335 | int ima_fw_from_file(struct file *file, char *buf, size_t size) | 342 | static int read_idmap[READING_MAX_ID] = { |
343 | [READING_FIRMWARE] = FIRMWARE_CHECK, | ||
344 | [READING_MODULE] = MODULE_CHECK, | ||
345 | [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK, | ||
346 | [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK, | ||
347 | [READING_POLICY] = POLICY_CHECK | ||
348 | }; | ||
349 | |||
350 | /** | ||
351 | * ima_post_read_file - in memory collect/appraise/audit measurement | ||
352 | * @file: pointer to the file to be measured/appraised/audit | ||
353 | * @buf: pointer to in memory file contents | ||
354 | * @size: size of in memory file contents | ||
355 | * @read_id: caller identifier | ||
356 | * | ||
357 | * Measure/appraise/audit in memory file based on policy. Policy rules | ||
358 | * are written in terms of a policy identifier. | ||
359 | * | ||
360 | * On success return 0. On integrity appraisal error, assuming the file | ||
361 | * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. | ||
362 | */ | ||
363 | int ima_post_read_file(struct file *file, void *buf, loff_t size, | ||
364 | enum kernel_read_file_id read_id) | ||
336 | { | 365 | { |
337 | if (!file) { | 366 | enum ima_hooks func; |
367 | |||
368 | if (!file && read_id == READING_FIRMWARE) { | ||
338 | if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && | 369 | if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && |
339 | (ima_appraise & IMA_APPRAISE_ENFORCE)) | 370 | (ima_appraise & IMA_APPRAISE_ENFORCE)) |
340 | return -EACCES; /* INTEGRITY_UNKNOWN */ | 371 | return -EACCES; /* INTEGRITY_UNKNOWN */ |
341 | return 0; | 372 | return 0; |
342 | } | 373 | } |
343 | return process_measurement(file, MAY_EXEC, FIRMWARE_CHECK, 0); | 374 | |
375 | if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */ | ||
376 | return 0; | ||
377 | |||
378 | if (!file || !buf || size == 0) { /* should never happen */ | ||
379 | if (ima_appraise & IMA_APPRAISE_ENFORCE) | ||
380 | return -EACCES; | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | func = read_idmap[read_id] ?: FILE_CHECK; | ||
385 | return process_measurement(file, buf, size, MAY_READ, func, 0); | ||
344 | } | 386 | } |
345 | 387 | ||
346 | static int __init init_ima(void) | 388 | static int __init init_ima(void) |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 0a3b781f18e5..be09e2cacf82 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/fs.h> | ||
15 | #include <linux/security.h> | 16 | #include <linux/security.h> |
16 | #include <linux/magic.h> | 17 | #include <linux/magic.h> |
17 | #include <linux/parser.h> | 18 | #include <linux/parser.h> |
@@ -113,6 +114,7 @@ static struct ima_rule_entry default_measurement_rules[] = { | |||
113 | .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID}, | 114 | .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID}, |
114 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, | 115 | {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, |
115 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, | 116 | {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, |
117 | {.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC}, | ||
116 | }; | 118 | }; |
117 | 119 | ||
118 | static struct ima_rule_entry default_appraise_rules[] = { | 120 | static struct ima_rule_entry default_appraise_rules[] = { |
@@ -127,6 +129,10 @@ static struct ima_rule_entry default_appraise_rules[] = { | |||
127 | {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, | 129 | {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, |
128 | {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, | 130 | {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, |
129 | {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, | 131 | {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, |
132 | #ifdef CONFIG_IMA_WRITE_POLICY | ||
133 | {.action = APPRAISE, .func = POLICY_CHECK, | ||
134 | .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, | ||
135 | #endif | ||
130 | #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT | 136 | #ifndef CONFIG_IMA_APPRAISE_SIGNED_INIT |
131 | {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, | 137 | {.action = APPRAISE, .fowner = GLOBAL_ROOT_UID, .flags = IMA_FOWNER}, |
132 | #else | 138 | #else |
@@ -207,8 +213,8 @@ static void ima_lsm_update_rules(void) | |||
207 | * | 213 | * |
208 | * Returns true on rule match, false on failure. | 214 | * Returns true on rule match, false on failure. |
209 | */ | 215 | */ |
210 | static bool ima_match_rules(struct ima_rule_entry *rule, | 216 | static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, |
211 | struct inode *inode, enum ima_hooks func, int mask) | 217 | enum ima_hooks func, int mask) |
212 | { | 218 | { |
213 | struct task_struct *tsk = current; | 219 | struct task_struct *tsk = current; |
214 | const struct cred *cred = current_cred(); | 220 | const struct cred *cred = current_cred(); |
@@ -289,7 +295,7 @@ retry: | |||
289 | * In addition to knowing that we need to appraise the file in general, | 295 | * In addition to knowing that we need to appraise the file in general, |
290 | * we need to differentiate between calling hooks, for hook specific rules. | 296 | * we need to differentiate between calling hooks, for hook specific rules. |
291 | */ | 297 | */ |
292 | static int get_subaction(struct ima_rule_entry *rule, int func) | 298 | static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) |
293 | { | 299 | { |
294 | if (!(rule->flags & IMA_FUNC)) | 300 | if (!(rule->flags & IMA_FUNC)) |
295 | return IMA_FILE_APPRAISE; | 301 | return IMA_FILE_APPRAISE; |
@@ -299,13 +305,12 @@ static int get_subaction(struct ima_rule_entry *rule, int func) | |||
299 | return IMA_MMAP_APPRAISE; | 305 | return IMA_MMAP_APPRAISE; |
300 | case BPRM_CHECK: | 306 | case BPRM_CHECK: |
301 | return IMA_BPRM_APPRAISE; | 307 | return IMA_BPRM_APPRAISE; |
302 | case MODULE_CHECK: | ||
303 | return IMA_MODULE_APPRAISE; | ||
304 | case FIRMWARE_CHECK: | ||
305 | return IMA_FIRMWARE_APPRAISE; | ||
306 | case FILE_CHECK: | 308 | case FILE_CHECK: |
307 | default: | 309 | case POST_SETATTR: |
308 | return IMA_FILE_APPRAISE; | 310 | return IMA_FILE_APPRAISE; |
311 | case MODULE_CHECK ... MAX_CHECK - 1: | ||
312 | default: | ||
313 | return IMA_READ_APPRAISE; | ||
309 | } | 314 | } |
310 | } | 315 | } |
311 | 316 | ||
@@ -411,13 +416,16 @@ void __init ima_init_policy(void) | |||
411 | for (i = 0; i < appraise_entries; i++) { | 416 | for (i = 0; i < appraise_entries; i++) { |
412 | list_add_tail(&default_appraise_rules[i].list, | 417 | list_add_tail(&default_appraise_rules[i].list, |
413 | &ima_default_rules); | 418 | &ima_default_rules); |
419 | if (default_appraise_rules[i].func == POLICY_CHECK) | ||
420 | temp_ima_appraise |= IMA_APPRAISE_POLICY; | ||
414 | } | 421 | } |
415 | 422 | ||
416 | ima_rules = &ima_default_rules; | 423 | ima_rules = &ima_default_rules; |
424 | ima_update_policy_flag(); | ||
417 | } | 425 | } |
418 | 426 | ||
419 | /* Make sure we have a valid policy, at least containing some rules. */ | 427 | /* Make sure we have a valid policy, at least containing some rules. */ |
420 | int ima_check_policy() | 428 | int ima_check_policy(void) |
421 | { | 429 | { |
422 | if (list_empty(&ima_temp_rules)) | 430 | if (list_empty(&ima_temp_rules)) |
423 | return -EINVAL; | 431 | return -EINVAL; |
@@ -612,6 +620,14 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
612 | entry->func = MMAP_CHECK; | 620 | entry->func = MMAP_CHECK; |
613 | else if (strcmp(args[0].from, "BPRM_CHECK") == 0) | 621 | else if (strcmp(args[0].from, "BPRM_CHECK") == 0) |
614 | entry->func = BPRM_CHECK; | 622 | entry->func = BPRM_CHECK; |
623 | else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") == | ||
624 | 0) | ||
625 | entry->func = KEXEC_KERNEL_CHECK; | ||
626 | else if (strcmp(args[0].from, "KEXEC_INITRAMFS_CHECK") | ||
627 | == 0) | ||
628 | entry->func = KEXEC_INITRAMFS_CHECK; | ||
629 | else if (strcmp(args[0].from, "POLICY_CHECK") == 0) | ||
630 | entry->func = POLICY_CHECK; | ||
615 | else | 631 | else |
616 | result = -EINVAL; | 632 | result = -EINVAL; |
617 | if (!result) | 633 | if (!result) |
@@ -770,6 +786,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) | |||
770 | temp_ima_appraise |= IMA_APPRAISE_MODULES; | 786 | temp_ima_appraise |= IMA_APPRAISE_MODULES; |
771 | else if (entry->func == FIRMWARE_CHECK) | 787 | else if (entry->func == FIRMWARE_CHECK) |
772 | temp_ima_appraise |= IMA_APPRAISE_FIRMWARE; | 788 | temp_ima_appraise |= IMA_APPRAISE_FIRMWARE; |
789 | else if (entry->func == POLICY_CHECK) | ||
790 | temp_ima_appraise |= IMA_APPRAISE_POLICY; | ||
773 | audit_log_format(ab, "res=%d", !result); | 791 | audit_log_format(ab, "res=%d", !result); |
774 | audit_log_end(ab); | 792 | audit_log_end(ab); |
775 | return result; | 793 | return result; |
@@ -855,7 +873,9 @@ static char *mask_tokens[] = { | |||
855 | 873 | ||
856 | enum { | 874 | enum { |
857 | func_file = 0, func_mmap, func_bprm, | 875 | func_file = 0, func_mmap, func_bprm, |
858 | func_module, func_firmware, func_post | 876 | func_module, func_firmware, func_post, |
877 | func_kexec_kernel, func_kexec_initramfs, | ||
878 | func_policy | ||
859 | }; | 879 | }; |
860 | 880 | ||
861 | static char *func_tokens[] = { | 881 | static char *func_tokens[] = { |
@@ -864,6 +884,9 @@ static char *func_tokens[] = { | |||
864 | "BPRM_CHECK", | 884 | "BPRM_CHECK", |
865 | "MODULE_CHECK", | 885 | "MODULE_CHECK", |
866 | "FIRMWARE_CHECK", | 886 | "FIRMWARE_CHECK", |
887 | "KEXEC_KERNEL_CHECK", | ||
888 | "KEXEC_INITRAMFS_CHECK", | ||
889 | "POLICY_CHECK", | ||
867 | "POST_SETATTR" | 890 | "POST_SETATTR" |
868 | }; | 891 | }; |
869 | 892 | ||
@@ -903,6 +926,49 @@ void ima_policy_stop(struct seq_file *m, void *v) | |||
903 | #define mt(token) mask_tokens[token] | 926 | #define mt(token) mask_tokens[token] |
904 | #define ft(token) func_tokens[token] | 927 | #define ft(token) func_tokens[token] |
905 | 928 | ||
929 | /* | ||
930 | * policy_func_show - display the ima_hooks policy rule | ||
931 | */ | ||
932 | static void policy_func_show(struct seq_file *m, enum ima_hooks func) | ||
933 | { | ||
934 | char tbuf[64] = {0,}; | ||
935 | |||
936 | switch (func) { | ||
937 | case FILE_CHECK: | ||
938 | seq_printf(m, pt(Opt_func), ft(func_file)); | ||
939 | break; | ||
940 | case MMAP_CHECK: | ||
941 | seq_printf(m, pt(Opt_func), ft(func_mmap)); | ||
942 | break; | ||
943 | case BPRM_CHECK: | ||
944 | seq_printf(m, pt(Opt_func), ft(func_bprm)); | ||
945 | break; | ||
946 | case MODULE_CHECK: | ||
947 | seq_printf(m, pt(Opt_func), ft(func_module)); | ||
948 | break; | ||
949 | case FIRMWARE_CHECK: | ||
950 | seq_printf(m, pt(Opt_func), ft(func_firmware)); | ||
951 | break; | ||
952 | case POST_SETATTR: | ||
953 | seq_printf(m, pt(Opt_func), ft(func_post)); | ||
954 | break; | ||
955 | case KEXEC_KERNEL_CHECK: | ||
956 | seq_printf(m, pt(Opt_func), ft(func_kexec_kernel)); | ||
957 | break; | ||
958 | case KEXEC_INITRAMFS_CHECK: | ||
959 | seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs)); | ||
960 | break; | ||
961 | case POLICY_CHECK: | ||
962 | seq_printf(m, pt(Opt_func), ft(func_policy)); | ||
963 | break; | ||
964 | default: | ||
965 | snprintf(tbuf, sizeof(tbuf), "%d", func); | ||
966 | seq_printf(m, pt(Opt_func), tbuf); | ||
967 | break; | ||
968 | } | ||
969 | seq_puts(m, " "); | ||
970 | } | ||
971 | |||
906 | int ima_policy_show(struct seq_file *m, void *v) | 972 | int ima_policy_show(struct seq_file *m, void *v) |
907 | { | 973 | { |
908 | struct ima_rule_entry *entry = v; | 974 | struct ima_rule_entry *entry = v; |
@@ -924,33 +990,8 @@ int ima_policy_show(struct seq_file *m, void *v) | |||
924 | 990 | ||
925 | seq_puts(m, " "); | 991 | seq_puts(m, " "); |
926 | 992 | ||
927 | if (entry->flags & IMA_FUNC) { | 993 | if (entry->flags & IMA_FUNC) |
928 | switch (entry->func) { | 994 | policy_func_show(m, entry->func); |
929 | case FILE_CHECK: | ||
930 | seq_printf(m, pt(Opt_func), ft(func_file)); | ||
931 | break; | ||
932 | case MMAP_CHECK: | ||
933 | seq_printf(m, pt(Opt_func), ft(func_mmap)); | ||
934 | break; | ||
935 | case BPRM_CHECK: | ||
936 | seq_printf(m, pt(Opt_func), ft(func_bprm)); | ||
937 | break; | ||
938 | case MODULE_CHECK: | ||
939 | seq_printf(m, pt(Opt_func), ft(func_module)); | ||
940 | break; | ||
941 | case FIRMWARE_CHECK: | ||
942 | seq_printf(m, pt(Opt_func), ft(func_firmware)); | ||
943 | break; | ||
944 | case POST_SETATTR: | ||
945 | seq_printf(m, pt(Opt_func), ft(func_post)); | ||
946 | break; | ||
947 | default: | ||
948 | snprintf(tbuf, sizeof(tbuf), "%d", entry->func); | ||
949 | seq_printf(m, pt(Opt_func), tbuf); | ||
950 | break; | ||
951 | } | ||
952 | seq_puts(m, " "); | ||
953 | } | ||
954 | 995 | ||
955 | if (entry->flags & IMA_MASK) { | 996 | if (entry->flags & IMA_MASK) { |
956 | if (entry->mask & MAY_EXEC) | 997 | if (entry->mask & MAY_EXEC) |
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 0b7404ebfa80..febd12ed9b55 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c | |||
@@ -15,8 +15,6 @@ | |||
15 | 15 | ||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
17 | 17 | ||
18 | #include <crypto/hash_info.h> | ||
19 | |||
20 | #include "ima.h" | 18 | #include "ima.h" |
21 | #include "ima_template_lib.h" | 19 | #include "ima_template_lib.h" |
22 | 20 | ||
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 2934e3d377f1..f9bae04ba176 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * File: ima_template_lib.c | 12 | * File: ima_template_lib.c |
13 | * Library of supported template fields. | 13 | * Library of supported template fields. |
14 | */ | 14 | */ |
15 | #include <crypto/hash_info.h> | ||
16 | 15 | ||
17 | #include "ima_template_lib.h" | 16 | #include "ima_template_lib.h" |
18 | 17 | ||
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 5efe2ecc538d..e08935cf343f 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h | |||
@@ -45,16 +45,12 @@ | |||
45 | #define IMA_MMAP_APPRAISED 0x00000800 | 45 | #define IMA_MMAP_APPRAISED 0x00000800 |
46 | #define IMA_BPRM_APPRAISE 0x00001000 | 46 | #define IMA_BPRM_APPRAISE 0x00001000 |
47 | #define IMA_BPRM_APPRAISED 0x00002000 | 47 | #define IMA_BPRM_APPRAISED 0x00002000 |
48 | #define IMA_MODULE_APPRAISE 0x00004000 | 48 | #define IMA_READ_APPRAISE 0x00004000 |
49 | #define IMA_MODULE_APPRAISED 0x00008000 | 49 | #define IMA_READ_APPRAISED 0x00008000 |
50 | #define IMA_FIRMWARE_APPRAISE 0x00010000 | ||
51 | #define IMA_FIRMWARE_APPRAISED 0x00020000 | ||
52 | #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ | 50 | #define IMA_APPRAISE_SUBMASK (IMA_FILE_APPRAISE | IMA_MMAP_APPRAISE | \ |
53 | IMA_BPRM_APPRAISE | IMA_MODULE_APPRAISE | \ | 51 | IMA_BPRM_APPRAISE | IMA_READ_APPRAISE) |
54 | IMA_FIRMWARE_APPRAISE) | ||
55 | #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ | 52 | #define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \ |
56 | IMA_BPRM_APPRAISED | IMA_MODULE_APPRAISED | \ | 53 | IMA_BPRM_APPRAISED | IMA_READ_APPRAISED) |
57 | IMA_FIRMWARE_APPRAISED) | ||
58 | 54 | ||
59 | enum evm_ima_xattr_type { | 55 | enum evm_ima_xattr_type { |
60 | IMA_XATTR_DIGEST = 0x01, | 56 | IMA_XATTR_DIGEST = 0x01, |
@@ -94,7 +90,7 @@ struct ima_digest_data { | |||
94 | struct signature_v2_hdr { | 90 | struct signature_v2_hdr { |
95 | uint8_t type; /* xattr type */ | 91 | uint8_t type; /* xattr type */ |
96 | uint8_t version; /* signature format version */ | 92 | uint8_t version; /* signature format version */ |
97 | uint8_t hash_algo; /* Digest algorithm [enum pkey_hash_algo] */ | 93 | uint8_t hash_algo; /* Digest algorithm [enum hash_algo] */ |
98 | uint32_t keyid; /* IMA key identifier - not X509/PGP specific */ | 94 | uint32_t keyid; /* IMA key identifier - not X509/PGP specific */ |
99 | uint16_t sig_size; /* signature size */ | 95 | uint16_t sig_size; /* signature size */ |
100 | uint8_t sig[0]; /* signature payload */ | 96 | uint8_t sig[0]; /* signature payload */ |
@@ -109,8 +105,7 @@ struct integrity_iint_cache { | |||
109 | enum integrity_status ima_file_status:4; | 105 | enum integrity_status ima_file_status:4; |
110 | enum integrity_status ima_mmap_status:4; | 106 | enum integrity_status ima_mmap_status:4; |
111 | enum integrity_status ima_bprm_status:4; | 107 | enum integrity_status ima_bprm_status:4; |
112 | enum integrity_status ima_module_status:4; | 108 | enum integrity_status ima_read_status:4; |
113 | enum integrity_status ima_firmware_status:4; | ||
114 | enum integrity_status evm_status:4; | 109 | enum integrity_status evm_status:4; |
115 | struct ima_digest_data *ima_hash; | 110 | struct ima_digest_data *ima_hash; |
116 | }; | 111 | }; |
diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 907c1522ee46..c721e398893a 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c | |||
@@ -9,7 +9,6 @@ | |||
9 | * 2 of the Licence, or (at your option) any later version. | 9 | * 2 of the Licence, or (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | 12 | #include <linux/init.h> |
14 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
15 | #include <linux/file.h> | 14 | #include <linux/file.h> |
@@ -18,8 +17,6 @@ | |||
18 | #include <keys/user-type.h> | 17 | #include <keys/user-type.h> |
19 | #include <keys/big_key-type.h> | 18 | #include <keys/big_key-type.h> |
20 | 19 | ||
21 | MODULE_LICENSE("GPL"); | ||
22 | |||
23 | /* | 20 | /* |
24 | * Layout of key payload words. | 21 | * Layout of key payload words. |
25 | */ | 22 | */ |
@@ -212,18 +209,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) | |||
212 | return ret; | 209 | return ret; |
213 | } | 210 | } |
214 | 211 | ||
215 | /* | ||
216 | * Module stuff | ||
217 | */ | ||
218 | static int __init big_key_init(void) | 212 | static int __init big_key_init(void) |
219 | { | 213 | { |
220 | return register_key_type(&key_type_big_key); | 214 | return register_key_type(&key_type_big_key); |
221 | } | 215 | } |
222 | 216 | device_initcall(big_key_init); | |
223 | static void __exit big_key_cleanup(void) | ||
224 | { | ||
225 | unregister_key_type(&key_type_big_key); | ||
226 | } | ||
227 | |||
228 | module_init(big_key_init); | ||
229 | module_exit(big_key_cleanup); | ||
diff --git a/security/keys/key.c b/security/keys/key.c index 09ef276c4bdc..b28755131687 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -296,6 +296,8 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
296 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; | 296 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; |
297 | if (flags & KEY_ALLOC_TRUSTED) | 297 | if (flags & KEY_ALLOC_TRUSTED) |
298 | key->flags |= 1 << KEY_FLAG_TRUSTED; | 298 | key->flags |= 1 << KEY_FLAG_TRUSTED; |
299 | if (flags & KEY_ALLOC_BUILT_IN) | ||
300 | key->flags |= 1 << KEY_FLAG_BUILTIN; | ||
299 | 301 | ||
300 | #ifdef KEY_DEBUGGING | 302 | #ifdef KEY_DEBUGGING |
301 | key->magic = KEY_DEBUG_MAGIC; | 303 | key->magic = KEY_DEBUG_MAGIC; |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 0dcab20cdacd..90d61751ff12 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
@@ -744,6 +744,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
744 | unsigned long handle; | 744 | unsigned long handle; |
745 | unsigned long lock; | 745 | unsigned long lock; |
746 | unsigned long token_mask = 0; | 746 | unsigned long token_mask = 0; |
747 | unsigned int digest_len; | ||
747 | int i; | 748 | int i; |
748 | int tpm2; | 749 | int tpm2; |
749 | 750 | ||
@@ -752,7 +753,6 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
752 | return tpm2; | 753 | return tpm2; |
753 | 754 | ||
754 | opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; | 755 | opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; |
755 | opt->digest_len = hash_digest_size[opt->hash]; | ||
756 | 756 | ||
757 | while ((p = strsep(&c, " \t"))) { | 757 | while ((p = strsep(&c, " \t"))) { |
758 | if (*p == '\0' || *p == ' ' || *p == '\t') | 758 | if (*p == '\0' || *p == ' ' || *p == '\t') |
@@ -812,8 +812,6 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
812 | for (i = 0; i < HASH_ALGO__LAST; i++) { | 812 | for (i = 0; i < HASH_ALGO__LAST; i++) { |
813 | if (!strcmp(args[0].from, hash_algo_name[i])) { | 813 | if (!strcmp(args[0].from, hash_algo_name[i])) { |
814 | opt->hash = i; | 814 | opt->hash = i; |
815 | opt->digest_len = | ||
816 | hash_digest_size[opt->hash]; | ||
817 | break; | 815 | break; |
818 | } | 816 | } |
819 | } | 817 | } |
@@ -825,13 +823,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
825 | } | 823 | } |
826 | break; | 824 | break; |
827 | case Opt_policydigest: | 825 | case Opt_policydigest: |
828 | if (!tpm2 || | 826 | digest_len = hash_digest_size[opt->hash]; |
829 | strlen(args[0].from) != (2 * opt->digest_len)) | 827 | if (!tpm2 || strlen(args[0].from) != (2 * digest_len)) |
830 | return -EINVAL; | 828 | return -EINVAL; |
831 | res = hex2bin(opt->policydigest, args[0].from, | 829 | res = hex2bin(opt->policydigest, args[0].from, |
832 | opt->digest_len); | 830 | digest_len); |
833 | if (res < 0) | 831 | if (res < 0) |
834 | return -EINVAL; | 832 | return -EINVAL; |
833 | opt->policydigest_len = digest_len; | ||
835 | break; | 834 | break; |
836 | case Opt_policyhandle: | 835 | case Opt_policyhandle: |
837 | if (!tpm2) | 836 | if (!tpm2) |
diff --git a/security/security.c b/security/security.c index e8ffd92ae2eb..3644b0344d29 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -884,31 +884,33 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
884 | return call_int_hook(kernel_create_files_as, 0, new, inode); | 884 | return call_int_hook(kernel_create_files_as, 0, new, inode); |
885 | } | 885 | } |
886 | 886 | ||
887 | int security_kernel_fw_from_file(struct file *file, char *buf, size_t size) | 887 | int security_kernel_module_request(char *kmod_name) |
888 | { | ||
889 | return call_int_hook(kernel_module_request, 0, kmod_name); | ||
890 | } | ||
891 | |||
892 | int security_kernel_read_file(struct file *file, enum kernel_read_file_id id) | ||
888 | { | 893 | { |
889 | int ret; | 894 | int ret; |
890 | 895 | ||
891 | ret = call_int_hook(kernel_fw_from_file, 0, file, buf, size); | 896 | ret = call_int_hook(kernel_read_file, 0, file, id); |
892 | if (ret) | 897 | if (ret) |
893 | return ret; | 898 | return ret; |
894 | return ima_fw_from_file(file, buf, size); | 899 | return ima_read_file(file, id); |
895 | } | ||
896 | EXPORT_SYMBOL_GPL(security_kernel_fw_from_file); | ||
897 | |||
898 | int security_kernel_module_request(char *kmod_name) | ||
899 | { | ||
900 | return call_int_hook(kernel_module_request, 0, kmod_name); | ||
901 | } | 900 | } |
901 | EXPORT_SYMBOL_GPL(security_kernel_read_file); | ||
902 | 902 | ||
903 | int security_kernel_module_from_file(struct file *file) | 903 | int security_kernel_post_read_file(struct file *file, char *buf, loff_t size, |
904 | enum kernel_read_file_id id) | ||
904 | { | 905 | { |
905 | int ret; | 906 | int ret; |
906 | 907 | ||
907 | ret = call_int_hook(kernel_module_from_file, 0, file); | 908 | ret = call_int_hook(kernel_post_read_file, 0, file, buf, size, id); |
908 | if (ret) | 909 | if (ret) |
909 | return ret; | 910 | return ret; |
910 | return ima_module_check(file); | 911 | return ima_post_read_file(file, buf, size, id); |
911 | } | 912 | } |
913 | EXPORT_SYMBOL_GPL(security_kernel_post_read_file); | ||
912 | 914 | ||
913 | int security_task_fix_setuid(struct cred *new, const struct cred *old, | 915 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
914 | int flags) | 916 | int flags) |
@@ -1691,12 +1693,12 @@ struct security_hook_heads security_hook_heads = { | |||
1691 | LIST_HEAD_INIT(security_hook_heads.kernel_act_as), | 1693 | LIST_HEAD_INIT(security_hook_heads.kernel_act_as), |
1692 | .kernel_create_files_as = | 1694 | .kernel_create_files_as = |
1693 | LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as), | 1695 | LIST_HEAD_INIT(security_hook_heads.kernel_create_files_as), |
1694 | .kernel_fw_from_file = | ||
1695 | LIST_HEAD_INIT(security_hook_heads.kernel_fw_from_file), | ||
1696 | .kernel_module_request = | 1696 | .kernel_module_request = |
1697 | LIST_HEAD_INIT(security_hook_heads.kernel_module_request), | 1697 | LIST_HEAD_INIT(security_hook_heads.kernel_module_request), |
1698 | .kernel_module_from_file = | 1698 | .kernel_read_file = |
1699 | LIST_HEAD_INIT(security_hook_heads.kernel_module_from_file), | 1699 | LIST_HEAD_INIT(security_hook_heads.kernel_read_file), |
1700 | .kernel_post_read_file = | ||
1701 | LIST_HEAD_INIT(security_hook_heads.kernel_post_read_file), | ||
1700 | .task_fix_setuid = | 1702 | .task_fix_setuid = |
1701 | LIST_HEAD_INIT(security_hook_heads.task_fix_setuid), | 1703 | LIST_HEAD_INIT(security_hook_heads.task_fix_setuid), |
1702 | .task_setpgid = LIST_HEAD_INIT(security_hook_heads.task_setpgid), | 1704 | .task_setpgid = LIST_HEAD_INIT(security_hook_heads.task_setpgid), |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index ad5cd76ec231..3411c33e2a44 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
@@ -13,7 +13,7 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | |||
13 | 13 | ||
14 | selinux-$(CONFIG_NETLABEL) += netlabel.o | 14 | selinux-$(CONFIG_NETLABEL) += netlabel.o |
15 | 15 | ||
16 | ccflags-y := -Isecurity/selinux -Isecurity/selinux/include | 16 | ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include |
17 | 17 | ||
18 | $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h | 18 | $(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h |
19 | 19 | ||
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2d6e9bdea398..11f79013ae1f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1442,9 +1442,13 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) | |||
1442 | * Don't do anything special for these. | 1442 | * Don't do anything special for these. |
1443 | * XATTR_NAME_SMACKIPIN | 1443 | * XATTR_NAME_SMACKIPIN |
1444 | * XATTR_NAME_SMACKIPOUT | 1444 | * XATTR_NAME_SMACKIPOUT |
1445 | * XATTR_NAME_SMACKEXEC | ||
1446 | */ | 1445 | */ |
1447 | if (strcmp(name, XATTR_NAME_SMACK) == 0) | 1446 | if (strcmp(name, XATTR_NAME_SMACK) == 0) { |
1447 | struct super_block *sbp = d_backing_inode(dentry)->i_sb; | ||
1448 | struct superblock_smack *sbsp = sbp->s_security; | ||
1449 | |||
1450 | isp->smk_inode = sbsp->smk_default; | ||
1451 | } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) | ||
1448 | isp->smk_task = NULL; | 1452 | isp->smk_task = NULL; |
1449 | else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) | 1453 | else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) |
1450 | isp->smk_mmap = NULL; | 1454 | isp->smk_mmap = NULL; |
@@ -1545,12 +1549,8 @@ static void smack_inode_getsecid(struct inode *inode, u32 *secid) | |||
1545 | * File Hooks | 1549 | * File Hooks |
1546 | */ | 1550 | */ |
1547 | 1551 | ||
1548 | /** | 1552 | /* |
1549 | * smack_file_permission - Smack check on file operations | 1553 | * There is no smack_file_permission hook |
1550 | * @file: unused | ||
1551 | * @mask: unused | ||
1552 | * | ||
1553 | * Returns 0 | ||
1554 | * | 1554 | * |
1555 | * Should access checks be done on each read or write? | 1555 | * Should access checks be done on each read or write? |
1556 | * UNICOS and SELinux say yes. | 1556 | * UNICOS and SELinux say yes. |
@@ -1559,10 +1559,6 @@ static void smack_inode_getsecid(struct inode *inode, u32 *secid) | |||
1559 | * I'll say no for now. Smack does not do the frequent | 1559 | * I'll say no for now. Smack does not do the frequent |
1560 | * label changing that SELinux does. | 1560 | * label changing that SELinux does. |
1561 | */ | 1561 | */ |
1562 | static int smack_file_permission(struct file *file, int mask) | ||
1563 | { | ||
1564 | return 0; | ||
1565 | } | ||
1566 | 1562 | ||
1567 | /** | 1563 | /** |
1568 | * smack_file_alloc_security - assign a file security blob | 1564 | * smack_file_alloc_security - assign a file security blob |
@@ -4503,16 +4499,10 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, | |||
4503 | return 0; | 4499 | return 0; |
4504 | } | 4500 | } |
4505 | 4501 | ||
4506 | /** | 4502 | /* |
4507 | * smack_audit_rule_free - free smack rule representation | 4503 | * There is no need for a smack_audit_rule_free hook. |
4508 | * @vrule: rule to be freed. | ||
4509 | * | ||
4510 | * No memory was allocated. | 4504 | * No memory was allocated. |
4511 | */ | 4505 | */ |
4512 | static void smack_audit_rule_free(void *vrule) | ||
4513 | { | ||
4514 | /* No-op */ | ||
4515 | } | ||
4516 | 4506 | ||
4517 | #endif /* CONFIG_AUDIT */ | 4507 | #endif /* CONFIG_AUDIT */ |
4518 | 4508 | ||
@@ -4563,16 +4553,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | |||
4563 | return 0; | 4553 | return 0; |
4564 | } | 4554 | } |
4565 | 4555 | ||
4566 | /** | 4556 | /* |
4567 | * smack_release_secctx - don't do anything. | 4557 | * There used to be a smack_release_secctx hook |
4568 | * @secdata: unused | 4558 | * that did nothing back when hooks were in a vector. |
4569 | * @seclen: unused | 4559 | * Now that there's a list such a hook adds cost. |
4570 | * | ||
4571 | * Exists to make sure nothing gets done, and properly | ||
4572 | */ | 4560 | */ |
4573 | static void smack_release_secctx(char *secdata, u32 seclen) | ||
4574 | { | ||
4575 | } | ||
4576 | 4561 | ||
4577 | static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) | 4562 | static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) |
4578 | { | 4563 | { |
@@ -4631,7 +4616,6 @@ static struct security_hook_list smack_hooks[] = { | |||
4631 | LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity), | 4616 | LSM_HOOK_INIT(inode_listsecurity, smack_inode_listsecurity), |
4632 | LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid), | 4617 | LSM_HOOK_INIT(inode_getsecid, smack_inode_getsecid), |
4633 | 4618 | ||
4634 | LSM_HOOK_INIT(file_permission, smack_file_permission), | ||
4635 | LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), | 4619 | LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), |
4636 | LSM_HOOK_INIT(file_free_security, smack_file_free_security), | 4620 | LSM_HOOK_INIT(file_free_security, smack_file_free_security), |
4637 | LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), | 4621 | LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), |
@@ -4726,13 +4710,11 @@ static struct security_hook_list smack_hooks[] = { | |||
4726 | LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init), | 4710 | LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init), |
4727 | LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known), | 4711 | LSM_HOOK_INIT(audit_rule_known, smack_audit_rule_known), |
4728 | LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match), | 4712 | LSM_HOOK_INIT(audit_rule_match, smack_audit_rule_match), |
4729 | LSM_HOOK_INIT(audit_rule_free, smack_audit_rule_free), | ||
4730 | #endif /* CONFIG_AUDIT */ | 4713 | #endif /* CONFIG_AUDIT */ |
4731 | 4714 | ||
4732 | LSM_HOOK_INIT(ismaclabel, smack_ismaclabel), | 4715 | LSM_HOOK_INIT(ismaclabel, smack_ismaclabel), |
4733 | LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx), | 4716 | LSM_HOOK_INIT(secid_to_secctx, smack_secid_to_secctx), |
4734 | LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid), | 4717 | LSM_HOOK_INIT(secctx_to_secid, smack_secctx_to_secid), |
4735 | LSM_HOOK_INIT(release_secctx, smack_release_secctx), | ||
4736 | LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx), | 4718 | LSM_HOOK_INIT(inode_notifysecctx, smack_inode_notifysecctx), |
4737 | LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx), | 4719 | LSM_HOOK_INIT(inode_setsecctx, smack_inode_setsecctx), |
4738 | LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx), | 4720 | LSM_HOOK_INIT(inode_getsecctx, smack_inode_getsecctx), |