Merge branch 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux

Pull module signing support from Rusty Russell:
"module signing is the highlight, but it's an all-over David Howells frenzy..."

Hmm "Magrathea: Glacier signing key". Somebody has been reading too much HHGTTG.

* 'modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (37 commits)
X.509: Fix indefinite length element skip error handling
X.509: Convert some printk calls to pr_devel
asymmetric keys: fix printk format warning
MODSIGN: Fix 32-bit overflow in X.509 certificate validity date checking
MODSIGN: Make mrproper should remove generated files.
MODSIGN: Use utf8 strings in signer's name in autogenerated X.509 certs
MODSIGN: Use the same digest for the autogen key sig as for the module sig
MODSIGN: Sign modules during the build process
MODSIGN: Provide a script for generating a key ID from an X.509 cert
MODSIGN: Implement module signature checking
MODSIGN: Provide module signing public keys to the kernel
MODSIGN: Automatically generate module signing keys if missing
MODSIGN: Provide Kconfig options
MODSIGN: Provide gitignore and make clean rules for extra files
MODSIGN: Add FIPS policy
module: signature checking hook
X.509: Add a crypto key parser for binary (DER) X.509 certificates
MPILIB: Provide a function to read raw data into an MPI
X.509: Add an ASN.1 decoder
X.509: Add simple ASN.1 grammar compiler
...

Changed files
+6799 -594
Documentation
arch
alpha
include
asm
arm
include
asm
avr32
include
asm
blackfin
include
asm
c6x
include
asm
cris
include
frv
include
asm
h8300
include
hexagon
ia64
include
asm
m32r
include
kernel
m68k
include
asm
microblaze
mips
mn10300
include
asm
openrisc
parisc
include
asm
powerpc
include
asm
s390
include
asm
score
include
asm
kernel
sh
include
asm
sparc
include
tile
unicore32
x86
xtensa
include
asm
crypto
fs
include
init
kernel
lib
net
ceph
dns_resolver
rxrpc
scripts
security
+14
.gitignore
··· 14 14 *.o.* 15 15 *.a 16 16 *.s 17 + *.ko.unsigned 18 + *.ko.stripped 19 + *.ko.stripped.dig 20 + *.ko.stripped.sig 17 21 *.ko 18 22 *.so 19 23 *.so.dbg ··· 88 84 *.orig 89 85 *~ 90 86 \#*# 87 + 88 + # 89 + # Leavings from module signing 90 + # 91 + extra_certificates 92 + signing_key.priv 93 + signing_key.x509 94 + signing_key.x509.keyid 95 + signing_key.x509.signer 96 + x509.genkey
+312
Documentation/crypto/asymmetric-keys.txt
··· 1 + ============================================= 2 + ASYMMETRIC / PUBLIC-KEY CRYPTOGRAPHY KEY TYPE 3 + ============================================= 4 + 5 + Contents: 6 + 7 + - Overview. 8 + - Key identification. 9 + - Accessing asymmetric keys. 10 + - Signature verification. 11 + - Asymmetric key subtypes. 12 + - Instantiation data parsers. 13 + 14 + 15 + ======== 16 + OVERVIEW 17 + ======== 18 + 19 + The "asymmetric" key type is designed to be a container for the keys used in 20 + public-key cryptography, without imposing any particular restrictions on the 21 + form or mechanism of the cryptography or form of the key. 22 + 23 + The asymmetric key is given a subtype that defines what sort of data is 24 + associated with the key and provides operations to describe and destroy it. 25 + However, no requirement is made that the key data actually be stored in the 26 + key. 27 + 28 + A completely in-kernel key retention and operation subtype can be defined, but 29 + it would also be possible to provide access to cryptographic hardware (such as 30 + a TPM) that might be used to both retain the relevant key and perform 31 + operations using that key. In such a case, the asymmetric key would then 32 + merely be an interface to the TPM driver. 33 + 34 + Also provided is the concept of a data parser. Data parsers are responsible 35 + for extracting information from the blobs of data passed to the instantiation 36 + function. The first data parser that recognises the blob gets to set the 37 + subtype of the key and define the operations that can be done on that key. 38 + 39 + A data parser may interpret the data blob as containing the bits representing a 40 + key, or it may interpret it as a reference to a key held somewhere else in the 41 + system (for example, a TPM). 42 + 43 + 44 + ================== 45 + KEY IDENTIFICATION 46 + ================== 47 + 48 + If a key is added with an empty name, the instantiation data parsers are given 49 + the opportunity to pre-parse a key and to determine the description the key 50 + should be given from the content of the key. 51 + 52 + This can then be used to refer to the key, either by complete match or by 53 + partial match. The key type may also use other criteria to refer to a key. 54 + 55 + The asymmetric key type's match function can then perform a wider range of 56 + comparisons than just the straightforward comparison of the description with 57 + the criterion string: 58 + 59 + (1) If the criterion string is of the form "id:<hexdigits>" then the match 60 + function will examine a key's fingerprint to see if the hex digits given 61 + after the "id:" match the tail. For instance: 62 + 63 + keyctl search @s asymmetric id:5acc2142 64 + 65 + will match a key with fingerprint: 66 + 67 + 1A00 2040 7601 7889 DE11 882C 3823 04AD 5ACC 2142 68 + 69 + (2) If the criterion string is of the form "<subtype>:<hexdigits>" then the 70 + match will match the ID as in (1), but with the added restriction that 71 + only keys of the specified subtype (e.g. tpm) will be matched. For 72 + instance: 73 + 74 + keyctl search @s asymmetric tpm:5acc2142 75 + 76 + Looking in /proc/keys, the last 8 hex digits of the key fingerprint are 77 + displayed, along with the subtype: 78 + 79 + 1a39e171 I----- 1 perm 3f010000 0 0 asymmetri modsign.0: DSA 5acc2142 [] 80 + 81 + 82 + ========================= 83 + ACCESSING ASYMMETRIC KEYS 84 + ========================= 85 + 86 + For general access to asymmetric keys from within the kernel, the following 87 + inclusion is required: 88 + 89 + #include <crypto/public_key.h> 90 + 91 + This gives access to functions for dealing with asymmetric / public keys. 92 + Three enums are defined there for representing public-key cryptography 93 + algorithms: 94 + 95 + enum pkey_algo 96 + 97 + digest algorithms used by those: 98 + 99 + enum pkey_hash_algo 100 + 101 + and key identifier representations: 102 + 103 + enum pkey_id_type 104 + 105 + Note that the key type representation types are required because key 106 + identifiers from different standards aren't necessarily compatible. For 107 + instance, PGP generates key identifiers by hashing the key data plus some 108 + PGP-specific metadata, whereas X.509 has arbitrary certificate identifiers. 109 + 110 + The operations defined upon a key are: 111 + 112 + (1) Signature verification. 113 + 114 + Other operations are possible (such as encryption) with the same key data 115 + required for verification, but not currently supported, and others 116 + (eg. decryption and signature generation) require extra key data. 117 + 118 + 119 + SIGNATURE VERIFICATION 120 + ---------------------- 121 + 122 + An operation is provided to perform cryptographic signature verification, using 123 + an asymmetric key to provide or to provide access to the public key. 124 + 125 + int verify_signature(const struct key *key, 126 + const struct public_key_signature *sig); 127 + 128 + The caller must have already obtained the key from some source and can then use 129 + it to check the signature. The caller must have parsed the signature and 130 + transferred the relevant bits to the structure pointed to by sig. 131 + 132 + struct public_key_signature { 133 + u8 *digest; 134 + u8 digest_size; 135 + enum pkey_hash_algo pkey_hash_algo : 8; 136 + u8 nr_mpi; 137 + union { 138 + MPI mpi[2]; 139 + ... 140 + }; 141 + }; 142 + 143 + The algorithm used must be noted in sig->pkey_hash_algo, and all the MPIs that 144 + make up the actual signature must be stored in sig->mpi[] and the count of MPIs 145 + placed in sig->nr_mpi. 146 + 147 + In addition, the data must have been digested by the caller and the resulting 148 + hash must be pointed to by sig->digest and the size of the hash be placed in 149 + sig->digest_size. 150 + 151 + The function will return 0 upon success or -EKEYREJECTED if the signature 152 + doesn't match. 153 + 154 + The function may also return -ENOTSUPP if an unsupported public-key algorithm 155 + or public-key/hash algorithm combination is specified or the key doesn't 156 + support the operation; -EBADMSG or -ERANGE if some of the parameters have weird 157 + data; or -ENOMEM if an allocation can't be performed. -EINVAL can be returned 158 + if the key argument is the wrong type or is incompletely set up. 159 + 160 + 161 + ======================= 162 + ASYMMETRIC KEY SUBTYPES 163 + ======================= 164 + 165 + Asymmetric keys have a subtype that defines the set of operations that can be 166 + performed on that key and that determines what data is attached as the key 167 + payload. The payload format is entirely at the whim of the subtype. 168 + 169 + The subtype is selected by the key data parser and the parser must initialise 170 + the data required for it. The asymmetric key retains a reference on the 171 + subtype module. 172 + 173 + The subtype definition structure can be found in: 174 + 175 + #include <keys/asymmetric-subtype.h> 176 + 177 + and looks like the following: 178 + 179 + struct asymmetric_key_subtype { 180 + struct module *owner; 181 + const char *name; 182 + 183 + void (*describe)(const struct key *key, struct seq_file *m); 184 + void (*destroy)(void *payload); 185 + int (*verify_signature)(const struct key *key, 186 + const struct public_key_signature *sig); 187 + }; 188 + 189 + Asymmetric keys point to this with their type_data[0] member. 190 + 191 + The owner and name fields should be set to the owning module and the name of 192 + the subtype. Currently, the name is only used for print statements. 193 + 194 + There are a number of operations defined by the subtype: 195 + 196 + (1) describe(). 197 + 198 + Mandatory. This allows the subtype to display something in /proc/keys 199 + against the key. For instance the name of the public key algorithm type 200 + could be displayed. The key type will display the tail of the key 201 + identity string after this. 202 + 203 + (2) destroy(). 204 + 205 + Mandatory. This should free the memory associated with the key. The 206 + asymmetric key will look after freeing the fingerprint and releasing the 207 + reference on the subtype module. 208 + 209 + (3) verify_signature(). 210 + 211 + Optional. These are the entry points for the key usage operations. 212 + Currently there is only the one defined. If not set, the caller will be 213 + given -ENOTSUPP. The subtype may do anything it likes to implement an 214 + operation, including offloading to hardware. 215 + 216 + 217 + ========================== 218 + INSTANTIATION DATA PARSERS 219 + ========================== 220 + 221 + The asymmetric key type doesn't generally want to store or to deal with a raw 222 + blob of data that holds the key data. It would have to parse it and error 223 + check it each time it wanted to use it. Further, the contents of the blob may 224 + have various checks that can be performed on it (eg. self-signatures, validity 225 + dates) and may contain useful data about the key (identifiers, capabilities). 226 + 227 + Also, the blob may represent a pointer to some hardware containing the key 228 + rather than the key itself. 229 + 230 + Examples of blob formats for which parsers could be implemented include: 231 + 232 + - OpenPGP packet stream [RFC 4880]. 233 + - X.509 ASN.1 stream. 234 + - Pointer to TPM key. 235 + - Pointer to UEFI key. 236 + 237 + During key instantiation each parser in the list is tried until one doesn't 238 + return -EBADMSG. 239 + 240 + The parser definition structure can be found in: 241 + 242 + #include <keys/asymmetric-parser.h> 243 + 244 + and looks like the following: 245 + 246 + struct asymmetric_key_parser { 247 + struct module *owner; 248 + const char *name; 249 + 250 + int (*parse)(struct key_preparsed_payload *prep); 251 + }; 252 + 253 + The owner and name fields should be set to the owning module and the name of 254 + the parser. 255 + 256 + There is currently only a single operation defined by the parser, and it is 257 + mandatory: 258 + 259 + (1) parse(). 260 + 261 + This is called to preparse the key from the key creation and update paths. 262 + In particular, it is called during the key creation _before_ a key is 263 + allocated, and as such, is permitted to provide the key's description in 264 + the case that the caller declines to do so. 265 + 266 + The caller passes a pointer to the following struct with all of the fields 267 + cleared, except for data, datalen and quotalen [see 268 + Documentation/security/keys.txt]. 269 + 270 + struct key_preparsed_payload { 271 + char *description; 272 + void *type_data[2]; 273 + void *payload; 274 + const void *data; 275 + size_t datalen; 276 + size_t quotalen; 277 + }; 278 + 279 + The instantiation data is in a blob pointed to by data and is datalen in 280 + size. The parse() function is not permitted to change these two values at 281 + all, and shouldn't change any of the other values _unless_ they are 282 + recognise the blob format and will not return -EBADMSG to indicate it is 283 + not theirs. 284 + 285 + If the parser is happy with the blob, it should propose a description for 286 + the key and attach it to ->description, ->type_data[0] should be set to 287 + point to the subtype to be used, ->payload should be set to point to the 288 + initialised data for that subtype, ->type_data[1] should point to a hex 289 + fingerprint and quotalen should be updated to indicate how much quota this 290 + key should account for. 291 + 292 + When clearing up, the data attached to ->type_data[1] and ->description 293 + will be kfree()'d and the data attached to ->payload will be passed to the 294 + subtype's ->destroy() method to be disposed of. A module reference for 295 + the subtype pointed to by ->type_data[0] will be put. 296 + 297 + 298 + If the data format is not recognised, -EBADMSG should be returned. If it 299 + is recognised, but the key cannot for some reason be set up, some other 300 + negative error code should be returned. On success, 0 should be returned. 301 + 302 + The key's fingerprint string may be partially matched upon. For a 303 + public-key algorithm such as RSA and DSA this will likely be a printable 304 + hex version of the key's fingerprint. 305 + 306 + Functions are provided to register and unregister parsers: 307 + 308 + int register_asymmetric_key_parser(struct asymmetric_key_parser *parser); 309 + void unregister_asymmetric_key_parser(struct asymmetric_key_parser *subtype); 310 + 311 + Parsers may not have the same name. The names are otherwise only used for 312 + displaying in debugging messages.
+6
Documentation/kernel-parameters.txt
··· 1593 1593 log everything. Information is printed at KERN_DEBUG 1594 1594 so loglevel=8 may also need to be specified. 1595 1595 1596 + module.sig_enforce 1597 + [KNL] When CONFIG_MODULE_SIG is set, this means that 1598 + modules without (valid) signatures will fail to load. 1599 + Note that if CONFIG_MODULE_SIG_ENFORCE is set, that 1600 + is always true, so this option does nothing. 1601 + 1596 1602 mousedev.tap_time= 1597 1603 [MOUSE] Maximum time between finger touching and 1598 1604 leaving touchpad surface for touch to be considered
+49 -1
Documentation/security/keys.txt
··· 412 412 to the keyring. In this case, an error will be generated if the process 413 413 does not have permission to write to the keyring. 414 414 415 + If the key type supports it, if the description is NULL or an empty 416 + string, the key type will try and generate a description from the content 417 + of the payload. 418 + 415 419 The payload is optional, and the pointer can be NULL if not required by 416 420 the type. The payload is plen in size, and plen can be zero for an empty 417 421 payload. ··· 1118 1114 it should return 0. 1119 1115 1120 1116 1121 - (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); 1117 + (*) int (*preparse)(struct key_preparsed_payload *prep); 1118 + 1119 + This optional method permits the key type to attempt to parse payload 1120 + before a key is created (add key) or the key semaphore is taken (update or 1121 + instantiate key). The structure pointed to by prep looks like: 1122 + 1123 + struct key_preparsed_payload { 1124 + char *description; 1125 + void *type_data[2]; 1126 + void *payload; 1127 + const void *data; 1128 + size_t datalen; 1129 + size_t quotalen; 1130 + }; 1131 + 1132 + Before calling the method, the caller will fill in data and datalen with 1133 + the payload blob parameters; quotalen will be filled in with the default 1134 + quota size from the key type and the rest will be cleared. 1135 + 1136 + If a description can be proposed from the payload contents, that should be 1137 + attached as a string to the description field. This will be used for the 1138 + key description if the caller of add_key() passes NULL or "". 1139 + 1140 + The method can attach anything it likes to type_data[] and payload. These 1141 + are merely passed along to the instantiate() or update() operations. 1142 + 1143 + The method should return 0 if success ful or a negative error code 1144 + otherwise. 1145 + 1146 + 1147 + (*) void (*free_preparse)(struct key_preparsed_payload *prep); 1148 + 1149 + This method is only required if the preparse() method is provided, 1150 + otherwise it is unused. It cleans up anything attached to the 1151 + description, type_data and payload fields of the key_preparsed_payload 1152 + struct as filled in by the preparse() method. 1153 + 1154 + 1155 + (*) int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); 1122 1156 1123 1157 This method is called to attach a payload to a key during construction. 1124 1158 The payload attached need not bear any relation to the data passed to this 1125 1159 function. 1160 + 1161 + The prep->data and prep->datalen fields will define the original payload 1162 + blob. If preparse() was supplied then other fields may be filled in also. 1126 1163 1127 1164 If the amount of data attached to the key differs from the size in 1128 1165 keytype->def_datalen, then key_payload_reserve() should be called. ··· 1179 1134 1180 1135 If this type of key can be updated, then this method should be provided. 1181 1136 It is called to update a key's payload from the blob of data provided. 1137 + 1138 + The prep->data and prep->datalen fields will define the original payload 1139 + blob. If preparse() was supplied then other fields may be filled in also. 1182 1140 1183 1141 key_payload_reserve() should be called if the data length might change 1184 1142 before any changes are actually made. Note that if this succeeds, the type
+5 -1
Makefile
··· 997 997 MRPROPER_DIRS += include/config usr/include include/generated \ 998 998 arch/*/include/generated 999 999 MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \ 1000 - Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS 1000 + Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ 1001 + signing_key.priv signing_key.x509 x509.genkey \ 1002 + extra_certificates signing_key.x509.keyid \ 1003 + signing_key.x509.signer 1001 1004 1002 1005 # clean - Delete most, but leave enough to build external modules 1003 1006 # ··· 1244 1241 $(call cmd,rmfiles) 1245 1242 @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ 1246 1243 \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ 1244 + -o -name '*.ko.*' \ 1247 1245 -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ 1248 1246 -o -name '*.symtypes' -o -name 'modules.order' \ 1249 1247 -o -name modules.builtin -o -name '.tmp_*.o.*' \
+19
arch/Kconfig
··· 322 322 config HAVE_ARCH_TRANSPARENT_HUGEPAGE 323 323 bool 324 324 325 + config HAVE_MOD_ARCH_SPECIFIC 326 + bool 327 + help 328 + The arch uses struct mod_arch_specific to store data. Many arches 329 + just need a simple module loader without arch specific data - those 330 + should not enable this. 331 + 332 + config MODULES_USE_ELF_RELA 333 + bool 334 + help 335 + Modules only use ELF RELA relocations. Modules with ELF REL 336 + relocations will give an error. 337 + 338 + config MODULES_USE_ELF_REL 339 + bool 340 + help 341 + Modules only use ELF REL relocations. Modules with ELF RELA 342 + relocations will give an error. 343 + 325 344 source "kernel/gcov/Kconfig"
+2
arch/alpha/Kconfig
··· 22 22 select GENERIC_STRNLEN_USER 23 23 select GENERIC_KERNEL_THREAD 24 24 select GENERIC_KERNEL_EXECVE 25 + select HAVE_MOD_ARCH_SPECIFIC 26 + select MODULES_USE_ELF_RELA 25 27 help 26 28 The Alpha is a 64-bit general-purpose processor designed and 27 29 marketed by the Digital Equipment Corporation of blessed memory,
+2 -8
arch/alpha/include/asm/module.h
··· 1 1 #ifndef _ALPHA_MODULE_H 2 2 #define _ALPHA_MODULE_H 3 3 4 + #include <asm-generic/module.h> 5 + 4 6 struct mod_arch_specific 5 7 { 6 8 unsigned int gotsecindex; 7 9 }; 8 - 9 - #define Elf_Sym Elf64_Sym 10 - #define Elf_Shdr Elf64_Shdr 11 - #define Elf_Ehdr Elf64_Ehdr 12 - #define Elf_Phdr Elf64_Phdr 13 - #define Elf_Dyn Elf64_Dyn 14 - #define Elf_Rel Elf64_Rel 15 - #define Elf_Rela Elf64_Rela 16 10 17 11 #define ARCH_SHF_SMALL SHF_ALPHA_GPREL 18 12
+2
arch/arm/Kconfig
··· 53 53 select PERF_USE_VMALLOC 54 54 select RTC_LIB 55 55 select SYS_SUPPORTS_APM_EMULATION 56 + select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND 57 + select MODULES_USE_ELF_REL 56 58 help 57 59 The ARM series is a line of low-power-consumption RISC chip designs 58 60 licensed by ARM Ltd and targeted at embedded applications and
+2 -6
arch/arm/include/asm/module.h
··· 1 1 #ifndef _ASM_ARM_MODULE_H 2 2 #define _ASM_ARM_MODULE_H 3 3 4 - #define Elf_Shdr Elf32_Shdr 5 - #define Elf_Sym Elf32_Sym 6 - #define Elf_Ehdr Elf32_Ehdr 4 + #include <asm-generic/module.h> 7 5 8 6 struct unwind_table; 9 7 ··· 14 16 ARM_SEC_DEVEXIT, 15 17 ARM_SEC_MAX, 16 18 }; 17 - #endif 18 19 19 20 struct mod_arch_specific { 20 - #ifdef CONFIG_ARM_UNWIND 21 21 struct unwind_table *unwind[ARM_SEC_MAX]; 22 - #endif 23 22 }; 23 + #endif 24 24 25 25 /* 26 26 * Add the ARM architecture version to the version magic string
+2
arch/avr32/Kconfig
··· 15 15 select ARCH_WANT_IPC_PARSE_VERSION 16 16 select ARCH_HAVE_NMI_SAFE_CMPXCHG 17 17 select GENERIC_CLOCKEVENTS 18 + select HAVE_MOD_ARCH_SPECIFIC 19 + select MODULES_USE_ELF_RELA 18 20 help 19 21 AVR32 is a high-performance 32-bit RISC microprocessor core, 20 22 designed for cost-sensitive embedded applications, with particular
+2 -4
arch/avr32/include/asm/module.h
··· 1 1 #ifndef __ASM_AVR32_MODULE_H 2 2 #define __ASM_AVR32_MODULE_H 3 3 4 + #include <asm-generic/module.h> 5 + 4 6 struct mod_arch_syminfo { 5 7 unsigned long got_offset; 6 8 int got_initialized; ··· 18 16 /* Additional symbol information (got offsets). */ 19 17 struct mod_arch_syminfo *syminfo; 20 18 }; 21 - 22 - #define Elf_Shdr Elf32_Shdr 23 - #define Elf_Sym Elf32_Sym 24 - #define Elf_Ehdr Elf32_Ehdr 25 19 26 20 #define MODULE_PROC_FAMILY "AVR32v1" 27 21
+2
arch/blackfin/Kconfig
··· 43 43 select HAVE_NMI_WATCHDOG if NMI_WATCHDOG 44 44 select GENERIC_SMP_IDLE_THREAD 45 45 select ARCH_USES_GETTIMEOFFSET if !GENERIC_CLOCKEVENTS 46 + select HAVE_MOD_ARCH_SPECIFIC 47 + select MODULES_USE_ELF_RELA 46 48 47 49 config GENERIC_CSUM 48 50 def_bool y
+1 -3
arch/blackfin/include/asm/module.h
··· 7 7 #ifndef _ASM_BFIN_MODULE_H 8 8 #define _ASM_BFIN_MODULE_H 9 9 10 - #define Elf_Shdr Elf32_Shdr 11 - #define Elf_Sym Elf32_Sym 12 - #define Elf_Ehdr Elf32_Ehdr 10 + #include <asm-generic/module.h> 13 11 14 12 struct mod_arch_specific { 15 13 Elf_Shdr *text_l1;
+1
arch/c6x/Kconfig
··· 18 18 select OF_EARLY_FLATTREE 19 19 select GENERIC_CLOCKEVENTS 20 20 select GENERIC_KERNEL_THREAD 21 + select MODULES_USE_ELF_RELA 21 22 22 23 config MMU 23 24 def_bool n
+1 -11
arch/c6x/include/asm/module.h
··· 13 13 #ifndef _ASM_C6X_MODULE_H 14 14 #define _ASM_C6X_MODULE_H 15 15 16 - #define Elf_Shdr Elf32_Shdr 17 - #define Elf_Sym Elf32_Sym 18 - #define Elf_Ehdr Elf32_Ehdr 19 - #define Elf_Addr Elf32_Addr 20 - #define Elf_Word Elf32_Word 21 - 22 - /* 23 - * This file contains the C6x architecture specific module code. 24 - */ 25 - struct mod_arch_specific { 26 - }; 16 + #include <asm-generic/module.h> 27 17 28 18 struct loaded_sections { 29 19 unsigned int new_vaddr;
+1
arch/cris/Kconfig
··· 48 48 select GENERIC_IOMAP 49 49 select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32 50 50 select GENERIC_CMOS_UPDATE 51 + select MODULES_USE_ELF_RELA 51 52 52 53 config HZ 53 54 int
+1
arch/cris/include/asm/Kbuild
··· 10 10 11 11 generic-y += clkdev.h 12 12 generic-y += exec.h 13 + generic-y += module.h
-9
arch/cris/include/asm/module.h
··· 1 - #ifndef _ASM_CRIS_MODULE_H 2 - #define _ASM_CRIS_MODULE_H 3 - /* cris is simple */ 4 - struct mod_arch_specific { }; 5 - 6 - #define Elf_Shdr Elf32_Shdr 7 - #define Elf_Sym Elf32_Sym 8 - #define Elf_Ehdr Elf32_Ehdr 9 - #endif /* _ASM_CRIS_MODULE_H */
+1 -7
arch/frv/include/asm/module.h
··· 11 11 #ifndef _ASM_MODULE_H 12 12 #define _ASM_MODULE_H 13 13 14 - struct mod_arch_specific 15 - { 16 - }; 17 - 18 - #define Elf_Shdr Elf32_Shdr 19 - #define Elf_Sym Elf32_Sym 20 - #define Elf_Ehdr Elf32_Ehdr 14 + #include <asm-generic/module.h> 21 15 22 16 /* 23 17 * Include the architecture version.
+1
arch/h8300/Kconfig
··· 7 7 select ARCH_WANT_IPC_PARSE_VERSION 8 8 select GENERIC_IRQ_SHOW 9 9 select GENERIC_CPU_DEVICES 10 + select MODULES_USE_ELF_RELA 10 11 11 12 config SYMBOL_PREFIX 12 13 string
+1
arch/h8300/include/asm/Kbuild
··· 2 2 3 3 generic-y += clkdev.h 4 4 generic-y += exec.h 5 + generic-y += module.h
-11
arch/h8300/include/asm/module.h
··· 1 - #ifndef _ASM_H8300_MODULE_H 2 - #define _ASM_H8300_MODULE_H 3 - /* 4 - * This file contains the H8/300 architecture specific module code. 5 - */ 6 - struct mod_arch_specific { }; 7 - #define Elf_Shdr Elf32_Shdr 8 - #define Elf_Sym Elf32_Sym 9 - #define Elf_Ehdr Elf32_Ehdr 10 - 11 - #endif /* _ASM_H8/300_MODULE_H */
+1
arch/hexagon/Kconfig
··· 30 30 select KTIME_SCALAR 31 31 select GENERIC_CLOCKEVENTS 32 32 select GENERIC_CLOCKEVENTS_BROADCAST 33 + select MODULES_USE_ELF_RELA 33 34 ---help--- 34 35 Qualcomm Hexagon is a processor architecture designed for high 35 36 performance and low power across a wide variety of applications.
+2
arch/ia64/Kconfig
··· 40 40 select ARCH_THREAD_INFO_ALLOCATOR 41 41 select ARCH_CLOCKSOURCE_DATA 42 42 select GENERIC_TIME_VSYSCALL_OLD 43 + select HAVE_MOD_ARCH_SPECIFIC 44 + select MODULES_USE_ELF_RELA 43 45 default y 44 46 help 45 47 The Itanium Processor Family is Intel's 64-bit successor to
+2 -4
arch/ia64/include/asm/module.h
··· 1 1 #ifndef _ASM_IA64_MODULE_H 2 2 #define _ASM_IA64_MODULE_H 3 3 4 + #include <asm-generic/module.h> 5 + 4 6 /* 5 7 * IA-64-specific support for kernel module loader. 6 8 * ··· 30 28 void *init_unw_table; /* init unwind-table cookie returned by unwinder */ 31 29 unsigned int next_got_entry; /* index of next available got entry */ 32 30 }; 33 - 34 - #define Elf_Shdr Elf64_Shdr 35 - #define Elf_Sym Elf64_Sym 36 - #define Elf_Ehdr Elf64_Ehdr 37 31 38 32 #define MODULE_PROC_FAMILY "ia64" 39 33 #define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY \
+1
arch/m32r/Kconfig
··· 14 14 select GENERIC_IRQ_SHOW 15 15 select GENERIC_ATOMIC64 16 16 select ARCH_USES_GETTIMEOFFSET 17 + select MODULES_USE_ELF_RELA 17 18 18 19 config SBUS 19 20 bool
+1
arch/m32r/include/asm/Kbuild
··· 2 2 3 3 generic-y += clkdev.h 4 4 generic-y += exec.h 5 + generic-y += module.h
-10
arch/m32r/include/asm/module.h
··· 1 - #ifndef _ASM_M32R_MODULE_H 2 - #define _ASM_M32R_MODULE_H 3 - 4 - struct mod_arch_specific { }; 5 - 6 - #define Elf_Shdr Elf32_Shdr 7 - #define Elf_Sym Elf32_Sym 8 - #define Elf_Ehdr Elf32_Ehdr 9 - 10 - #endif /* _ASM_M32R_MODULE_H */
-15
arch/m32r/kernel/module.c
··· 201 201 } 202 202 return 0; 203 203 } 204 - 205 - int apply_relocate(Elf32_Shdr *sechdrs, 206 - const char *strtab, 207 - unsigned int symindex, 208 - unsigned int relsec, 209 - struct module *me) 210 - { 211 - #if 0 212 - printk(KERN_ERR "module %s: REL RELOCATION unsupported\n", 213 - me->name); 214 - return -ENOEXEC; 215 - #endif 216 - return 0; 217 - 218 - }
+3
arch/m68k/Kconfig
··· 16 16 select ARCH_WANT_IPC_PARSE_VERSION 17 17 select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE 18 18 select GENERIC_KERNEL_THREAD 19 + select HAVE_MOD_ARCH_SPECIFIC 20 + select MODULES_USE_ELF_REL 21 + select MODULES_USE_ELF_RELA 19 22 20 23 config RWSEM_GENERIC_SPINLOCK 21 24 bool
+2 -4
arch/m68k/include/asm/module.h
··· 1 1 #ifndef _ASM_M68K_MODULE_H 2 2 #define _ASM_M68K_MODULE_H 3 3 4 + #include <asm-generic/module.h> 5 + 4 6 enum m68k_fixup_type { 5 7 m68k_fixup_memoffset, 6 8 m68k_fixup_vnode_shift, ··· 37 35 struct module; 38 36 extern void module_fixup(struct module *mod, struct m68k_fixup_info *start, 39 37 struct m68k_fixup_info *end); 40 - 41 - #define Elf_Shdr Elf32_Shdr 42 - #define Elf_Sym Elf32_Sym 43 - #define Elf_Ehdr Elf32_Ehdr 44 38 45 39 #endif /* _ASM_M68K_MODULE_H */
+1
arch/microblaze/Kconfig
··· 25 25 select GENERIC_CPU_DEVICES 26 26 select GENERIC_ATOMIC64 27 27 select GENERIC_CLOCKEVENTS 28 + select MODULES_USE_ELF_RELA 28 29 29 30 config SWAP 30 31 def_bool n
+3
arch/mips/Kconfig
··· 37 37 select BUILDTIME_EXTABLE_SORT 38 38 select GENERIC_CLOCKEVENTS 39 39 select GENERIC_CMOS_UPDATE 40 + select HAVE_MOD_ARCH_SPECIFIC 41 + select MODULES_USE_ELF_REL 42 + select MODULES_USE_ELF_RELA if 64BIT 40 43 41 44 menu "Machine selection" 42 45
+8 -2
arch/mips/include/asm/module.h
··· 35 35 } Elf64_Mips_Rela; 36 36 37 37 #ifdef CONFIG_32BIT 38 - 39 38 #define Elf_Shdr Elf32_Shdr 40 39 #define Elf_Sym Elf32_Sym 41 40 #define Elf_Ehdr Elf32_Ehdr 42 41 #define Elf_Addr Elf32_Addr 42 + #define Elf_Rel Elf32_Rel 43 + #define Elf_Rela Elf32_Rela 44 + #define ELF_R_TYPE(X) ELF32_R_TYPE(X) 45 + #define ELF_R_SYM(X) ELF32_R_SYM(X) 43 46 44 47 #define Elf_Mips_Rel Elf32_Rel 45 48 #define Elf_Mips_Rela Elf32_Rela ··· 53 50 #endif 54 51 55 52 #ifdef CONFIG_64BIT 56 - 57 53 #define Elf_Shdr Elf64_Shdr 58 54 #define Elf_Sym Elf64_Sym 59 55 #define Elf_Ehdr Elf64_Ehdr 60 56 #define Elf_Addr Elf64_Addr 57 + #define Elf_Rel Elf64_Rel 58 + #define Elf_Rela Elf64_Rela 59 + #define ELF_R_TYPE(X) ELF64_R_TYPE(X) 60 + #define ELF_R_SYM(X) ELF64_R_SYM(X) 61 61 62 62 #define Elf_Mips_Rel Elf64_Mips_Rel 63 63 #define Elf_Mips_Rela Elf64_Mips_Rela
+1
arch/mips/kernel/Makefile
··· 31 31 32 32 obj-$(CONFIG_STACKTRACE) += stacktrace.o 33 33 obj-$(CONFIG_MODULES) += mips_ksyms.o module.o 34 + obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o 34 35 35 36 obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o 36 37
+145
arch/mips/kernel/module-rela.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify 3 + * it under the terms of the GNU General Public License as published by 4 + * the Free Software Foundation; either version 2 of the License, or 5 + * (at your option) any later version. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + * 12 + * You should have received a copy of the GNU General Public License 13 + * along with this program; if not, write to the Free Software 14 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15 + * 16 + * Copyright (C) 2001 Rusty Russell. 17 + * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) 18 + * Copyright (C) 2005 Thiemo Seufer 19 + */ 20 + 21 + #include <linux/elf.h> 22 + #include <linux/err.h> 23 + #include <linux/errno.h> 24 + #include <linux/moduleloader.h> 25 + 26 + extern int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v); 27 + 28 + static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) 29 + { 30 + *location = v; 31 + 32 + return 0; 33 + } 34 + 35 + static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) 36 + { 37 + if (v % 4) { 38 + pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", 39 + me->name); 40 + return -ENOEXEC; 41 + } 42 + 43 + if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 44 + printk(KERN_ERR 45 + "module %s: relocation overflow\n", 46 + me->name); 47 + return -ENOEXEC; 48 + } 49 + 50 + *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); 51 + 52 + return 0; 53 + } 54 + 55 + static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) 56 + { 57 + *location = (*location & 0xffff0000) | 58 + ((((long long) v + 0x8000LL) >> 16) & 0xffff); 59 + 60 + return 0; 61 + } 62 + 63 + static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) 64 + { 65 + *location = (*location & 0xffff0000) | (v & 0xffff); 66 + 67 + return 0; 68 + } 69 + 70 + static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) 71 + { 72 + *(Elf_Addr *)location = v; 73 + 74 + return 0; 75 + } 76 + 77 + static int apply_r_mips_higher_rela(struct module *me, u32 *location, 78 + Elf_Addr v) 79 + { 80 + *location = (*location & 0xffff0000) | 81 + ((((long long) v + 0x80008000LL) >> 32) & 0xffff); 82 + 83 + return 0; 84 + } 85 + 86 + static int apply_r_mips_highest_rela(struct module *me, u32 *location, 87 + Elf_Addr v) 88 + { 89 + *location = (*location & 0xffff0000) | 90 + ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); 91 + 92 + return 0; 93 + } 94 + 95 + static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, 96 + Elf_Addr v) = { 97 + [R_MIPS_NONE] = apply_r_mips_none, 98 + [R_MIPS_32] = apply_r_mips_32_rela, 99 + [R_MIPS_26] = apply_r_mips_26_rela, 100 + [R_MIPS_HI16] = apply_r_mips_hi16_rela, 101 + [R_MIPS_LO16] = apply_r_mips_lo16_rela, 102 + [R_MIPS_64] = apply_r_mips_64_rela, 103 + [R_MIPS_HIGHER] = apply_r_mips_higher_rela, 104 + [R_MIPS_HIGHEST] = apply_r_mips_highest_rela 105 + }; 106 + 107 + int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, 108 + unsigned int symindex, unsigned int relsec, 109 + struct module *me) 110 + { 111 + Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; 112 + Elf_Sym *sym; 113 + u32 *location; 114 + unsigned int i; 115 + Elf_Addr v; 116 + int res; 117 + 118 + pr_debug("Applying relocate section %u to %u\n", relsec, 119 + sechdrs[relsec].sh_info); 120 + 121 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 122 + /* This is where to make the change */ 123 + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 124 + + rel[i].r_offset; 125 + /* This is the symbol it is referring to */ 126 + sym = (Elf_Sym *)sechdrs[symindex].sh_addr 127 + + ELF_MIPS_R_SYM(rel[i]); 128 + if (IS_ERR_VALUE(sym->st_value)) { 129 + /* Ignore unresolved weak symbol */ 130 + if (ELF_ST_BIND(sym->st_info) == STB_WEAK) 131 + continue; 132 + printk(KERN_WARNING "%s: Unknown symbol %s\n", 133 + me->name, strtab + sym->st_name); 134 + return -ENOENT; 135 + } 136 + 137 + v = sym->st_value + rel[i].r_addend; 138 + 139 + res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); 140 + if (res) 141 + return res; 142 + } 143 + 144 + return 0; 145 + }
+1 -120
arch/mips/kernel/module.c
··· 51 51 } 52 52 #endif 53 53 54 - static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) 54 + int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v) 55 55 { 56 56 return 0; 57 57 } ··· 59 59 static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v) 60 60 { 61 61 *location += v; 62 - 63 - return 0; 64 - } 65 - 66 - static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) 67 - { 68 - *location = v; 69 62 70 63 return 0; 71 64 } ··· 84 91 return 0; 85 92 } 86 93 87 - static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) 88 - { 89 - if (v % 4) { 90 - pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", 91 - me->name); 92 - return -ENOEXEC; 93 - } 94 - 95 - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 96 - printk(KERN_ERR 97 - "module %s: relocation overflow\n", 98 - me->name); 99 - return -ENOEXEC; 100 - } 101 - 102 - *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff); 103 - 104 - return 0; 105 - } 106 - 107 94 static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v) 108 95 { 109 96 struct mips_hi16 *n; ··· 101 128 n->value = v; 102 129 n->next = me->arch.r_mips_hi16_list; 103 130 me->arch.r_mips_hi16_list = n; 104 - 105 - return 0; 106 - } 107 - 108 - static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v) 109 - { 110 - *location = (*location & 0xffff0000) | 111 - ((((long long) v + 0x8000LL) >> 16) & 0xffff); 112 131 113 132 return 0; 114 133 } ··· 182 217 return -ENOEXEC; 183 218 } 184 219 185 - static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v) 186 - { 187 - *location = (*location & 0xffff0000) | (v & 0xffff); 188 - 189 - return 0; 190 - } 191 - 192 - static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v) 193 - { 194 - *(Elf_Addr *)location = v; 195 - 196 - return 0; 197 - } 198 - 199 - static int apply_r_mips_higher_rela(struct module *me, u32 *location, 200 - Elf_Addr v) 201 - { 202 - *location = (*location & 0xffff0000) | 203 - ((((long long) v + 0x80008000LL) >> 32) & 0xffff); 204 - 205 - return 0; 206 - } 207 - 208 - static int apply_r_mips_highest_rela(struct module *me, u32 *location, 209 - Elf_Addr v) 210 - { 211 - *location = (*location & 0xffff0000) | 212 - ((((long long) v + 0x800080008000LL) >> 48) & 0xffff); 213 - 214 - return 0; 215 - } 216 - 217 220 static int (*reloc_handlers_rel[]) (struct module *me, u32 *location, 218 221 Elf_Addr v) = { 219 222 [R_MIPS_NONE] = apply_r_mips_none, ··· 189 256 [R_MIPS_26] = apply_r_mips_26_rel, 190 257 [R_MIPS_HI16] = apply_r_mips_hi16_rel, 191 258 [R_MIPS_LO16] = apply_r_mips_lo16_rel 192 - }; 193 - 194 - static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, 195 - Elf_Addr v) = { 196 - [R_MIPS_NONE] = apply_r_mips_none, 197 - [R_MIPS_32] = apply_r_mips_32_rela, 198 - [R_MIPS_26] = apply_r_mips_26_rela, 199 - [R_MIPS_HI16] = apply_r_mips_hi16_rela, 200 - [R_MIPS_LO16] = apply_r_mips_lo16_rela, 201 - [R_MIPS_64] = apply_r_mips_64_rela, 202 - [R_MIPS_HIGHER] = apply_r_mips_higher_rela, 203 - [R_MIPS_HIGHEST] = apply_r_mips_highest_rela 204 259 }; 205 260 206 261 int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, ··· 240 319 me->arch.r_mips_hi16_list = NULL; 241 320 242 321 return -ENOEXEC; 243 - } 244 - 245 - return 0; 246 - } 247 - 248 - int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, 249 - unsigned int symindex, unsigned int relsec, 250 - struct module *me) 251 - { 252 - Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; 253 - Elf_Sym *sym; 254 - u32 *location; 255 - unsigned int i; 256 - Elf_Addr v; 257 - int res; 258 - 259 - pr_debug("Applying relocate section %u to %u\n", relsec, 260 - sechdrs[relsec].sh_info); 261 - 262 - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 263 - /* This is where to make the change */ 264 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 265 - + rel[i].r_offset; 266 - /* This is the symbol it is referring to */ 267 - sym = (Elf_Sym *)sechdrs[symindex].sh_addr 268 - + ELF_MIPS_R_SYM(rel[i]); 269 - if (IS_ERR_VALUE(sym->st_value)) { 270 - /* Ignore unresolved weak symbol */ 271 - if (ELF_ST_BIND(sym->st_info) == STB_WEAK) 272 - continue; 273 - printk(KERN_WARNING "%s: Unknown symbol %s\n", 274 - me->name, strtab + sym->st_name); 275 - return -ENOENT; 276 - } 277 - 278 - v = sym->st_value + rel[i].r_addend; 279 - 280 - res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); 281 - if (res) 282 - return res; 283 322 } 284 323 285 324 return 0;
+1
arch/mn10300/Kconfig
··· 9 9 select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER 10 10 select GENERIC_CLOCKEVENTS 11 11 select GENERIC_KERNEL_THREAD 12 + select MODULES_USE_ELF_RELA 12 13 13 14 config AM33_2 14 15 def_bool n
+1 -6
arch/mn10300/include/asm/module.h
··· 12 12 #ifndef _ASM_MODULE_H 13 13 #define _ASM_MODULE_H 14 14 15 - struct mod_arch_specific { 16 - }; 17 - 18 - #define Elf_Shdr Elf32_Shdr 19 - #define Elf_Sym Elf32_Sym 20 - #define Elf_Ehdr Elf32_Ehdr 15 + #include <asm-generic/module.h> 21 16 22 17 /* 23 18 * Include the MN10300 architecture version.
+1
arch/openrisc/Kconfig
··· 21 21 select GENERIC_CLOCKEVENTS 22 22 select GENERIC_STRNCPY_FROM_USER 23 23 select GENERIC_STRNLEN_USER 24 + select MODULES_USE_ELF_RELA 24 25 25 26 config MMU 26 27 def_bool y
+2
arch/parisc/Kconfig
··· 20 20 select ARCH_HAVE_NMI_SAFE_CMPXCHG 21 21 select GENERIC_SMP_IDLE_THREAD 22 22 select GENERIC_STRNCPY_FROM_USER 23 + select HAVE_MOD_ARCH_SPECIFIC 24 + select MODULES_USE_ELF_RELA 23 25 24 26 help 25 27 The PA-RISC microprocessor is designed by Hewlett-Packard and used
+3 -13
arch/parisc/include/asm/module.h
··· 1 1 #ifndef _ASM_PARISC_MODULE_H 2 2 #define _ASM_PARISC_MODULE_H 3 + 4 + #include <asm-generic/module.h> 5 + 3 6 /* 4 7 * This file contains the parisc architecture specific module code. 5 8 */ 6 - #ifdef CONFIG_64BIT 7 - #define Elf_Shdr Elf64_Shdr 8 - #define Elf_Sym Elf64_Sym 9 - #define Elf_Ehdr Elf64_Ehdr 10 - #define Elf_Addr Elf64_Addr 11 - #define Elf_Rela Elf64_Rela 12 - #else 13 - #define Elf_Shdr Elf32_Shdr 14 - #define Elf_Sym Elf32_Sym 15 - #define Elf_Ehdr Elf32_Ehdr 16 - #define Elf_Addr Elf32_Addr 17 - #define Elf_Rela Elf32_Rela 18 - #endif 19 9 20 10 struct unwind_table; 21 11
+2
arch/powerpc/Kconfig
··· 142 142 select GENERIC_STRNCPY_FROM_USER 143 143 select GENERIC_STRNLEN_USER 144 144 select GENERIC_KERNEL_THREAD 145 + select HAVE_MOD_ARCH_SPECIFIC 146 + select MODULES_USE_ELF_RELA 145 147 146 148 config EARLY_PRINTK 147 149 bool
+1 -6
arch/powerpc/include/asm/module.h
··· 11 11 12 12 #include <linux/list.h> 13 13 #include <asm/bug.h> 14 + #include <asm-generic/module.h> 14 15 15 16 16 17 #ifndef __powerpc64__ ··· 61 60 */ 62 61 63 62 #ifdef __powerpc64__ 64 - # define Elf_Shdr Elf64_Shdr 65 - # define Elf_Sym Elf64_Sym 66 - # define Elf_Ehdr Elf64_Ehdr 67 63 # ifdef MODULE 68 64 asm(".section .stubs,\"ax\",@nobits; .align 3; .previous"); 69 65 # endif 70 66 #else 71 - # define Elf_Shdr Elf32_Shdr 72 - # define Elf_Sym Elf32_Sym 73 - # define Elf_Ehdr Elf32_Ehdr 74 67 # ifdef MODULE 75 68 asm(".section .plt,\"ax\",@nobits; .align 3; .previous"); 76 69 asm(".section .init.plt,\"ax\",@nobits; .align 3; .previous");
+2
arch/s390/Kconfig
··· 136 136 select KTIME_SCALAR if 32BIT 137 137 select HAVE_ARCH_SECCOMP_FILTER 138 138 select GENERIC_KERNEL_THREAD 139 + select HAVE_MOD_ARCH_SPECIFIC 140 + select MODULES_USE_ELF_RELA 139 141 140 142 config SCHED_OMIT_FRAME_POINTER 141 143 def_bool y
+3 -15
arch/s390/include/asm/module.h
··· 1 1 #ifndef _ASM_S390_MODULE_H 2 2 #define _ASM_S390_MODULE_H 3 + 4 + #include <asm-generic/module.h> 5 + 3 6 /* 4 7 * This file contains the s390 architecture specific module code. 5 8 */ ··· 31 28 struct mod_arch_syminfo *syminfo; 32 29 }; 33 30 34 - #ifdef CONFIG_64BIT 35 - #define ElfW(x) Elf64_ ## x 36 - #define ELFW(x) ELF64_ ## x 37 - #else 38 - #define ElfW(x) Elf32_ ## x 39 - #define ELFW(x) ELF32_ ## x 40 - #endif 41 - 42 - #define Elf_Addr ElfW(Addr) 43 - #define Elf_Rela ElfW(Rela) 44 - #define Elf_Shdr ElfW(Shdr) 45 - #define Elf_Sym ElfW(Sym) 46 - #define Elf_Ehdr ElfW(Ehdr) 47 - #define ELF_R_SYM ELFW(R_SYM) 48 - #define ELF_R_TYPE ELFW(R_TYPE) 49 31 #endif /* _ASM_S390_MODULE_H */
+2
arch/score/Kconfig
··· 11 11 select ARCH_DISCARD_MEMBLOCK 12 12 select GENERIC_CPU_DEVICES 13 13 select GENERIC_CLOCKEVENTS 14 + select HAVE_MOD_ARCH_SPECIFIC 15 + select MODULES_USE_ELF_REL 14 16 15 17 choice 16 18 prompt "System type"
+1 -5
arch/score/include/asm/module.h
··· 3 3 4 4 #include <linux/list.h> 5 5 #include <asm/uaccess.h> 6 + #include <asm-generic/module.h> 6 7 7 8 struct mod_arch_specific { 8 9 /* Data Bus Error exception tables */ ··· 13 12 }; 14 13 15 14 typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ 16 - 17 - #define Elf_Shdr Elf32_Shdr 18 - #define Elf_Sym Elf32_Sym 19 - #define Elf_Ehdr Elf32_Ehdr 20 - #define Elf_Addr Elf32_Addr 21 15 22 16 /* Given an address, look for it in the exception tables. */ 23 17 #ifdef CONFIG_MODULES
-10
arch/score/kernel/module.c
··· 125 125 return 0; 126 126 } 127 127 128 - int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, 129 - unsigned int symindex, unsigned int relsec, 130 - struct module *me) 131 - { 132 - /* Non-standard return value... most other arch's return -ENOEXEC 133 - * for an unsupported relocation variant 134 - */ 135 - return 0; 136 - } 137 - 138 128 /* Given an address, look for it in the module exception tables. */ 139 129 const struct exception_table_entry *search_module_dbetables(unsigned long addr) 140 130 {
+2
arch/sh/Kconfig
··· 38 38 select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST 39 39 select GENERIC_STRNCPY_FROM_USER 40 40 select GENERIC_STRNLEN_USER 41 + select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER 42 + select MODULES_USE_ELF_RELA 41 43 help 42 44 The SuperH is a RISC processor targeted for use in embedded systems 43 45 and consumer electronics; it was also used in the Sega Dreamcast
+3 -11
arch/sh/include/asm/module.h
··· 1 1 #ifndef _ASM_SH_MODULE_H 2 2 #define _ASM_SH_MODULE_H 3 3 4 - struct mod_arch_specific { 4 + #include <asm-generic/module.h> 5 + 5 6 #ifdef CONFIG_DWARF_UNWINDER 7 + struct mod_arch_specific { 6 8 struct list_head fde_list; 7 9 struct list_head cie_list; 8 - #endif 9 10 }; 10 - 11 - #ifdef CONFIG_64BIT 12 - #define Elf_Shdr Elf64_Shdr 13 - #define Elf_Sym Elf64_Sym 14 - #define Elf_Ehdr Elf64_Ehdr 15 - #else 16 - #define Elf_Shdr Elf32_Shdr 17 - #define Elf_Sym Elf32_Sym 18 - #define Elf_Ehdr Elf32_Ehdr 19 11 #endif 20 12 21 13 #ifdef CONFIG_CPU_LITTLE_ENDIAN
+1
arch/sparc/Kconfig
··· 39 39 select GENERIC_CLOCKEVENTS 40 40 select GENERIC_STRNCPY_FROM_USER 41 41 select GENERIC_STRNLEN_USER 42 + select MODULES_USE_ELF_RELA 42 43 43 44 config SPARC32 44 45 def_bool !64BIT
+1
arch/sparc/include/asm/Kbuild
··· 7 7 generic-y += local64.h 8 8 generic-y += irq_regs.h 9 9 generic-y += local.h 10 + generic-y += module.h 10 11 generic-y += word-at-a-time.h
-24
arch/sparc/include/asm/module.h
··· 1 - #ifndef __SPARC_MODULE_H 2 - #define __SPARC_MODULE_H 3 - struct mod_arch_specific { }; 4 - 5 - /* 6 - * Use some preprocessor magic to define the correct symbol 7 - * for sparc32 and sparc64. 8 - * Elf_Addr becomes Elf32_Addr for sparc32 and Elf64_Addr for sparc64 9 - */ 10 - #define ___ELF(a, b, c) a##b##c 11 - #define __ELF(a, b, c) ___ELF(a, b, c) 12 - #define _Elf(t) __ELF(Elf, CONFIG_BITS, t) 13 - #define _ELF(t) __ELF(ELF, CONFIG_BITS, t) 14 - 15 - #define Elf_Shdr _Elf(_Shdr) 16 - #define Elf_Sym _Elf(_Sym) 17 - #define Elf_Ehdr _Elf(_Ehdr) 18 - #define Elf_Rela _Elf(_Rela) 19 - #define Elf_Addr _Elf(_Addr) 20 - 21 - #define ELF_R_SYM _ELF(_R_SYM) 22 - #define ELF_R_TYPE _ELF(_R_TYPE) 23 - 24 - #endif /* __SPARC_MODULE_H */
+1
arch/tile/Kconfig
··· 20 20 select SYS_HYPERVISOR 21 21 select ARCH_HAVE_NMI_SAFE_CMPXCHG 22 22 select GENERIC_CLOCKEVENTS 23 + select MODULES_USE_ELF_RELA 23 24 24 25 # FIXME: investigate whether we need/want these options. 25 26 # select HAVE_IOREMAP_PROT
+1
arch/unicore32/Kconfig
··· 15 15 select GENERIC_IRQ_SHOW 16 16 select ARCH_WANT_FRAME_POINTERS 17 17 select GENERIC_IOMAP 18 + select MODULES_USE_ELF_REL 18 19 help 19 20 UniCore-32 is 32-bit Instruction Set Architecture, 20 21 including a series of low-power-consumption RISC chip
+2
arch/x86/Kconfig
··· 110 110 select HAVE_IRQ_TIME_ACCOUNTING 111 111 select GENERIC_KERNEL_THREAD 112 112 select GENERIC_KERNEL_EXECVE 113 + select MODULES_USE_ELF_REL if X86_32 114 + select MODULES_USE_ELF_RELA if X86_64 113 115 114 116 config INSTRUCTION_DECODER 115 117 def_bool y
+2
arch/x86/um/Kconfig
··· 24 24 def_bool !64BIT 25 25 select HAVE_AOUT 26 26 select ARCH_WANT_IPC_PARSE_VERSION 27 + select MODULES_USE_ELF_REL 27 28 28 29 config X86_64 29 30 def_bool 64BIT 31 + select MODULES_USE_ELF_RELA 30 32 31 33 config RWSEM_XCHGADD_ALGORITHM 32 34 def_bool X86_XADD && 64BIT
+1 -8
arch/xtensa/include/asm/module.h
··· 13 13 #ifndef _XTENSA_MODULE_H 14 14 #define _XTENSA_MODULE_H 15 15 16 - struct mod_arch_specific 17 - { 18 - /* No special elements, yet. */ 19 - }; 20 - 21 16 #define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " " 22 17 23 - #define Elf_Shdr Elf32_Shdr 24 - #define Elf_Sym Elf32_Sym 25 - #define Elf_Ehdr Elf32_Ehdr 18 + #include <asm-generic/module.h> 26 19 27 20 #endif /* _XTENSA_MODULE_H */
+1
crypto/Kconfig
··· 1216 1216 key cipher algorithms. 1217 1217 1218 1218 source "drivers/crypto/Kconfig" 1219 + source crypto/asymmetric_keys/Kconfig 1219 1220 1220 1221 endif # if CRYPTO
+1
crypto/Makefile
··· 97 97 # 98 98 obj-$(CONFIG_XOR_BLOCKS) += xor.o 99 99 obj-$(CONFIG_ASYNC_CORE) += async_tx/ 100 + obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
+1
crypto/asymmetric_keys/.gitignore
··· 1 + *-asn1.[ch]
+38
crypto/asymmetric_keys/Kconfig
··· 1 + menuconfig ASYMMETRIC_KEY_TYPE 2 + tristate "Asymmetric (public-key cryptographic) key type" 3 + depends on KEYS 4 + help 5 + This option provides support for a key type that holds the data for 6 + the asymmetric keys used for public key cryptographic operations such 7 + as encryption, decryption, signature generation and signature 8 + verification. 9 + 10 + if ASYMMETRIC_KEY_TYPE 11 + 12 + config ASYMMETRIC_PUBLIC_KEY_SUBTYPE 13 + tristate "Asymmetric public-key crypto algorithm subtype" 14 + select MPILIB 15 + help 16 + This option provides support for asymmetric public key type handling. 17 + If signature generation and/or verification are to be used, 18 + appropriate hash algorithms (such as SHA-1) must be available. 19 + ENOPKG will be reported if the requisite algorithm is unavailable. 20 + 21 + config PUBLIC_KEY_ALGO_RSA 22 + tristate "RSA public-key algorithm" 23 + depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE 24 + select MPILIB_EXTRA 25 + help 26 + This option enables support for the RSA algorithm (PKCS#1, RFC3447). 27 + 28 + config X509_CERTIFICATE_PARSER 29 + tristate "X.509 certificate parser" 30 + depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE 31 + select ASN1 32 + select OID_REGISTRY 33 + help 34 + This option procides support for parsing X.509 format blobs for key 35 + data and provides the ability to instantiate a crypto key from a 36 + public key packet found inside the certificate. 37 + 38 + endif # ASYMMETRIC_KEY_TYPE
+27
crypto/asymmetric_keys/Makefile
··· 1 + # 2 + # Makefile for asymmetric cryptographic keys 3 + # 4 + 5 + obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys.o 6 + 7 + asymmetric_keys-y := asymmetric_type.o signature.o 8 + 9 + obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o 10 + obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o 11 + 12 + # 13 + # X.509 Certificate handling 14 + # 15 + obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o 16 + x509_key_parser-y := \ 17 + x509-asn1.o \ 18 + x509_rsakey-asn1.o \ 19 + x509_cert_parser.o \ 20 + x509_public_key.o 21 + 22 + $(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h 23 + $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h 24 + $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h 25 + 26 + clean-files += x509-asn1.c x509-asn1.h 27 + clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
+15
crypto/asymmetric_keys/asymmetric_keys.h
··· 1 + /* Internal definitions for asymmetric key type 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 + static inline const char *asymmetric_key_id(const struct key *key) 13 + { 14 + return key->type_data.p[1]; 15 + }
+274
crypto/asymmetric_keys/asymmetric_type.c
··· 1 + /* Asymmetric public-key cryptography key type 2 + * 3 + * See Documentation/security/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 + #include <keys/asymmetric-subtype.h> 14 + #include <keys/asymmetric-parser.h> 15 + #include <linux/seq_file.h> 16 + #include <linux/module.h> 17 + #include <linux/slab.h> 18 + #include "asymmetric_keys.h" 19 + 20 + MODULE_LICENSE("GPL"); 21 + 22 + static LIST_HEAD(asymmetric_key_parsers); 23 + static DECLARE_RWSEM(asymmetric_key_parsers_sem); 24 + 25 + /* 26 + * Match asymmetric keys on (part of) their name 27 + * We have some shorthand methods for matching keys. We allow: 28 + * 29 + * "<desc>" - request a key by description 30 + * "id:<id>" - request a key matching the ID 31 + * "<subtype>:<id>" - request a key of a subtype 32 + */ 33 + static int asymmetric_key_match(const struct key *key, const void *description) 34 + { 35 + const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 36 + const char *spec = description; 37 + const char *id, *kid; 38 + ptrdiff_t speclen; 39 + size_t idlen, kidlen; 40 + 41 + if (!subtype || !spec || !*spec) 42 + return 0; 43 + 44 + /* See if the full key description matches as is */ 45 + if (key->description && strcmp(key->description, description) == 0) 46 + return 1; 47 + 48 + /* All tests from here on break the criterion description into a 49 + * specifier, a colon and then an identifier. 50 + */ 51 + id = strchr(spec, ':'); 52 + if (!id) 53 + return 0; 54 + 55 + speclen = id - spec; 56 + id++; 57 + 58 + /* Anything after here requires a partial match on the ID string */ 59 + kid = asymmetric_key_id(key); 60 + if (!kid) 61 + return 0; 62 + 63 + idlen = strlen(id); 64 + kidlen = strlen(kid); 65 + if (idlen > kidlen) 66 + return 0; 67 + 68 + kid += kidlen - idlen; 69 + if (strcasecmp(id, kid) != 0) 70 + return 0; 71 + 72 + if (speclen == 2 && 73 + memcmp(spec, "id", 2) == 0) 74 + return 1; 75 + 76 + if (speclen == subtype->name_len && 77 + memcmp(spec, subtype->name, speclen) == 0) 78 + return 1; 79 + 80 + return 0; 81 + } 82 + 83 + /* 84 + * Describe the asymmetric key 85 + */ 86 + static void asymmetric_key_describe(const struct key *key, struct seq_file *m) 87 + { 88 + const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 89 + const char *kid = asymmetric_key_id(key); 90 + size_t n; 91 + 92 + seq_puts(m, key->description); 93 + 94 + if (subtype) { 95 + seq_puts(m, ": "); 96 + subtype->describe(key, m); 97 + 98 + if (kid) { 99 + seq_putc(m, ' '); 100 + n = strlen(kid); 101 + if (n <= 8) 102 + seq_puts(m, kid); 103 + else 104 + seq_puts(m, kid + n - 8); 105 + } 106 + 107 + seq_puts(m, " ["); 108 + /* put something here to indicate the key's capabilities */ 109 + seq_putc(m, ']'); 110 + } 111 + } 112 + 113 + /* 114 + * Preparse a asymmetric payload to get format the contents appropriately for the 115 + * internal payload to cut down on the number of scans of the data performed. 116 + * 117 + * We also generate a proposed description from the contents of the key that 118 + * can be used to name the key if the user doesn't want to provide one. 119 + */ 120 + static int asymmetric_key_preparse(struct key_preparsed_payload *prep) 121 + { 122 + struct asymmetric_key_parser *parser; 123 + int ret; 124 + 125 + pr_devel("==>%s()\n", __func__); 126 + 127 + if (prep->datalen == 0) 128 + return -EINVAL; 129 + 130 + down_read(&asymmetric_key_parsers_sem); 131 + 132 + ret = -EBADMSG; 133 + list_for_each_entry(parser, &asymmetric_key_parsers, link) { 134 + pr_debug("Trying parser '%s'\n", parser->name); 135 + 136 + ret = parser->parse(prep); 137 + if (ret != -EBADMSG) { 138 + pr_debug("Parser recognised the format (ret %d)\n", 139 + ret); 140 + break; 141 + } 142 + } 143 + 144 + up_read(&asymmetric_key_parsers_sem); 145 + pr_devel("<==%s() = %d\n", __func__, ret); 146 + return ret; 147 + } 148 + 149 + /* 150 + * Clean up the preparse data 151 + */ 152 + static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) 153 + { 154 + struct asymmetric_key_subtype *subtype = prep->type_data[0]; 155 + 156 + pr_devel("==>%s()\n", __func__); 157 + 158 + if (subtype) { 159 + subtype->destroy(prep->payload); 160 + module_put(subtype->owner); 161 + } 162 + kfree(prep->type_data[1]); 163 + kfree(prep->description); 164 + } 165 + 166 + /* 167 + * Instantiate a asymmetric_key defined key. The key was preparsed, so we just 168 + * have to transfer the data here. 169 + */ 170 + static int asymmetric_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 171 + { 172 + int ret; 173 + 174 + pr_devel("==>%s()\n", __func__); 175 + 176 + ret = key_payload_reserve(key, prep->quotalen); 177 + if (ret == 0) { 178 + key->type_data.p[0] = prep->type_data[0]; 179 + key->type_data.p[1] = prep->type_data[1]; 180 + key->payload.data = prep->payload; 181 + prep->type_data[0] = NULL; 182 + prep->type_data[1] = NULL; 183 + prep->payload = NULL; 184 + } 185 + pr_devel("<==%s() = %d\n", __func__, ret); 186 + return ret; 187 + } 188 + 189 + /* 190 + * dispose of the data dangling from the corpse of a asymmetric key 191 + */ 192 + static void asymmetric_key_destroy(struct key *key) 193 + { 194 + struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 195 + if (subtype) { 196 + subtype->destroy(key->payload.data); 197 + module_put(subtype->owner); 198 + key->type_data.p[0] = NULL; 199 + } 200 + kfree(key->type_data.p[1]); 201 + key->type_data.p[1] = NULL; 202 + } 203 + 204 + struct key_type key_type_asymmetric = { 205 + .name = "asymmetric", 206 + .preparse = asymmetric_key_preparse, 207 + .free_preparse = asymmetric_key_free_preparse, 208 + .instantiate = asymmetric_key_instantiate, 209 + .match = asymmetric_key_match, 210 + .destroy = asymmetric_key_destroy, 211 + .describe = asymmetric_key_describe, 212 + }; 213 + EXPORT_SYMBOL_GPL(key_type_asymmetric); 214 + 215 + /** 216 + * register_asymmetric_key_parser - Register a asymmetric key blob parser 217 + * @parser: The parser to register 218 + */ 219 + int register_asymmetric_key_parser(struct asymmetric_key_parser *parser) 220 + { 221 + struct asymmetric_key_parser *cursor; 222 + int ret; 223 + 224 + down_write(&asymmetric_key_parsers_sem); 225 + 226 + list_for_each_entry(cursor, &asymmetric_key_parsers, link) { 227 + if (strcmp(cursor->name, parser->name) == 0) { 228 + pr_err("Asymmetric key parser '%s' already registered\n", 229 + parser->name); 230 + ret = -EEXIST; 231 + goto out; 232 + } 233 + } 234 + 235 + list_add_tail(&parser->link, &asymmetric_key_parsers); 236 + 237 + pr_notice("Asymmetric key parser '%s' registered\n", parser->name); 238 + ret = 0; 239 + 240 + out: 241 + up_write(&asymmetric_key_parsers_sem); 242 + return ret; 243 + } 244 + EXPORT_SYMBOL_GPL(register_asymmetric_key_parser); 245 + 246 + /** 247 + * unregister_asymmetric_key_parser - Unregister a asymmetric key blob parser 248 + * @parser: The parser to unregister 249 + */ 250 + void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser) 251 + { 252 + down_write(&asymmetric_key_parsers_sem); 253 + list_del(&parser->link); 254 + up_write(&asymmetric_key_parsers_sem); 255 + 256 + pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name); 257 + } 258 + EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser); 259 + 260 + /* 261 + * Module stuff 262 + */ 263 + static int __init asymmetric_key_init(void) 264 + { 265 + return register_key_type(&key_type_asymmetric); 266 + } 267 + 268 + static void __exit asymmetric_key_cleanup(void) 269 + { 270 + unregister_key_type(&key_type_asymmetric); 271 + } 272 + 273 + module_init(asymmetric_key_init); 274 + module_exit(asymmetric_key_cleanup);
+108
crypto/asymmetric_keys/public_key.c
··· 1 + /* In-software asymmetric public-key crypto subtype 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 + #define pr_fmt(fmt) "PKEY: "fmt 15 + #include <linux/module.h> 16 + #include <linux/export.h> 17 + #include <linux/kernel.h> 18 + #include <linux/slab.h> 19 + #include <linux/seq_file.h> 20 + #include <keys/asymmetric-subtype.h> 21 + #include "public_key.h" 22 + 23 + MODULE_LICENSE("GPL"); 24 + 25 + const char *const pkey_algo[PKEY_ALGO__LAST] = { 26 + [PKEY_ALGO_DSA] = "DSA", 27 + [PKEY_ALGO_RSA] = "RSA", 28 + }; 29 + EXPORT_SYMBOL_GPL(pkey_algo); 30 + 31 + const char *const pkey_hash_algo[PKEY_HASH__LAST] = { 32 + [PKEY_HASH_MD4] = "md4", 33 + [PKEY_HASH_MD5] = "md5", 34 + [PKEY_HASH_SHA1] = "sha1", 35 + [PKEY_HASH_RIPE_MD_160] = "rmd160", 36 + [PKEY_HASH_SHA256] = "sha256", 37 + [PKEY_HASH_SHA384] = "sha384", 38 + [PKEY_HASH_SHA512] = "sha512", 39 + [PKEY_HASH_SHA224] = "sha224", 40 + }; 41 + EXPORT_SYMBOL_GPL(pkey_hash_algo); 42 + 43 + const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = { 44 + [PKEY_ID_PGP] = "PGP", 45 + [PKEY_ID_X509] = "X509", 46 + }; 47 + EXPORT_SYMBOL_GPL(pkey_id_type); 48 + 49 + /* 50 + * Provide a part of a description of the key for /proc/keys. 51 + */ 52 + static void public_key_describe(const struct key *asymmetric_key, 53 + struct seq_file *m) 54 + { 55 + struct public_key *key = asymmetric_key->payload.data; 56 + 57 + if (key) 58 + seq_printf(m, "%s.%s", 59 + pkey_id_type[key->id_type], key->algo->name); 60 + } 61 + 62 + /* 63 + * Destroy a public key algorithm key. 64 + */ 65 + void public_key_destroy(void *payload) 66 + { 67 + struct public_key *key = payload; 68 + int i; 69 + 70 + if (key) { 71 + for (i = 0; i < ARRAY_SIZE(key->mpi); i++) 72 + mpi_free(key->mpi[i]); 73 + kfree(key); 74 + } 75 + } 76 + EXPORT_SYMBOL_GPL(public_key_destroy); 77 + 78 + /* 79 + * Verify a signature using a public key. 80 + */ 81 + static int public_key_verify_signature(const struct key *key, 82 + const struct public_key_signature *sig) 83 + { 84 + const struct public_key *pk = key->payload.data; 85 + 86 + if (!pk->algo->verify_signature) 87 + return -ENOTSUPP; 88 + 89 + if (sig->nr_mpi != pk->algo->n_sig_mpi) { 90 + pr_debug("Signature has %u MPI not %u\n", 91 + sig->nr_mpi, pk->algo->n_sig_mpi); 92 + return -EINVAL; 93 + } 94 + 95 + return pk->algo->verify_signature(pk, sig); 96 + } 97 + 98 + /* 99 + * Public key algorithm asymmetric key subtype 100 + */ 101 + struct asymmetric_key_subtype public_key_subtype = { 102 + .owner = THIS_MODULE, 103 + .name = "public_key", 104 + .describe = public_key_describe, 105 + .destroy = public_key_destroy, 106 + .verify_signature = public_key_verify_signature, 107 + }; 108 + EXPORT_SYMBOL_GPL(public_key_subtype);
+30
crypto/asymmetric_keys/public_key.h
··· 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;
+277
crypto/asymmetric_keys/rsa.c
··· 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 "public_key.h" 17 + 18 + MODULE_LICENSE("GPL"); 19 + MODULE_DESCRIPTION("RSA Public Key Algorithm"); 20 + 21 + #define kenter(FMT, ...) \ 22 + pr_devel("==> %s("FMT")\n", __func__, ##__VA_ARGS__) 23 + #define kleave(FMT, ...) \ 24 + pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__) 25 + 26 + /* 27 + * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2]. 28 + */ 29 + static const u8 RSA_digest_info_MD5[] = { 30 + 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 31 + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* OID */ 32 + 0x05, 0x00, 0x04, 0x10 33 + }; 34 + 35 + static const u8 RSA_digest_info_SHA1[] = { 36 + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 37 + 0x2B, 0x0E, 0x03, 0x02, 0x1A, 38 + 0x05, 0x00, 0x04, 0x14 39 + }; 40 + 41 + static const u8 RSA_digest_info_RIPE_MD_160[] = { 42 + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 43 + 0x2B, 0x24, 0x03, 0x02, 0x01, 44 + 0x05, 0x00, 0x04, 0x14 45 + }; 46 + 47 + static const u8 RSA_digest_info_SHA224[] = { 48 + 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 49 + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 50 + 0x05, 0x00, 0x04, 0x1C 51 + }; 52 + 53 + static const u8 RSA_digest_info_SHA256[] = { 54 + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 55 + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 56 + 0x05, 0x00, 0x04, 0x20 57 + }; 58 + 59 + static const u8 RSA_digest_info_SHA384[] = { 60 + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 61 + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 62 + 0x05, 0x00, 0x04, 0x30 63 + }; 64 + 65 + static const u8 RSA_digest_info_SHA512[] = { 66 + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 67 + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 68 + 0x05, 0x00, 0x04, 0x40 69 + }; 70 + 71 + static const struct { 72 + const u8 *data; 73 + size_t size; 74 + } RSA_ASN1_templates[PKEY_HASH__LAST] = { 75 + #define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) } 76 + [PKEY_HASH_MD5] = _(MD5), 77 + [PKEY_HASH_SHA1] = _(SHA1), 78 + [PKEY_HASH_RIPE_MD_160] = _(RIPE_MD_160), 79 + [PKEY_HASH_SHA256] = _(SHA256), 80 + [PKEY_HASH_SHA384] = _(SHA384), 81 + [PKEY_HASH_SHA512] = _(SHA512), 82 + [PKEY_HASH_SHA224] = _(SHA224), 83 + #undef _ 84 + }; 85 + 86 + /* 87 + * RSAVP1() function [RFC3447 sec 5.2.2] 88 + */ 89 + static int RSAVP1(const struct public_key *key, MPI s, MPI *_m) 90 + { 91 + MPI m; 92 + int ret; 93 + 94 + /* (1) Validate 0 <= s < n */ 95 + if (mpi_cmp_ui(s, 0) < 0) { 96 + kleave(" = -EBADMSG [s < 0]"); 97 + return -EBADMSG; 98 + } 99 + if (mpi_cmp(s, key->rsa.n) >= 0) { 100 + kleave(" = -EBADMSG [s >= n]"); 101 + return -EBADMSG; 102 + } 103 + 104 + m = mpi_alloc(0); 105 + if (!m) 106 + return -ENOMEM; 107 + 108 + /* (2) m = s^e mod n */ 109 + ret = mpi_powm(m, s, key->rsa.e, key->rsa.n); 110 + if (ret < 0) { 111 + mpi_free(m); 112 + return ret; 113 + } 114 + 115 + *_m = m; 116 + return 0; 117 + } 118 + 119 + /* 120 + * Integer to Octet String conversion [RFC3447 sec 4.1] 121 + */ 122 + static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X) 123 + { 124 + unsigned X_size, x_size; 125 + int X_sign; 126 + u8 *X; 127 + 128 + /* Make sure the string is the right length. The number should begin 129 + * with { 0x00, 0x01, ... } so we have to account for 15 leading zero 130 + * bits not being reported by MPI. 131 + */ 132 + x_size = mpi_get_nbits(x); 133 + pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8); 134 + if (x_size != xLen * 8 - 15) 135 + return -ERANGE; 136 + 137 + X = mpi_get_buffer(x, &X_size, &X_sign); 138 + if (!X) 139 + return -ENOMEM; 140 + if (X_sign < 0) { 141 + kfree(X); 142 + return -EBADMSG; 143 + } 144 + if (X_size != xLen - 1) { 145 + kfree(X); 146 + return -EBADMSG; 147 + } 148 + 149 + *_X = X; 150 + return 0; 151 + } 152 + 153 + /* 154 + * Perform the RSA signature verification. 155 + * @H: Value of hash of data and metadata 156 + * @EM: The computed signature value 157 + * @k: The size of EM (EM[0] is an invalid location but should hold 0x00) 158 + * @hash_size: The size of H 159 + * @asn1_template: The DigestInfo ASN.1 template 160 + * @asn1_size: Size of asm1_template[] 161 + */ 162 + static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size, 163 + const u8 *asn1_template, size_t asn1_size) 164 + { 165 + unsigned PS_end, T_offset, i; 166 + 167 + kenter(",,%zu,%zu,%zu", k, hash_size, asn1_size); 168 + 169 + if (k < 2 + 1 + asn1_size + hash_size) 170 + return -EBADMSG; 171 + 172 + /* Decode the EMSA-PKCS1-v1_5 */ 173 + if (EM[1] != 0x01) { 174 + kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]); 175 + return -EBADMSG; 176 + } 177 + 178 + T_offset = k - (asn1_size + hash_size); 179 + PS_end = T_offset - 1; 180 + if (EM[PS_end] != 0x00) { 181 + kleave(" = -EBADMSG [EM[T-1] == %02u]", EM[PS_end]); 182 + return -EBADMSG; 183 + } 184 + 185 + for (i = 2; i < PS_end; i++) { 186 + if (EM[i] != 0xff) { 187 + kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]); 188 + return -EBADMSG; 189 + } 190 + } 191 + 192 + if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) { 193 + kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]"); 194 + return -EBADMSG; 195 + } 196 + 197 + if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) { 198 + kleave(" = -EKEYREJECTED [EM[T] hash mismatch]"); 199 + return -EKEYREJECTED; 200 + } 201 + 202 + kleave(" = 0"); 203 + return 0; 204 + } 205 + 206 + /* 207 + * Perform the verification step [RFC3447 sec 8.2.2]. 208 + */ 209 + static int RSA_verify_signature(const struct public_key *key, 210 + const struct public_key_signature *sig) 211 + { 212 + size_t tsize; 213 + int ret; 214 + 215 + /* Variables as per RFC3447 sec 8.2.2 */ 216 + const u8 *H = sig->digest; 217 + u8 *EM = NULL; 218 + MPI m = NULL; 219 + size_t k; 220 + 221 + kenter(""); 222 + 223 + if (!RSA_ASN1_templates[sig->pkey_hash_algo].data) 224 + return -ENOTSUPP; 225 + 226 + /* (1) Check the signature size against the public key modulus size */ 227 + k = mpi_get_nbits(key->rsa.n); 228 + tsize = mpi_get_nbits(sig->rsa.s); 229 + 230 + /* According to RFC 4880 sec 3.2, length of MPI is computed starting 231 + * from most significant bit. So the RFC 3447 sec 8.2.2 size check 232 + * must be relaxed to conform with shorter signatures - so we fail here 233 + * only if signature length is longer than modulus size. 234 + */ 235 + pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize); 236 + if (k < tsize) { 237 + ret = -EBADMSG; 238 + goto error; 239 + } 240 + 241 + /* Round up and convert to octets */ 242 + k = (k + 7) / 8; 243 + 244 + /* (2b) Apply the RSAVP1 verification primitive to the public key */ 245 + ret = RSAVP1(key, sig->rsa.s, &m); 246 + if (ret < 0) 247 + goto error; 248 + 249 + /* (2c) Convert the message representative (m) to an encoded message 250 + * (EM) of length k octets. 251 + * 252 + * NOTE! The leading zero byte is suppressed by MPI, so we pass a 253 + * pointer to the _preceding_ byte to RSA_verify()! 254 + */ 255 + ret = RSA_I2OSP(m, k, &EM); 256 + if (ret < 0) 257 + goto error; 258 + 259 + ret = RSA_verify(H, EM - 1, k, sig->digest_size, 260 + RSA_ASN1_templates[sig->pkey_hash_algo].data, 261 + RSA_ASN1_templates[sig->pkey_hash_algo].size); 262 + 263 + error: 264 + kfree(EM); 265 + mpi_free(m); 266 + kleave(" = %d", ret); 267 + return ret; 268 + } 269 + 270 + const struct public_key_algorithm RSA_public_key_algorithm = { 271 + .name = "RSA", 272 + .n_pub_mpi = 2, 273 + .n_sec_mpi = 3, 274 + .n_sig_mpi = 1, 275 + .verify_signature = RSA_verify_signature, 276 + }; 277 + EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
+49
crypto/asymmetric_keys/signature.c
··· 1 + /* Signature verification with an asymmetric key 2 + * 3 + * See Documentation/security/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 <keys/asymmetric-subtype.h> 15 + #include <linux/module.h> 16 + #include <linux/err.h> 17 + #include <crypto/public_key.h> 18 + #include "asymmetric_keys.h" 19 + 20 + /** 21 + * verify_signature - Initiate the use of an asymmetric key to verify a signature 22 + * @key: The asymmetric key to verify against 23 + * @sig: The signature to check 24 + * 25 + * Returns 0 if successful or else an error. 26 + */ 27 + int verify_signature(const struct key *key, 28 + const struct public_key_signature *sig) 29 + { 30 + const struct asymmetric_key_subtype *subtype; 31 + int ret; 32 + 33 + pr_devel("==>%s()\n", __func__); 34 + 35 + if (key->type != &key_type_asymmetric) 36 + return -EINVAL; 37 + subtype = asymmetric_key_subtype(key); 38 + if (!subtype || 39 + !key->payload.data) 40 + return -EINVAL; 41 + if (!subtype->verify_signature) 42 + return -ENOTSUPP; 43 + 44 + ret = subtype->verify_signature(key, sig); 45 + 46 + pr_devel("<==%s() = %d\n", __func__, ret); 47 + return ret; 48 + } 49 + EXPORT_SYMBOL_GPL(verify_signature);
+60
crypto/asymmetric_keys/x509.asn1
··· 1 + Certificate ::= SEQUENCE { 2 + tbsCertificate TBSCertificate ({ x509_note_tbs_certificate }), 3 + signatureAlgorithm AlgorithmIdentifier, 4 + signature BIT STRING ({ x509_note_signature }) 5 + } 6 + 7 + TBSCertificate ::= SEQUENCE { 8 + version [ 0 ] Version DEFAULT, 9 + serialNumber CertificateSerialNumber, 10 + signature AlgorithmIdentifier ({ x509_note_pkey_algo }), 11 + issuer Name ({ x509_note_issuer }), 12 + validity Validity, 13 + subject Name ({ x509_note_subject }), 14 + subjectPublicKeyInfo SubjectPublicKeyInfo, 15 + issuerUniqueID [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL, 16 + subjectUniqueID [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL, 17 + extensions [ 3 ] Extensions OPTIONAL 18 + } 19 + 20 + Version ::= INTEGER 21 + CertificateSerialNumber ::= INTEGER 22 + 23 + AlgorithmIdentifier ::= SEQUENCE { 24 + algorithm OBJECT IDENTIFIER ({ x509_note_OID }), 25 + parameters ANY OPTIONAL 26 + } 27 + 28 + Name ::= SEQUENCE OF RelativeDistinguishedName 29 + 30 + RelativeDistinguishedName ::= SET OF AttributeValueAssertion 31 + 32 + AttributeValueAssertion ::= SEQUENCE { 33 + attributeType OBJECT IDENTIFIER ({ x509_note_OID }), 34 + attributeValue ANY ({ x509_extract_name_segment }) 35 + } 36 + 37 + Validity ::= SEQUENCE { 38 + notBefore Time ({ x509_note_not_before }), 39 + notAfter Time ({ x509_note_not_after }) 40 + } 41 + 42 + Time ::= CHOICE { 43 + utcTime UTCTime, 44 + generalTime GeneralizedTime 45 + } 46 + 47 + SubjectPublicKeyInfo ::= SEQUENCE { 48 + algorithm AlgorithmIdentifier, 49 + subjectPublicKey BIT STRING ({ x509_extract_key_data }) 50 + } 51 + 52 + UniqueIdentifier ::= BIT STRING 53 + 54 + Extensions ::= SEQUENCE OF Extension 55 + 56 + Extension ::= SEQUENCE { 57 + extnid OBJECT IDENTIFIER ({ x509_note_OID }), 58 + critical BOOLEAN DEFAULT, 59 + extnValue OCTET STRING ({ x509_process_extension }) 60 + }
+496
crypto/asymmetric_keys/x509_cert_parser.c
··· 1 + /* X.509 certificate parser 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) "X.509: "fmt 13 + #include <linux/kernel.h> 14 + #include <linux/slab.h> 15 + #include <linux/err.h> 16 + #include <linux/oid_registry.h> 17 + #include "public_key.h" 18 + #include "x509_parser.h" 19 + #include "x509-asn1.h" 20 + #include "x509_rsakey-asn1.h" 21 + 22 + struct x509_parse_context { 23 + struct x509_certificate *cert; /* Certificate being constructed */ 24 + unsigned long data; /* Start of data */ 25 + const void *cert_start; /* Start of cert content */ 26 + const void *key; /* Key data */ 27 + size_t key_size; /* Size of key data */ 28 + enum OID last_oid; /* Last OID encountered */ 29 + enum OID algo_oid; /* Algorithm OID */ 30 + unsigned char nr_mpi; /* Number of MPIs stored */ 31 + u8 o_size; /* Size of organizationName (O) */ 32 + u8 cn_size; /* Size of commonName (CN) */ 33 + u8 email_size; /* Size of emailAddress */ 34 + u16 o_offset; /* Offset of organizationName (O) */ 35 + u16 cn_offset; /* Offset of commonName (CN) */ 36 + u16 email_offset; /* Offset of emailAddress */ 37 + }; 38 + 39 + /* 40 + * Free an X.509 certificate 41 + */ 42 + void x509_free_certificate(struct x509_certificate *cert) 43 + { 44 + if (cert) { 45 + public_key_destroy(cert->pub); 46 + kfree(cert->issuer); 47 + kfree(cert->subject); 48 + kfree(cert->fingerprint); 49 + kfree(cert->authority); 50 + kfree(cert); 51 + } 52 + } 53 + 54 + /* 55 + * Parse an X.509 certificate 56 + */ 57 + struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) 58 + { 59 + struct x509_certificate *cert; 60 + struct x509_parse_context *ctx; 61 + long ret; 62 + 63 + ret = -ENOMEM; 64 + cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL); 65 + if (!cert) 66 + goto error_no_cert; 67 + cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL); 68 + if (!cert->pub) 69 + goto error_no_ctx; 70 + ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL); 71 + if (!ctx) 72 + goto error_no_ctx; 73 + 74 + ctx->cert = cert; 75 + ctx->data = (unsigned long)data; 76 + 77 + /* Attempt to decode the certificate */ 78 + ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen); 79 + if (ret < 0) 80 + goto error_decode; 81 + 82 + /* Decode the public key */ 83 + ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx, 84 + ctx->key, ctx->key_size); 85 + if (ret < 0) 86 + goto error_decode; 87 + 88 + kfree(ctx); 89 + return cert; 90 + 91 + error_decode: 92 + kfree(ctx); 93 + error_no_ctx: 94 + x509_free_certificate(cert); 95 + error_no_cert: 96 + return ERR_PTR(ret); 97 + } 98 + 99 + /* 100 + * Note an OID when we find one for later processing when we know how 101 + * to interpret it. 102 + */ 103 + int x509_note_OID(void *context, size_t hdrlen, 104 + unsigned char tag, 105 + const void *value, size_t vlen) 106 + { 107 + struct x509_parse_context *ctx = context; 108 + 109 + ctx->last_oid = look_up_OID(value, vlen); 110 + if (ctx->last_oid == OID__NR) { 111 + char buffer[50]; 112 + sprint_oid(value, vlen, buffer, sizeof(buffer)); 113 + pr_debug("Unknown OID: [%lu] %s\n", 114 + (unsigned long)value - ctx->data, buffer); 115 + } 116 + return 0; 117 + } 118 + 119 + /* 120 + * Save the position of the TBS data so that we can check the signature over it 121 + * later. 122 + */ 123 + int x509_note_tbs_certificate(void *context, size_t hdrlen, 124 + unsigned char tag, 125 + const void *value, size_t vlen) 126 + { 127 + struct x509_parse_context *ctx = context; 128 + 129 + pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n", 130 + hdrlen, tag, (unsigned long)value - ctx->data, vlen); 131 + 132 + ctx->cert->tbs = value - hdrlen; 133 + ctx->cert->tbs_size = vlen + hdrlen; 134 + return 0; 135 + } 136 + 137 + /* 138 + * Record the public key algorithm 139 + */ 140 + int x509_note_pkey_algo(void *context, size_t hdrlen, 141 + unsigned char tag, 142 + const void *value, size_t vlen) 143 + { 144 + struct x509_parse_context *ctx = context; 145 + 146 + pr_debug("PubKey Algo: %u\n", ctx->last_oid); 147 + 148 + switch (ctx->last_oid) { 149 + case OID_md2WithRSAEncryption: 150 + case OID_md3WithRSAEncryption: 151 + default: 152 + return -ENOPKG; /* Unsupported combination */ 153 + 154 + case OID_md4WithRSAEncryption: 155 + ctx->cert->sig_hash_algo = PKEY_HASH_MD5; 156 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 157 + break; 158 + 159 + case OID_sha1WithRSAEncryption: 160 + ctx->cert->sig_hash_algo = PKEY_HASH_SHA1; 161 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 162 + break; 163 + 164 + case OID_sha256WithRSAEncryption: 165 + ctx->cert->sig_hash_algo = PKEY_HASH_SHA256; 166 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 167 + break; 168 + 169 + case OID_sha384WithRSAEncryption: 170 + ctx->cert->sig_hash_algo = PKEY_HASH_SHA384; 171 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 172 + break; 173 + 174 + case OID_sha512WithRSAEncryption: 175 + ctx->cert->sig_hash_algo = PKEY_HASH_SHA512; 176 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 177 + break; 178 + 179 + case OID_sha224WithRSAEncryption: 180 + ctx->cert->sig_hash_algo = PKEY_HASH_SHA224; 181 + ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA; 182 + break; 183 + } 184 + 185 + ctx->algo_oid = ctx->last_oid; 186 + return 0; 187 + } 188 + 189 + /* 190 + * Note the whereabouts and type of the signature. 191 + */ 192 + int x509_note_signature(void *context, size_t hdrlen, 193 + unsigned char tag, 194 + const void *value, size_t vlen) 195 + { 196 + struct x509_parse_context *ctx = context; 197 + 198 + pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen); 199 + 200 + if (ctx->last_oid != ctx->algo_oid) { 201 + pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n", 202 + ctx->algo_oid, ctx->last_oid); 203 + return -EINVAL; 204 + } 205 + 206 + ctx->cert->sig = value; 207 + ctx->cert->sig_size = vlen; 208 + return 0; 209 + } 210 + 211 + /* 212 + * Note some of the name segments from which we'll fabricate a name. 213 + */ 214 + int x509_extract_name_segment(void *context, size_t hdrlen, 215 + unsigned char tag, 216 + const void *value, size_t vlen) 217 + { 218 + struct x509_parse_context *ctx = context; 219 + 220 + switch (ctx->last_oid) { 221 + case OID_commonName: 222 + ctx->cn_size = vlen; 223 + ctx->cn_offset = (unsigned long)value - ctx->data; 224 + break; 225 + case OID_organizationName: 226 + ctx->o_size = vlen; 227 + ctx->o_offset = (unsigned long)value - ctx->data; 228 + break; 229 + case OID_email_address: 230 + ctx->email_size = vlen; 231 + ctx->email_offset = (unsigned long)value - ctx->data; 232 + break; 233 + default: 234 + break; 235 + } 236 + 237 + return 0; 238 + } 239 + 240 + /* 241 + * Fabricate and save the issuer and subject names 242 + */ 243 + static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen, 244 + unsigned char tag, 245 + char **_name, size_t vlen) 246 + { 247 + const void *name, *data = (const void *)ctx->data; 248 + size_t namesize; 249 + char *buffer; 250 + 251 + if (*_name) 252 + return -EINVAL; 253 + 254 + /* Empty name string if no material */ 255 + if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) { 256 + buffer = kmalloc(1, GFP_KERNEL); 257 + if (!buffer) 258 + return -ENOMEM; 259 + buffer[0] = 0; 260 + goto done; 261 + } 262 + 263 + if (ctx->cn_size && ctx->o_size) { 264 + /* Consider combining O and CN, but use only the CN if it is 265 + * prefixed by the O, or a significant portion thereof. 266 + */ 267 + namesize = ctx->cn_size; 268 + name = data + ctx->cn_offset; 269 + if (ctx->cn_size >= ctx->o_size && 270 + memcmp(data + ctx->cn_offset, data + ctx->o_offset, 271 + ctx->o_size) == 0) 272 + goto single_component; 273 + if (ctx->cn_size >= 7 && 274 + ctx->o_size >= 7 && 275 + memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0) 276 + goto single_component; 277 + 278 + buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1, 279 + GFP_KERNEL); 280 + if (!buffer) 281 + return -ENOMEM; 282 + 283 + memcpy(buffer, 284 + data + ctx->o_offset, ctx->o_size); 285 + buffer[ctx->o_size + 0] = ':'; 286 + buffer[ctx->o_size + 1] = ' '; 287 + memcpy(buffer + ctx->o_size + 2, 288 + data + ctx->cn_offset, ctx->cn_size); 289 + buffer[ctx->o_size + 2 + ctx->cn_size] = 0; 290 + goto done; 291 + 292 + } else if (ctx->cn_size) { 293 + namesize = ctx->cn_size; 294 + name = data + ctx->cn_offset; 295 + } else if (ctx->o_size) { 296 + namesize = ctx->o_size; 297 + name = data + ctx->o_offset; 298 + } else { 299 + namesize = ctx->email_size; 300 + name = data + ctx->email_offset; 301 + } 302 + 303 + single_component: 304 + buffer = kmalloc(namesize + 1, GFP_KERNEL); 305 + if (!buffer) 306 + return -ENOMEM; 307 + memcpy(buffer, name, namesize); 308 + buffer[namesize] = 0; 309 + 310 + done: 311 + *_name = buffer; 312 + ctx->cn_size = 0; 313 + ctx->o_size = 0; 314 + ctx->email_size = 0; 315 + return 0; 316 + } 317 + 318 + int x509_note_issuer(void *context, size_t hdrlen, 319 + unsigned char tag, 320 + const void *value, size_t vlen) 321 + { 322 + struct x509_parse_context *ctx = context; 323 + return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen); 324 + } 325 + 326 + int x509_note_subject(void *context, size_t hdrlen, 327 + unsigned char tag, 328 + const void *value, size_t vlen) 329 + { 330 + struct x509_parse_context *ctx = context; 331 + return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen); 332 + } 333 + 334 + /* 335 + * Extract the data for the public key algorithm 336 + */ 337 + int x509_extract_key_data(void *context, size_t hdrlen, 338 + unsigned char tag, 339 + const void *value, size_t vlen) 340 + { 341 + struct x509_parse_context *ctx = context; 342 + 343 + if (ctx->last_oid != OID_rsaEncryption) 344 + return -ENOPKG; 345 + 346 + /* There seems to be an extraneous 0 byte on the front of the data */ 347 + ctx->cert->pkey_algo = PKEY_ALGO_RSA; 348 + ctx->key = value + 1; 349 + ctx->key_size = vlen - 1; 350 + return 0; 351 + } 352 + 353 + /* 354 + * Extract a RSA public key value 355 + */ 356 + int rsa_extract_mpi(void *context, size_t hdrlen, 357 + unsigned char tag, 358 + const void *value, size_t vlen) 359 + { 360 + struct x509_parse_context *ctx = context; 361 + MPI mpi; 362 + 363 + if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) { 364 + pr_err("Too many public key MPIs in certificate\n"); 365 + return -EBADMSG; 366 + } 367 + 368 + mpi = mpi_read_raw_data(value, vlen); 369 + if (!mpi) 370 + return -ENOMEM; 371 + 372 + ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi; 373 + return 0; 374 + } 375 + 376 + /* 377 + * Process certificate extensions that are used to qualify the certificate. 378 + */ 379 + int x509_process_extension(void *context, size_t hdrlen, 380 + unsigned char tag, 381 + const void *value, size_t vlen) 382 + { 383 + struct x509_parse_context *ctx = context; 384 + const unsigned char *v = value; 385 + char *f; 386 + int i; 387 + 388 + pr_debug("Extension: %u\n", ctx->last_oid); 389 + 390 + if (ctx->last_oid == OID_subjectKeyIdentifier) { 391 + /* Get hold of the key fingerprint */ 392 + if (vlen < 3) 393 + return -EBADMSG; 394 + if (v[0] != ASN1_OTS || v[1] != vlen - 2) 395 + return -EBADMSG; 396 + v += 2; 397 + vlen -= 2; 398 + 399 + f = kmalloc(vlen * 2 + 1, GFP_KERNEL); 400 + if (!f) 401 + return -ENOMEM; 402 + for (i = 0; i < vlen; i++) 403 + sprintf(f + i * 2, "%02x", v[i]); 404 + pr_debug("fingerprint %s\n", f); 405 + ctx->cert->fingerprint = f; 406 + return 0; 407 + } 408 + 409 + if (ctx->last_oid == OID_authorityKeyIdentifier) { 410 + /* Get hold of the CA key fingerprint */ 411 + if (vlen < 5) 412 + return -EBADMSG; 413 + if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) || 414 + v[1] != vlen - 2 || 415 + v[2] != (ASN1_CONT << 6) || 416 + v[3] != vlen - 4) 417 + return -EBADMSG; 418 + v += 4; 419 + vlen -= 4; 420 + 421 + f = kmalloc(vlen * 2 + 1, GFP_KERNEL); 422 + if (!f) 423 + return -ENOMEM; 424 + for (i = 0; i < vlen; i++) 425 + sprintf(f + i * 2, "%02x", v[i]); 426 + pr_debug("authority %s\n", f); 427 + ctx->cert->authority = f; 428 + return 0; 429 + } 430 + 431 + return 0; 432 + } 433 + 434 + /* 435 + * Record a certificate time. 436 + */ 437 + static int x509_note_time(struct tm *tm, size_t hdrlen, 438 + unsigned char tag, 439 + const unsigned char *value, size_t vlen) 440 + { 441 + const unsigned char *p = value; 442 + 443 + #define dec2bin(X) ((X) - '0') 444 + #define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; }) 445 + 446 + if (tag == ASN1_UNITIM) { 447 + /* UTCTime: YYMMDDHHMMSSZ */ 448 + if (vlen != 13) 449 + goto unsupported_time; 450 + tm->tm_year = DD2bin(p); 451 + if (tm->tm_year >= 50) 452 + tm->tm_year += 1900; 453 + else 454 + tm->tm_year += 2000; 455 + } else if (tag == ASN1_GENTIM) { 456 + /* GenTime: YYYYMMDDHHMMSSZ */ 457 + if (vlen != 15) 458 + goto unsupported_time; 459 + tm->tm_year = DD2bin(p) * 100 + DD2bin(p); 460 + } else { 461 + goto unsupported_time; 462 + } 463 + 464 + tm->tm_year -= 1900; 465 + tm->tm_mon = DD2bin(p) - 1; 466 + tm->tm_mday = DD2bin(p); 467 + tm->tm_hour = DD2bin(p); 468 + tm->tm_min = DD2bin(p); 469 + tm->tm_sec = DD2bin(p); 470 + 471 + if (*p != 'Z') 472 + goto unsupported_time; 473 + 474 + return 0; 475 + 476 + unsupported_time: 477 + pr_debug("Got unsupported time [tag %02x]: '%*.*s'\n", 478 + tag, (int)vlen, (int)vlen, value); 479 + return -EBADMSG; 480 + } 481 + 482 + int x509_note_not_before(void *context, size_t hdrlen, 483 + unsigned char tag, 484 + const void *value, size_t vlen) 485 + { 486 + struct x509_parse_context *ctx = context; 487 + return x509_note_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen); 488 + } 489 + 490 + int x509_note_not_after(void *context, size_t hdrlen, 491 + unsigned char tag, 492 + const void *value, size_t vlen) 493 + { 494 + struct x509_parse_context *ctx = context; 495 + return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen); 496 + }
+36
crypto/asymmetric_keys/x509_parser.h
··· 1 + /* X.509 certificate parser internal definitions 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 + #include <crypto/public_key.h> 13 + 14 + struct x509_certificate { 15 + struct x509_certificate *next; 16 + struct public_key *pub; /* Public key details */ 17 + char *issuer; /* Name of certificate issuer */ 18 + char *subject; /* Name of certificate subject */ 19 + char *fingerprint; /* Key fingerprint as hex */ 20 + char *authority; /* Authority key fingerprint as hex */ 21 + struct tm valid_from; 22 + struct tm valid_to; 23 + enum pkey_algo pkey_algo : 8; /* Public key algorithm */ 24 + enum pkey_algo sig_pkey_algo : 8; /* Signature public key algorithm */ 25 + enum pkey_hash_algo sig_hash_algo : 8; /* Signature hash algorithm */ 26 + const void *tbs; /* Signed data */ 27 + size_t tbs_size; /* Size of signed data */ 28 + const void *sig; /* Signature data */ 29 + size_t sig_size; /* Size of sigature */ 30 + }; 31 + 32 + /* 33 + * x509_cert_parser.c 34 + */ 35 + extern void x509_free_certificate(struct x509_certificate *cert); 36 + extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
+239
crypto/asymmetric_keys/x509_public_key.c
··· 1 + /* Instantiate a public key crypto key from an X.509 Certificate 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) "X.509: "fmt 13 + #include <linux/module.h> 14 + #include <linux/kernel.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> 20 + #include <keys/asymmetric-parser.h> 21 + #include <crypto/hash.h> 22 + #include "asymmetric_keys.h" 23 + #include "public_key.h" 24 + #include "x509_parser.h" 25 + 26 + static const 27 + struct public_key_algorithm *x509_public_key_algorithms[PKEY_ALGO__LAST] = { 28 + [PKEY_ALGO_DSA] = NULL, 29 + #if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \ 30 + defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE) 31 + [PKEY_ALGO_RSA] = &RSA_public_key_algorithm, 32 + #endif 33 + }; 34 + 35 + /* 36 + * Check the signature on a certificate using the provided public key 37 + */ 38 + static int x509_check_signature(const struct public_key *pub, 39 + const struct x509_certificate *cert) 40 + { 41 + struct public_key_signature *sig; 42 + struct crypto_shash *tfm; 43 + struct shash_desc *desc; 44 + size_t digest_size, desc_size; 45 + int ret; 46 + 47 + pr_devel("==>%s()\n", __func__); 48 + 49 + /* Allocate the hashing algorithm we're going to need and find out how 50 + * big the hash operational data will be. 51 + */ 52 + tfm = crypto_alloc_shash(pkey_hash_algo[cert->sig_hash_algo], 0, 0); 53 + if (IS_ERR(tfm)) 54 + return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 55 + 56 + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 57 + digest_size = crypto_shash_digestsize(tfm); 58 + 59 + /* We allocate the hash operational data storage on the end of our 60 + * context data. 61 + */ 62 + ret = -ENOMEM; 63 + sig = kzalloc(sizeof(*sig) + desc_size + digest_size, GFP_KERNEL); 64 + if (!sig) 65 + goto error_no_sig; 66 + 67 + sig->pkey_hash_algo = cert->sig_hash_algo; 68 + sig->digest = (u8 *)sig + sizeof(*sig) + desc_size; 69 + sig->digest_size = digest_size; 70 + 71 + desc = (void *)sig + sizeof(*sig); 72 + desc->tfm = tfm; 73 + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 74 + 75 + ret = crypto_shash_init(desc); 76 + if (ret < 0) 77 + goto error; 78 + 79 + ret = -ENOMEM; 80 + sig->rsa.s = mpi_read_raw_data(cert->sig, cert->sig_size); 81 + if (!sig->rsa.s) 82 + goto error; 83 + 84 + ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest); 85 + if (ret < 0) 86 + goto error_mpi; 87 + 88 + ret = pub->algo->verify_signature(pub, sig); 89 + 90 + pr_debug("Cert Verification: %d\n", ret); 91 + 92 + error_mpi: 93 + mpi_free(sig->rsa.s); 94 + error: 95 + kfree(sig); 96 + error_no_sig: 97 + crypto_free_shash(tfm); 98 + 99 + pr_devel("<==%s() = %d\n", __func__, ret); 100 + return ret; 101 + } 102 + 103 + /* 104 + * Attempt to parse a data blob for a key as an X509 certificate. 105 + */ 106 + static int x509_key_preparse(struct key_preparsed_payload *prep) 107 + { 108 + struct x509_certificate *cert; 109 + struct tm now; 110 + size_t srlen, sulen; 111 + char *desc = NULL; 112 + int ret; 113 + 114 + cert = x509_cert_parse(prep->data, prep->datalen); 115 + if (IS_ERR(cert)) 116 + return PTR_ERR(cert); 117 + 118 + pr_devel("Cert Issuer: %s\n", cert->issuer); 119 + pr_devel("Cert Subject: %s\n", cert->subject); 120 + pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]); 121 + pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n", 122 + cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1, 123 + cert->valid_from.tm_mday, cert->valid_from.tm_hour, 124 + cert->valid_from.tm_min, cert->valid_from.tm_sec); 125 + pr_devel("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n", 126 + cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1, 127 + cert->valid_to.tm_mday, cert->valid_to.tm_hour, 128 + cert->valid_to.tm_min, cert->valid_to.tm_sec); 129 + pr_devel("Cert Signature: %s + %s\n", 130 + pkey_algo[cert->sig_pkey_algo], 131 + pkey_hash_algo[cert->sig_hash_algo]); 132 + 133 + if (!cert->fingerprint || !cert->authority) { 134 + pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n", 135 + cert->subject); 136 + ret = -EKEYREJECTED; 137 + goto error_free_cert; 138 + } 139 + 140 + time_to_tm(CURRENT_TIME.tv_sec, 0, &now); 141 + pr_devel("Now: %04ld-%02d-%02d %02d:%02d:%02d\n", 142 + now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, 143 + now.tm_hour, now.tm_min, now.tm_sec); 144 + if (now.tm_year < cert->valid_from.tm_year || 145 + (now.tm_year == cert->valid_from.tm_year && 146 + (now.tm_mon < cert->valid_from.tm_mon || 147 + (now.tm_mon == cert->valid_from.tm_mon && 148 + (now.tm_mday < cert->valid_from.tm_mday || 149 + (now.tm_mday == cert->valid_from.tm_mday && 150 + (now.tm_hour < cert->valid_from.tm_hour || 151 + (now.tm_hour == cert->valid_from.tm_hour && 152 + (now.tm_min < cert->valid_from.tm_min || 153 + (now.tm_min == cert->valid_from.tm_min && 154 + (now.tm_sec < cert->valid_from.tm_sec 155 + ))))))))))) { 156 + pr_warn("Cert %s is not yet valid\n", cert->fingerprint); 157 + ret = -EKEYREJECTED; 158 + goto error_free_cert; 159 + } 160 + if (now.tm_year > cert->valid_to.tm_year || 161 + (now.tm_year == cert->valid_to.tm_year && 162 + (now.tm_mon > cert->valid_to.tm_mon || 163 + (now.tm_mon == cert->valid_to.tm_mon && 164 + (now.tm_mday > cert->valid_to.tm_mday || 165 + (now.tm_mday == cert->valid_to.tm_mday && 166 + (now.tm_hour > cert->valid_to.tm_hour || 167 + (now.tm_hour == cert->valid_to.tm_hour && 168 + (now.tm_min > cert->valid_to.tm_min || 169 + (now.tm_min == cert->valid_to.tm_min && 170 + (now.tm_sec > cert->valid_to.tm_sec 171 + ))))))))))) { 172 + pr_warn("Cert %s has expired\n", cert->fingerprint); 173 + ret = -EKEYEXPIRED; 174 + goto error_free_cert; 175 + } 176 + 177 + cert->pub->algo = x509_public_key_algorithms[cert->pkey_algo]; 178 + cert->pub->id_type = PKEY_ID_X509; 179 + 180 + /* Check the signature on the key */ 181 + if (strcmp(cert->fingerprint, cert->authority) == 0) { 182 + ret = x509_check_signature(cert->pub, cert); 183 + if (ret < 0) 184 + goto error_free_cert; 185 + } 186 + 187 + /* Propose a description */ 188 + sulen = strlen(cert->subject); 189 + srlen = strlen(cert->fingerprint); 190 + ret = -ENOMEM; 191 + desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL); 192 + if (!desc) 193 + goto error_free_cert; 194 + memcpy(desc, cert->subject, sulen); 195 + desc[sulen] = ':'; 196 + desc[sulen + 1] = ' '; 197 + memcpy(desc + sulen + 2, cert->fingerprint, srlen); 198 + desc[sulen + 2 + srlen] = 0; 199 + 200 + /* We're pinning the module by being linked against it */ 201 + __module_get(public_key_subtype.owner); 202 + prep->type_data[0] = &public_key_subtype; 203 + prep->type_data[1] = cert->fingerprint; 204 + prep->payload = cert->pub; 205 + prep->description = desc; 206 + prep->quotalen = 100; 207 + 208 + /* We've finished with the certificate */ 209 + cert->pub = NULL; 210 + cert->fingerprint = NULL; 211 + desc = NULL; 212 + ret = 0; 213 + 214 + error_free_cert: 215 + x509_free_certificate(cert); 216 + return ret; 217 + } 218 + 219 + static struct asymmetric_key_parser x509_key_parser = { 220 + .owner = THIS_MODULE, 221 + .name = "x509", 222 + .parse = x509_key_preparse, 223 + }; 224 + 225 + /* 226 + * Module stuff 227 + */ 228 + static int __init x509_key_init(void) 229 + { 230 + return register_asymmetric_key_parser(&x509_key_parser); 231 + } 232 + 233 + static void __exit x509_key_exit(void) 234 + { 235 + unregister_asymmetric_key_parser(&x509_key_parser); 236 + } 237 + 238 + module_init(x509_key_init); 239 + module_exit(x509_key_exit);
+4
crypto/asymmetric_keys/x509_rsakey.asn1
··· 1 + RSAPublicKey ::= SEQUENCE { 2 + modulus INTEGER ({ rsa_extract_mpi }), -- n 3 + publicExponent INTEGER ({ rsa_extract_mpi }) -- e 4 + }
+3 -3
fs/cifs/cifs_spnego.c
··· 31 31 32 32 /* create a new cifs key */ 33 33 static int 34 - cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) 34 + cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 35 35 { 36 36 char *payload; 37 37 int ret; 38 38 39 39 ret = -ENOMEM; 40 - payload = kmalloc(datalen, GFP_KERNEL); 40 + payload = kmalloc(prep->datalen, GFP_KERNEL); 41 41 if (!payload) 42 42 goto error; 43 43 44 44 /* attach the data */ 45 - memcpy(payload, data, datalen); 45 + memcpy(payload, prep->data, prep->datalen); 46 46 key->payload.data = payload; 47 47 ret = 0; 48 48
+4 -4
fs/cifs/cifsacl.c
··· 167 167 }; 168 168 169 169 static int 170 - cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen) 170 + cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 171 171 { 172 172 char *payload; 173 173 174 - payload = kmalloc(datalen, GFP_KERNEL); 174 + payload = kmalloc(prep->datalen, GFP_KERNEL); 175 175 if (!payload) 176 176 return -ENOMEM; 177 177 178 - memcpy(payload, data, datalen); 178 + memcpy(payload, prep->data, prep->datalen); 179 179 key->payload.data = payload; 180 - key->datalen = datalen; 180 + key->datalen = prep->datalen; 181 181 return 0; 182 182 } 183 183
+57
include/asm-generic/bitops/count_zeros.h
··· 1 + /* Count leading and trailing zeros functions 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 + #ifndef _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ 13 + #define _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ 14 + 15 + #include <asm/bitops.h> 16 + 17 + /** 18 + * count_leading_zeros - Count the number of zeros from the MSB back 19 + * @x: The value 20 + * 21 + * Count the number of leading zeros from the MSB going towards the LSB in @x. 22 + * 23 + * If the MSB of @x is set, the result is 0. 24 + * If only the LSB of @x is set, then the result is BITS_PER_LONG-1. 25 + * If @x is 0 then the result is COUNT_LEADING_ZEROS_0. 26 + */ 27 + static inline int count_leading_zeros(unsigned long x) 28 + { 29 + if (sizeof(x) == 4) 30 + return BITS_PER_LONG - fls(x); 31 + else 32 + return BITS_PER_LONG - fls64(x); 33 + } 34 + 35 + #define COUNT_LEADING_ZEROS_0 BITS_PER_LONG 36 + 37 + /** 38 + * count_trailing_zeros - Count the number of zeros from the LSB forwards 39 + * @x: The value 40 + * 41 + * Count the number of trailing zeros from the LSB going towards the MSB in @x. 42 + * 43 + * If the LSB of @x is set, the result is 0. 44 + * If only the MSB of @x is set, then the result is BITS_PER_LONG-1. 45 + * If @x is 0 then the result is COUNT_TRAILING_ZEROS_0. 46 + */ 47 + static inline int count_trailing_zeros(unsigned long x) 48 + { 49 + #define COUNT_TRAILING_ZEROS_0 (-1) 50 + 51 + if (sizeof(x) == 4) 52 + return ffs(x); 53 + else 54 + return (x != 0) ? __ffs(x) : COUNT_TRAILING_ZEROS_0; 55 + } 56 + 57 + #endif /* _ASM_GENERIC_BITOPS_COUNT_ZEROS_H_ */
+33 -7
include/asm-generic/module.h
··· 5 5 * Many architectures just need a simple module 6 6 * loader without arch specific data. 7 7 */ 8 + #ifndef CONFIG_HAVE_MOD_ARCH_SPECIFIC 8 9 struct mod_arch_specific 9 10 { 10 11 }; 12 + #endif 11 13 12 14 #ifdef CONFIG_64BIT 13 - #define Elf_Shdr Elf64_Shdr 14 - #define Elf_Sym Elf64_Sym 15 - #define Elf_Ehdr Elf64_Ehdr 16 - #else 17 - #define Elf_Shdr Elf32_Shdr 18 - #define Elf_Sym Elf32_Sym 19 - #define Elf_Ehdr Elf32_Ehdr 15 + #define Elf_Shdr Elf64_Shdr 16 + #define Elf_Phdr Elf64_Phdr 17 + #define Elf_Sym Elf64_Sym 18 + #define Elf_Dyn Elf64_Dyn 19 + #define Elf_Ehdr Elf64_Ehdr 20 + #define Elf_Addr Elf64_Addr 21 + #ifdef CONFIG_MODULES_USE_ELF_REL 22 + #define Elf_Rel Elf64_Rel 23 + #endif 24 + #ifdef CONFIG_MODULES_USE_ELF_RELA 25 + #define Elf_Rela Elf64_Rela 26 + #endif 27 + #define ELF_R_TYPE(X) ELF64_R_TYPE(X) 28 + #define ELF_R_SYM(X) ELF64_R_SYM(X) 29 + 30 + #else /* CONFIG_64BIT */ 31 + 32 + #define Elf_Shdr Elf32_Shdr 33 + #define Elf_Phdr Elf32_Phdr 34 + #define Elf_Sym Elf32_Sym 35 + #define Elf_Dyn Elf32_Dyn 36 + #define Elf_Ehdr Elf32_Ehdr 37 + #define Elf_Addr Elf32_Addr 38 + #ifdef CONFIG_MODULES_USE_ELF_REL 39 + #define Elf_Rel Elf32_Rel 40 + #endif 41 + #ifdef CONFIG_MODULES_USE_ELF_RELA 42 + #define Elf_Rela Elf32_Rela 43 + #endif 44 + #define ELF_R_TYPE(X) ELF32_R_TYPE(X) 45 + #define ELF_R_SYM(X) ELF32_R_SYM(X) 20 46 #endif 21 47 22 48 #endif /* __ASM_GENERIC_MODULE_H */
+108
include/crypto/public_key.h
··· 1 + /* Asymmetric public-key algorithm definitions 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 + #ifndef _LINUX_PUBLIC_KEY_H 15 + #define _LINUX_PUBLIC_KEY_H 16 + 17 + #include <linux/mpi.h> 18 + 19 + enum pkey_algo { 20 + PKEY_ALGO_DSA, 21 + PKEY_ALGO_RSA, 22 + PKEY_ALGO__LAST 23 + }; 24 + 25 + extern const char *const pkey_algo[PKEY_ALGO__LAST]; 26 + 27 + enum pkey_hash_algo { 28 + PKEY_HASH_MD4, 29 + PKEY_HASH_MD5, 30 + PKEY_HASH_SHA1, 31 + PKEY_HASH_RIPE_MD_160, 32 + PKEY_HASH_SHA256, 33 + PKEY_HASH_SHA384, 34 + PKEY_HASH_SHA512, 35 + PKEY_HASH_SHA224, 36 + PKEY_HASH__LAST 37 + }; 38 + 39 + extern const char *const pkey_hash_algo[PKEY_HASH__LAST]; 40 + 41 + enum pkey_id_type { 42 + PKEY_ID_PGP, /* OpenPGP generated key ID */ 43 + PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ 44 + PKEY_ID_TYPE__LAST 45 + }; 46 + 47 + extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST]; 48 + 49 + /* 50 + * Cryptographic data for the public-key subtype of the asymmetric key type. 51 + * 52 + * Note that this may include private part of the key as well as the public 53 + * part. 54 + */ 55 + struct public_key { 56 + const struct public_key_algorithm *algo; 57 + u8 capabilities; 58 + #define PKEY_CAN_ENCRYPT 0x01 59 + #define PKEY_CAN_DECRYPT 0x02 60 + #define PKEY_CAN_SIGN 0x04 61 + #define PKEY_CAN_VERIFY 0x08 62 + enum pkey_id_type id_type : 8; 63 + union { 64 + MPI mpi[5]; 65 + struct { 66 + MPI p; /* DSA prime */ 67 + MPI q; /* DSA group order */ 68 + MPI g; /* DSA group generator */ 69 + MPI y; /* DSA public-key value = g^x mod p */ 70 + MPI x; /* DSA secret exponent (if present) */ 71 + } dsa; 72 + struct { 73 + MPI n; /* RSA public modulus */ 74 + MPI e; /* RSA public encryption exponent */ 75 + MPI d; /* RSA secret encryption exponent (if present) */ 76 + MPI p; /* RSA secret prime (if present) */ 77 + MPI q; /* RSA secret prime (if present) */ 78 + } rsa; 79 + }; 80 + }; 81 + 82 + extern void public_key_destroy(void *payload); 83 + 84 + /* 85 + * Public key cryptography signature data 86 + */ 87 + struct public_key_signature { 88 + u8 *digest; 89 + u8 digest_size; /* Number of bytes in digest */ 90 + u8 nr_mpi; /* Occupancy of mpi[] */ 91 + enum pkey_hash_algo pkey_hash_algo : 8; 92 + union { 93 + MPI mpi[2]; 94 + struct { 95 + MPI s; /* m^d mod n */ 96 + } rsa; 97 + struct { 98 + MPI r; 99 + MPI s; 100 + } dsa; 101 + }; 102 + }; 103 + 104 + struct key; 105 + extern int verify_signature(const struct key *key, 106 + const struct public_key_signature *sig); 107 + 108 + #endif /* _LINUX_PUBLIC_KEY_H */
+37
include/keys/asymmetric-parser.h
··· 1 + /* Asymmetric public-key cryptography data parser 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 + #ifndef _KEYS_ASYMMETRIC_PARSER_H 15 + #define _KEYS_ASYMMETRIC_PARSER_H 16 + 17 + /* 18 + * Key data parser. Called during key instantiation. 19 + */ 20 + struct asymmetric_key_parser { 21 + struct list_head link; 22 + struct module *owner; 23 + const char *name; 24 + 25 + /* Attempt to parse a key from the data blob passed to add_key() or 26 + * keyctl_instantiate(). Should also generate a proposed description 27 + * that the caller can optionally use for the key. 28 + * 29 + * Return EBADMSG if not recognised. 30 + */ 31 + int (*parse)(struct key_preparsed_payload *prep); 32 + }; 33 + 34 + extern int register_asymmetric_key_parser(struct asymmetric_key_parser *); 35 + extern void unregister_asymmetric_key_parser(struct asymmetric_key_parser *); 36 + 37 + #endif /* _KEYS_ASYMMETRIC_PARSER_H */
+55
include/keys/asymmetric-subtype.h
··· 1 + /* Asymmetric public-key cryptography key subtype 2 + * 3 + * See Documentation/security/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 + #ifndef _KEYS_ASYMMETRIC_SUBTYPE_H 15 + #define _KEYS_ASYMMETRIC_SUBTYPE_H 16 + 17 + #include <linux/seq_file.h> 18 + #include <keys/asymmetric-type.h> 19 + 20 + struct public_key_signature; 21 + 22 + /* 23 + * Keys of this type declare a subtype that indicates the handlers and 24 + * capabilities. 25 + */ 26 + struct asymmetric_key_subtype { 27 + struct module *owner; 28 + const char *name; 29 + unsigned short name_len; /* length of name */ 30 + 31 + /* Describe a key of this subtype for /proc/keys */ 32 + void (*describe)(const struct key *key, struct seq_file *m); 33 + 34 + /* Destroy a key of this subtype */ 35 + void (*destroy)(void *payload); 36 + 37 + /* Verify the signature on a key of this subtype (optional) */ 38 + int (*verify_signature)(const struct key *key, 39 + const struct public_key_signature *sig); 40 + }; 41 + 42 + /** 43 + * asymmetric_key_subtype - Get the subtype from an asymmetric key 44 + * @key: The key of interest. 45 + * 46 + * Retrieves and returns the subtype pointer of the asymmetric key from the 47 + * type-specific data attached to the key. 48 + */ 49 + static inline 50 + struct asymmetric_key_subtype *asymmetric_key_subtype(const struct key *key) 51 + { 52 + return key->type_data.p[0]; 53 + } 54 + 55 + #endif /* _KEYS_ASYMMETRIC_SUBTYPE_H */
+25
include/keys/asymmetric-type.h
··· 1 + /* Asymmetric Public-key cryptography key type interface 2 + * 3 + * See Documentation/security/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 + #ifndef _KEYS_ASYMMETRIC_TYPE_H 15 + #define _KEYS_ASYMMETRIC_TYPE_H 16 + 17 + #include <linux/key-type.h> 18 + 19 + extern struct key_type key_type_asymmetric; 20 + 21 + /* 22 + * The payload is at the discretion of the subtype. 23 + */ 24 + 25 + #endif /* _KEYS_ASYMMETRIC_TYPE_H */
+4 -2
include/keys/user-type.h
··· 35 35 extern struct key_type key_type_user; 36 36 extern struct key_type key_type_logon; 37 37 38 - extern int user_instantiate(struct key *key, const void *data, size_t datalen); 39 - extern int user_update(struct key *key, const void *data, size_t datalen); 38 + struct key_preparsed_payload; 39 + 40 + extern int user_instantiate(struct key *key, struct key_preparsed_payload *prep); 41 + extern int user_update(struct key *key, struct key_preparsed_payload *prep); 40 42 extern int user_match(const struct key *key, const void *criterion); 41 43 extern void user_revoke(struct key *key); 42 44 extern void user_destroy(struct key *key);
+67
include/linux/asn1.h
··· 1 + /* ASN.1 BER/DER/CER encoding definitions 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 + #ifndef _LINUX_ASN1_H 13 + #define _LINUX_ASN1_H 14 + 15 + /* Class */ 16 + enum asn1_class { 17 + ASN1_UNIV = 0, /* Universal */ 18 + ASN1_APPL = 1, /* Application */ 19 + ASN1_CONT = 2, /* Context */ 20 + ASN1_PRIV = 3 /* Private */ 21 + }; 22 + #define ASN1_CLASS_BITS 0xc0 23 + 24 + 25 + enum asn1_method { 26 + ASN1_PRIM = 0, /* Primitive */ 27 + ASN1_CONS = 1 /* Constructed */ 28 + }; 29 + #define ASN1_CONS_BIT 0x20 30 + 31 + /* Tag */ 32 + enum asn1_tag { 33 + ASN1_EOC = 0, /* End Of Contents or N/A */ 34 + ASN1_BOOL = 1, /* Boolean */ 35 + ASN1_INT = 2, /* Integer */ 36 + ASN1_BTS = 3, /* Bit String */ 37 + ASN1_OTS = 4, /* Octet String */ 38 + ASN1_NULL = 5, /* Null */ 39 + ASN1_OID = 6, /* Object Identifier */ 40 + ASN1_ODE = 7, /* Object Description */ 41 + ASN1_EXT = 8, /* External */ 42 + ASN1_REAL = 9, /* Real float */ 43 + ASN1_ENUM = 10, /* Enumerated */ 44 + ASN1_EPDV = 11, /* Embedded PDV */ 45 + ASN1_UTF8STR = 12, /* UTF8 String */ 46 + ASN1_RELOID = 13, /* Relative OID */ 47 + /* 14 - Reserved */ 48 + /* 15 - Reserved */ 49 + ASN1_SEQ = 16, /* Sequence and Sequence of */ 50 + ASN1_SET = 17, /* Set and Set of */ 51 + ASN1_NUMSTR = 18, /* Numerical String */ 52 + ASN1_PRNSTR = 19, /* Printable String */ 53 + ASN1_TEXSTR = 20, /* T61 String / Teletext String */ 54 + ASN1_VIDSTR = 21, /* Videotex String */ 55 + ASN1_IA5STR = 22, /* IA5 String */ 56 + ASN1_UNITIM = 23, /* Universal Time */ 57 + ASN1_GENTIM = 24, /* General Time */ 58 + ASN1_GRASTR = 25, /* Graphic String */ 59 + ASN1_VISSTR = 26, /* Visible String */ 60 + ASN1_GENSTR = 27, /* General String */ 61 + ASN1_UNISTR = 28, /* Universal String */ 62 + ASN1_CHRSTR = 29, /* Character String */ 63 + ASN1_BMPSTR = 30, /* BMP String */ 64 + ASN1_LONG_TAG = 31 /* Long form tag */ 65 + }; 66 + 67 + #endif /* _LINUX_ASN1_H */
+87
include/linux/asn1_ber_bytecode.h
··· 1 + /* ASN.1 BER/DER/CER parsing state machine internal definitions 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 + #ifndef _LINUX_ASN1_BER_BYTECODE_H 13 + #define _LINUX_ASN1_BER_BYTECODE_H 14 + 15 + #ifdef __KERNEL__ 16 + #include <linux/types.h> 17 + #endif 18 + #include <linux/asn1.h> 19 + 20 + typedef int (*asn1_action_t)(void *context, 21 + size_t hdrlen, /* In case of ANY type */ 22 + unsigned char tag, /* In case of ANY type */ 23 + const void *value, size_t vlen); 24 + 25 + struct asn1_decoder { 26 + const unsigned char *machine; 27 + size_t machlen; 28 + const asn1_action_t *actions; 29 + }; 30 + 31 + enum asn1_opcode { 32 + /* The tag-matching ops come first and the odd-numbered slots 33 + * are for OR_SKIP ops. 34 + */ 35 + #define ASN1_OP_MATCH__SKIP 0x01 36 + #define ASN1_OP_MATCH__ACT 0x02 37 + #define ASN1_OP_MATCH__JUMP 0x04 38 + #define ASN1_OP_MATCH__ANY 0x08 39 + #define ASN1_OP_MATCH__COND 0x10 40 + 41 + ASN1_OP_MATCH = 0x00, 42 + ASN1_OP_MATCH_OR_SKIP = 0x01, 43 + ASN1_OP_MATCH_ACT = 0x02, 44 + ASN1_OP_MATCH_ACT_OR_SKIP = 0x03, 45 + ASN1_OP_MATCH_JUMP = 0x04, 46 + ASN1_OP_MATCH_JUMP_OR_SKIP = 0x05, 47 + ASN1_OP_MATCH_ANY = 0x08, 48 + ASN1_OP_MATCH_ANY_ACT = 0x0a, 49 + /* Everything before here matches unconditionally */ 50 + 51 + ASN1_OP_COND_MATCH_OR_SKIP = 0x11, 52 + ASN1_OP_COND_MATCH_ACT_OR_SKIP = 0x13, 53 + ASN1_OP_COND_MATCH_JUMP_OR_SKIP = 0x15, 54 + ASN1_OP_COND_MATCH_ANY = 0x18, 55 + ASN1_OP_COND_MATCH_ANY_ACT = 0x1a, 56 + 57 + /* Everything before here will want a tag from the data */ 58 + #define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT 59 + 60 + /* These are here to help fill up space */ 61 + ASN1_OP_COND_FAIL = 0x1b, 62 + ASN1_OP_COMPLETE = 0x1c, 63 + ASN1_OP_ACT = 0x1d, 64 + ASN1_OP_RETURN = 0x1e, 65 + 66 + /* The following eight have bit 0 -> SET, 1 -> OF, 2 -> ACT */ 67 + ASN1_OP_END_SEQ = 0x20, 68 + ASN1_OP_END_SET = 0x21, 69 + ASN1_OP_END_SEQ_OF = 0x22, 70 + ASN1_OP_END_SET_OF = 0x23, 71 + ASN1_OP_END_SEQ_ACT = 0x24, 72 + ASN1_OP_END_SET_ACT = 0x25, 73 + ASN1_OP_END_SEQ_OF_ACT = 0x26, 74 + ASN1_OP_END_SET_OF_ACT = 0x27, 75 + #define ASN1_OP_END__SET 0x01 76 + #define ASN1_OP_END__OF 0x02 77 + #define ASN1_OP_END__ACT 0x04 78 + 79 + ASN1_OP__NR 80 + }; 81 + 82 + #define _tag(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | ASN1_##TAG) 83 + #define _tagn(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | TAG) 84 + #define _jump_target(N) (N) 85 + #define _action(N) (N) 86 + 87 + #endif /* _LINUX_ASN1_BER_BYTECODE_H */
+24
include/linux/asn1_decoder.h
··· 1 + /* ASN.1 decoder 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 + #ifndef _LINUX_ASN1_DECODER_H 13 + #define _LINUX_ASN1_DECODER_H 14 + 15 + #include <linux/asn1.h> 16 + 17 + struct asn1_decoder; 18 + 19 + extern int asn1_ber_decoder(const struct asn1_decoder *decoder, 20 + void *context, 21 + const unsigned char *data, 22 + size_t datalen); 23 + 24 + #endif /* _LINUX_ASN1_DECODER_H */
+33 -2
include/linux/key-type.h
··· 26 26 struct key *authkey;/* authorisation for key being constructed */ 27 27 }; 28 28 29 + /* 30 + * Pre-parsed payload, used by key add, update and instantiate. 31 + * 32 + * This struct will be cleared and data and datalen will be set with the data 33 + * and length parameters from the caller and quotalen will be set from 34 + * def_datalen from the key type. Then if the preparse() op is provided by the 35 + * key type, that will be called. Then the struct will be passed to the 36 + * instantiate() or the update() op. 37 + * 38 + * If the preparse() op is given, the free_preparse() op will be called to 39 + * clear the contents. 40 + */ 41 + struct key_preparsed_payload { 42 + char *description; /* Proposed key description (or NULL) */ 43 + void *type_data[2]; /* Private key-type data */ 44 + void *payload; /* Proposed payload */ 45 + const void *data; /* Raw data */ 46 + size_t datalen; /* Raw datalen */ 47 + size_t quotalen; /* Quota length for proposed payload */ 48 + }; 49 + 29 50 typedef int (*request_key_actor_t)(struct key_construction *key, 30 51 const char *op, void *aux); 31 52 ··· 66 45 /* vet a description */ 67 46 int (*vet_description)(const char *description); 68 47 48 + /* Preparse the data blob from userspace that is to be the payload, 49 + * generating a proposed description and payload that will be handed to 50 + * the instantiate() and update() ops. 51 + */ 52 + int (*preparse)(struct key_preparsed_payload *prep); 53 + 54 + /* Free a preparse data structure. 55 + */ 56 + void (*free_preparse)(struct key_preparsed_payload *prep); 57 + 69 58 /* instantiate a key of this type 70 59 * - this method should call key_payload_reserve() to determine if the 71 60 * user's quota will hold the payload 72 61 */ 73 - int (*instantiate)(struct key *key, const void *data, size_t datalen); 62 + int (*instantiate)(struct key *key, struct key_preparsed_payload *prep); 74 63 75 64 /* update a key of this type (optional) 76 65 * - this method should call key_payload_reserve() to recalculate the 77 66 * quota consumption 78 67 * - the key must be locked against read when modifying 79 68 */ 80 - int (*update)(struct key *key, const void *data, size_t datalen); 69 + int (*update)(struct key *key, struct key_preparsed_payload *prep); 81 70 82 71 /* match a key against a description */ 83 72 int (*match)(const struct key *key, const void *desc);
+8
include/linux/module.h
··· 21 21 #include <linux/percpu.h> 22 22 #include <asm/module.h> 23 23 24 + /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ 25 + #define MODULE_SIG_STRING "~Module signature appended~\n" 26 + 24 27 /* Not Yet Implemented */ 25 28 #define MODULE_SUPPORTED_DEVICE(name) 26 29 ··· 261 258 unsigned int num_unused_gpl_syms; 262 259 const struct kernel_symbol *unused_gpl_syms; 263 260 const unsigned long *unused_gpl_crcs; 261 + #endif 262 + 263 + #ifdef CONFIG_MODULE_SIG 264 + /* Signature was verified. */ 265 + bool sig_ok; 264 266 #endif 265 267 266 268 /* symbols that will be GPL-only in the near future. */
+32 -4
include/linux/moduleloader.h
··· 28 28 /* Free memory returned from module_alloc. */ 29 29 void module_free(struct module *mod, void *module_region); 30 30 31 - /* Apply the given relocation to the (simplified) ELF. Return -error 32 - or 0. */ 31 + /* 32 + * Apply the given relocation to the (simplified) ELF. Return -error 33 + * or 0. 34 + */ 35 + #ifdef CONFIG_MODULES_USE_ELF_REL 33 36 int apply_relocate(Elf_Shdr *sechdrs, 34 37 const char *strtab, 35 38 unsigned int symindex, 36 39 unsigned int relsec, 37 40 struct module *mod); 41 + #else 42 + static inline int apply_relocate(Elf_Shdr *sechdrs, 43 + const char *strtab, 44 + unsigned int symindex, 45 + unsigned int relsec, 46 + struct module *me) 47 + { 48 + printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); 49 + return -ENOEXEC; 50 + } 51 + #endif 38 52 39 - /* Apply the given add relocation to the (simplified) ELF. Return 40 - -error or 0 */ 53 + /* 54 + * Apply the given add relocation to the (simplified) ELF. Return 55 + * -error or 0 56 + */ 57 + #ifdef CONFIG_MODULES_USE_ELF_RELA 41 58 int apply_relocate_add(Elf_Shdr *sechdrs, 42 59 const char *strtab, 43 60 unsigned int symindex, 44 61 unsigned int relsec, 45 62 struct module *mod); 63 + #else 64 + static inline int apply_relocate_add(Elf_Shdr *sechdrs, 65 + const char *strtab, 66 + unsigned int symindex, 67 + unsigned int relsec, 68 + struct module *me) 69 + { 70 + printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); 71 + return -ENOEXEC; 72 + } 73 + #endif 46 74 47 75 /* Any final processing of module before access. Return -error or 0. */ 48 76 int module_finalize(const Elf_Ehdr *hdr,
+1
include/linux/mpi.h
··· 76 76 77 77 /*-- mpicoder.c --*/ 78 78 MPI do_encode_md(const void *sha_buffer, unsigned nbits); 79 + MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes); 79 80 MPI mpi_read_from_buffer(const void *buffer, unsigned *ret_nread); 80 81 int mpi_fromstr(MPI val, const char *str); 81 82 u32 mpi_get_keyid(MPI a, u32 *keyid);
+92
include/linux/oid_registry.h
··· 1 + /* ASN.1 Object identifier (OID) registry 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 + #ifndef _LINUX_OID_REGISTRY_H 13 + #define _LINUX_OID_REGISTRY_H 14 + 15 + #include <linux/types.h> 16 + 17 + /* 18 + * OIDs are turned into these values if possible, or OID__NR if not held here. 19 + * 20 + * NOTE! Do not mess with the format of each line as this is read by 21 + * build_OID_registry.pl to generate the data for look_up_OID(). 22 + */ 23 + enum OID { 24 + OID_id_dsa_with_sha1, /* 1.2.840.10030.4.3 */ 25 + OID_id_dsa, /* 1.2.840.10040.4.1 */ 26 + OID_id_ecdsa_with_sha1, /* 1.2.840.10045.4.1 */ 27 + OID_id_ecPublicKey, /* 1.2.840.10045.2.1 */ 28 + 29 + /* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */ 30 + OID_rsaEncryption, /* 1.2.840.113549.1.1.1 */ 31 + OID_md2WithRSAEncryption, /* 1.2.840.113549.1.1.2 */ 32 + OID_md3WithRSAEncryption, /* 1.2.840.113549.1.1.3 */ 33 + OID_md4WithRSAEncryption, /* 1.2.840.113549.1.1.4 */ 34 + OID_sha1WithRSAEncryption, /* 1.2.840.113549.1.1.5 */ 35 + OID_sha256WithRSAEncryption, /* 1.2.840.113549.1.1.11 */ 36 + OID_sha384WithRSAEncryption, /* 1.2.840.113549.1.1.12 */ 37 + OID_sha512WithRSAEncryption, /* 1.2.840.113549.1.1.13 */ 38 + OID_sha224WithRSAEncryption, /* 1.2.840.113549.1.1.14 */ 39 + /* PKCS#7 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-7(7)} */ 40 + OID_data, /* 1.2.840.113549.1.7.1 */ 41 + OID_signed_data, /* 1.2.840.113549.1.7.2 */ 42 + /* PKCS#9 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)} */ 43 + OID_email_address, /* 1.2.840.113549.1.9.1 */ 44 + OID_content_type, /* 1.2.840.113549.1.9.3 */ 45 + OID_messageDigest, /* 1.2.840.113549.1.9.4 */ 46 + OID_signingTime, /* 1.2.840.113549.1.9.5 */ 47 + OID_smimeCapabilites, /* 1.2.840.113549.1.9.15 */ 48 + OID_smimeAuthenticatedAttrs, /* 1.2.840.113549.1.9.16.2.11 */ 49 + 50 + /* {iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2)} */ 51 + OID_md2, /* 1.2.840.113549.2.2 */ 52 + OID_md4, /* 1.2.840.113549.2.4 */ 53 + OID_md5, /* 1.2.840.113549.2.5 */ 54 + 55 + OID_certAuthInfoAccess, /* 1.3.6.1.5.5.7.1.1 */ 56 + OID_msOutlookExpress, /* 1.3.6.1.4.1.311.16.4 */ 57 + OID_sha1, /* 1.3.14.3.2.26 */ 58 + 59 + /* Distinguished Name attribute IDs [RFC 2256] */ 60 + OID_commonName, /* 2.5.4.3 */ 61 + OID_surname, /* 2.5.4.4 */ 62 + OID_countryName, /* 2.5.4.6 */ 63 + OID_locality, /* 2.5.4.7 */ 64 + OID_stateOrProvinceName, /* 2.5.4.8 */ 65 + OID_organizationName, /* 2.5.4.10 */ 66 + OID_organizationUnitName, /* 2.5.4.11 */ 67 + OID_title, /* 2.5.4.12 */ 68 + OID_description, /* 2.5.4.13 */ 69 + OID_name, /* 2.5.4.41 */ 70 + OID_givenName, /* 2.5.4.42 */ 71 + OID_initials, /* 2.5.4.43 */ 72 + OID_generationalQualifier, /* 2.5.4.44 */ 73 + 74 + /* Certificate extension IDs */ 75 + OID_subjectKeyIdentifier, /* 2.5.29.14 */ 76 + OID_keyUsage, /* 2.5.29.15 */ 77 + OID_subjectAltName, /* 2.5.29.17 */ 78 + OID_issuerAltName, /* 2.5.29.18 */ 79 + OID_basicConstraints, /* 2.5.29.19 */ 80 + OID_crlDistributionPoints, /* 2.5.29.31 */ 81 + OID_certPolicies, /* 2.5.29.32 */ 82 + OID_authorityKeyIdentifier, /* 2.5.29.35 */ 83 + OID_extKeyUsage, /* 2.5.29.37 */ 84 + 85 + OID__NR 86 + }; 87 + 88 + extern enum OID look_up_OID(const void *data, size_t datasize); 89 + extern int sprint_oid(const void *, size_t, char *, size_t); 90 + extern int sprint_OID(enum OID, char *, size_t); 91 + 92 + #endif /* _LINUX_OID_REGISTRY_H */
+68
init/Kconfig
··· 1574 1574 the version). With this option, such a "srcversion" field 1575 1575 will be created for all modules. If unsure, say N. 1576 1576 1577 + config MODULE_SIG 1578 + bool "Module signature verification" 1579 + depends on MODULES 1580 + select KEYS 1581 + select CRYPTO 1582 + select ASYMMETRIC_KEY_TYPE 1583 + select ASYMMETRIC_PUBLIC_KEY_SUBTYPE 1584 + select PUBLIC_KEY_ALGO_RSA 1585 + select ASN1 1586 + select OID_REGISTRY 1587 + select X509_CERTIFICATE_PARSER 1588 + help 1589 + Check modules for valid signatures upon load: the signature 1590 + is simply appended to the module. For more information see 1591 + Documentation/module-signing.txt. 1592 + 1593 + !!!WARNING!!! If you enable this option, you MUST make sure that the 1594 + module DOES NOT get stripped after being signed. This includes the 1595 + debuginfo strip done by some packagers (such as rpmbuild) and 1596 + inclusion into an initramfs that wants the module size reduced. 1597 + 1598 + config MODULE_SIG_FORCE 1599 + bool "Require modules to be validly signed" 1600 + depends on MODULE_SIG 1601 + help 1602 + Reject unsigned modules or signed modules for which we don't have a 1603 + key. Without this, such modules will simply taint the kernel. 1604 + 1605 + choice 1606 + prompt "Which hash algorithm should modules be signed with?" 1607 + depends on MODULE_SIG 1608 + help 1609 + This determines which sort of hashing algorithm will be used during 1610 + signature generation. This algorithm _must_ be built into the kernel 1611 + directly so that signature verification can take place. It is not 1612 + possible to load a signed module containing the algorithm to check 1613 + the signature on that module. 1614 + 1615 + config MODULE_SIG_SHA1 1616 + bool "Sign modules with SHA-1" 1617 + select CRYPTO_SHA1 1618 + 1619 + config MODULE_SIG_SHA224 1620 + bool "Sign modules with SHA-224" 1621 + select CRYPTO_SHA256 1622 + 1623 + config MODULE_SIG_SHA256 1624 + bool "Sign modules with SHA-256" 1625 + select CRYPTO_SHA256 1626 + 1627 + config MODULE_SIG_SHA384 1628 + bool "Sign modules with SHA-384" 1629 + select CRYPTO_SHA512 1630 + 1631 + config MODULE_SIG_SHA512 1632 + bool "Sign modules with SHA-512" 1633 + select CRYPTO_SHA512 1634 + 1635 + endchoice 1636 + 1577 1637 endif # MODULES 1578 1638 1579 1639 config INIT_ALL_POSSIBLE ··· 1666 1606 # mappings 1667 1607 config BROKEN_RODATA 1668 1608 bool 1609 + 1610 + config ASN1 1611 + tristate 1612 + help 1613 + Build a simple ASN.1 grammar compiler that produces a bytecode output 1614 + that can be interpreted by the ASN.1 stream decoder and used to 1615 + inform it as to what tags are to be expected in a stream and what 1616 + functions to call on what tags. 1669 1617 1670 1618 source "kernel/Kconfig.locks"
+77
kernel/Makefile
··· 54 54 obj-$(CONFIG_PROVE_LOCKING) += spinlock.o 55 55 obj-$(CONFIG_UID16) += uid16.o 56 56 obj-$(CONFIG_MODULES) += module.o 57 + obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o 57 58 obj-$(CONFIG_KALLSYMS) += kallsyms.o 58 59 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 59 60 obj-$(CONFIG_KEXEC) += kexec.o ··· 131 130 targets += timeconst.h 132 131 $(obj)/timeconst.h: $(src)/timeconst.pl FORCE 133 132 $(call if_changed,timeconst) 133 + 134 + ifeq ($(CONFIG_MODULE_SIG),y) 135 + # 136 + # Pull the signing certificate and any extra certificates into the kernel 137 + # 138 + extra_certificates: 139 + touch $@ 140 + 141 + kernel/modsign_pubkey.o: signing_key.x509 extra_certificates 142 + 143 + ############################################################################### 144 + # 145 + # If module signing is requested, say by allyesconfig, but a key has not been 146 + # supplied, then one will need to be generated to make sure the build does not 147 + # fail and that the kernel may be used afterwards. 148 + # 149 + ############################################################################### 150 + sign_key_with_hash := 151 + ifeq ($(CONFIG_MODULE_SIG_SHA1),y) 152 + sign_key_with_hash := -sha1 153 + endif 154 + ifeq ($(CONFIG_MODULE_SIG_SHA224),y) 155 + sign_key_with_hash := -sha224 156 + endif 157 + ifeq ($(CONFIG_MODULE_SIG_SHA256),y) 158 + sign_key_with_hash := -sha256 159 + endif 160 + ifeq ($(CONFIG_MODULE_SIG_SHA384),y) 161 + sign_key_with_hash := -sha384 162 + endif 163 + ifeq ($(CONFIG_MODULE_SIG_SHA512),y) 164 + sign_key_with_hash := -sha512 165 + endif 166 + ifeq ($(sign_key_with_hash),) 167 + $(error Could not determine digest type to use from kernel config) 168 + endif 169 + 170 + signing_key.priv signing_key.x509: x509.genkey 171 + @echo "###" 172 + @echo "### Now generating an X.509 key pair to be used for signing modules." 173 + @echo "###" 174 + @echo "### If this takes a long time, you might wish to run rngd in the" 175 + @echo "### background to keep the supply of entropy topped up. It" 176 + @echo "### needs to be run as root, and should use a hardware random" 177 + @echo "### number generator if one is available, eg:" 178 + @echo "###" 179 + @echo "### rngd -r /dev/hwrandom" 180 + @echo "###" 181 + openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \ 182 + -x509 -config x509.genkey \ 183 + -outform DER -out signing_key.x509 \ 184 + -keyout signing_key.priv 185 + @echo "###" 186 + @echo "### Key pair generated." 187 + @echo "###" 188 + 189 + x509.genkey: 190 + @echo Generating X.509 key generation config 191 + @echo >x509.genkey "[ req ]" 192 + @echo >>x509.genkey "default_bits = 4096" 193 + @echo >>x509.genkey "distinguished_name = req_distinguished_name" 194 + @echo >>x509.genkey "prompt = no" 195 + @echo >>x509.genkey "string_mask = utf8only" 196 + @echo >>x509.genkey "x509_extensions = myexts" 197 + @echo >>x509.genkey 198 + @echo >>x509.genkey "[ req_distinguished_name ]" 199 + @echo >>x509.genkey "O = Magrathea" 200 + @echo >>x509.genkey "CN = Glacier signing key" 201 + @echo >>x509.genkey "emailAddress = slartibartfast@magrathea.h2g2" 202 + @echo >>x509.genkey 203 + @echo >>x509.genkey "[ myexts ]" 204 + @echo >>x509.genkey "basicConstraints=critical,CA:FALSE" 205 + @echo >>x509.genkey "keyUsage=digitalSignature" 206 + @echo >>x509.genkey "subjectKeyIdentifier=hash" 207 + @echo >>x509.genkey "authorityKeyIdentifier=keyid" 208 + endif
+113
kernel/modsign_pubkey.c
··· 1 + /* Public keys for module signature verification 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 + #include <linux/kernel.h> 13 + #include <linux/sched.h> 14 + #include <linux/cred.h> 15 + #include <linux/err.h> 16 + #include <keys/asymmetric-type.h> 17 + #include "module-internal.h" 18 + 19 + struct key *modsign_keyring; 20 + 21 + extern __initdata const u8 modsign_certificate_list[]; 22 + extern __initdata const u8 modsign_certificate_list_end[]; 23 + asm(".section .init.data,\"aw\"\n" 24 + "modsign_certificate_list:\n" 25 + ".incbin \"signing_key.x509\"\n" 26 + ".incbin \"extra_certificates\"\n" 27 + "modsign_certificate_list_end:" 28 + ); 29 + 30 + /* 31 + * We need to make sure ccache doesn't cache the .o file as it doesn't notice 32 + * if modsign.pub changes. 33 + */ 34 + static __initdata const char annoy_ccache[] = __TIME__ "foo"; 35 + 36 + /* 37 + * Load the compiled-in keys 38 + */ 39 + static __init int module_verify_init(void) 40 + { 41 + pr_notice("Initialise module verification\n"); 42 + 43 + modsign_keyring = key_alloc(&key_type_keyring, ".module_sign", 44 + KUIDT_INIT(0), KGIDT_INIT(0), 45 + current_cred(), 46 + (KEY_POS_ALL & ~KEY_POS_SETATTR) | 47 + KEY_USR_VIEW | KEY_USR_READ, 48 + KEY_ALLOC_NOT_IN_QUOTA); 49 + if (IS_ERR(modsign_keyring)) 50 + panic("Can't allocate module signing keyring\n"); 51 + 52 + if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0) 53 + panic("Can't instantiate module signing keyring\n"); 54 + 55 + return 0; 56 + } 57 + 58 + /* 59 + * Must be initialised before we try and load the keys into the keyring. 60 + */ 61 + device_initcall(module_verify_init); 62 + 63 + /* 64 + * Load the compiled-in keys 65 + */ 66 + static __init int load_module_signing_keys(void) 67 + { 68 + key_ref_t key; 69 + const u8 *p, *end; 70 + size_t plen; 71 + 72 + pr_notice("Loading module verification certificates\n"); 73 + 74 + end = modsign_certificate_list_end; 75 + p = modsign_certificate_list; 76 + while (p < end) { 77 + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more 78 + * than 256 bytes in size. 79 + */ 80 + if (end - p < 4) 81 + goto dodgy_cert; 82 + if (p[0] != 0x30 && 83 + p[1] != 0x82) 84 + goto dodgy_cert; 85 + plen = (p[2] << 8) | p[3]; 86 + plen += 4; 87 + if (plen > end - p) 88 + goto dodgy_cert; 89 + 90 + key = key_create_or_update(make_key_ref(modsign_keyring, 1), 91 + "asymmetric", 92 + NULL, 93 + p, 94 + plen, 95 + (KEY_POS_ALL & ~KEY_POS_SETATTR) | 96 + KEY_USR_VIEW, 97 + KEY_ALLOC_NOT_IN_QUOTA); 98 + if (IS_ERR(key)) 99 + pr_err("MODSIGN: Problem loading in-kernel X.509 certificate (%ld)\n", 100 + PTR_ERR(key)); 101 + else 102 + pr_notice("MODSIGN: Loaded cert '%s'\n", 103 + key_ref_to_ptr(key)->description); 104 + p += plen; 105 + } 106 + 107 + return 0; 108 + 109 + dodgy_cert: 110 + pr_err("MODSIGN: Problem parsing in-kernel X.509 certificate list\n"); 111 + return 0; 112 + } 113 + late_initcall(load_module_signing_keys);
+15
kernel/module-internal.h
··· 1 + /* Module internals 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 + extern struct key *modsign_keyring; 13 + 14 + extern int mod_verify_sig(const void *mod, unsigned long modlen, 15 + const void *sig, unsigned long siglen);
+130 -27
kernel/module.c
··· 58 58 #include <linux/jump_label.h> 59 59 #include <linux/pfn.h> 60 60 #include <linux/bsearch.h> 61 + #include <linux/fips.h> 62 + #include "module-internal.h" 61 63 62 64 #define CREATE_TRACE_POINTS 63 65 #include <trace/events/module.h> ··· 104 102 struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ 105 103 #endif /* CONFIG_KGDB_KDB */ 106 104 105 + #ifdef CONFIG_MODULE_SIG 106 + #ifdef CONFIG_MODULE_SIG_FORCE 107 + static bool sig_enforce = true; 108 + #else 109 + static bool sig_enforce = false; 110 + 111 + static int param_set_bool_enable_only(const char *val, 112 + const struct kernel_param *kp) 113 + { 114 + int err; 115 + bool test; 116 + struct kernel_param dummy_kp = *kp; 117 + 118 + dummy_kp.arg = &test; 119 + 120 + err = param_set_bool(val, &dummy_kp); 121 + if (err) 122 + return err; 123 + 124 + /* Don't let them unset it once it's set! */ 125 + if (!test && sig_enforce) 126 + return -EROFS; 127 + 128 + if (test) 129 + sig_enforce = true; 130 + return 0; 131 + } 132 + 133 + static const struct kernel_param_ops param_ops_bool_enable_only = { 134 + .set = param_set_bool_enable_only, 135 + .get = param_get_bool, 136 + }; 137 + #define param_check_bool_enable_only param_check_bool 138 + 139 + module_param(sig_enforce, bool_enable_only, 0644); 140 + #endif /* !CONFIG_MODULE_SIG_FORCE */ 141 + #endif /* CONFIG_MODULE_SIG */ 107 142 108 143 /* Block module loading/unloading? */ 109 144 int modules_disabled = 0; ··· 175 136 unsigned long symoffs, stroffs; 176 137 struct _ddebug *debug; 177 138 unsigned int num_debug; 139 + bool sig_ok; 178 140 struct { 179 141 unsigned int sym, str, mod, vers, info, pcpu; 180 142 } index; ··· 1989 1949 return ret; 1990 1950 } 1991 1951 1992 - int __weak apply_relocate(Elf_Shdr *sechdrs, 1993 - const char *strtab, 1994 - unsigned int symindex, 1995 - unsigned int relsec, 1996 - struct module *me) 1997 - { 1998 - pr_err("module %s: REL relocation unsupported\n", me->name); 1999 - return -ENOEXEC; 2000 - } 2001 - 2002 - int __weak apply_relocate_add(Elf_Shdr *sechdrs, 2003 - const char *strtab, 2004 - unsigned int symindex, 2005 - unsigned int relsec, 2006 - struct module *me) 2007 - { 2008 - pr_err("module %s: RELA relocation unsupported\n", me->name); 2009 - return -ENOEXEC; 2010 - } 2011 - 2012 1952 static int apply_relocations(struct module *mod, const struct load_info *info) 2013 1953 { 2014 1954 unsigned int i; ··· 2419 2399 } 2420 2400 #endif 2421 2401 2422 - /* Sets info->hdr and info->len. */ 2402 + #ifdef CONFIG_MODULE_SIG 2403 + static int module_sig_check(struct load_info *info, 2404 + const void *mod, unsigned long *len) 2405 + { 2406 + int err = -ENOKEY; 2407 + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; 2408 + const void *p = mod, *end = mod + *len; 2409 + 2410 + /* Poor man's memmem. */ 2411 + while ((p = memchr(p, MODULE_SIG_STRING[0], end - p))) { 2412 + if (p + markerlen > end) 2413 + break; 2414 + 2415 + if (memcmp(p, MODULE_SIG_STRING, markerlen) == 0) { 2416 + const void *sig = p + markerlen; 2417 + /* Truncate module up to signature. */ 2418 + *len = p - mod; 2419 + err = mod_verify_sig(mod, *len, sig, end - sig); 2420 + break; 2421 + } 2422 + p++; 2423 + } 2424 + 2425 + if (!err) { 2426 + info->sig_ok = true; 2427 + return 0; 2428 + } 2429 + 2430 + /* Not having a signature is only an error if we're strict. */ 2431 + if (err < 0 && fips_enabled) 2432 + panic("Module verification failed with error %d in FIPS mode\n", 2433 + err); 2434 + if (err == -ENOKEY && !sig_enforce) 2435 + err = 0; 2436 + 2437 + return err; 2438 + } 2439 + #else /* !CONFIG_MODULE_SIG */ 2440 + static int module_sig_check(struct load_info *info, 2441 + void *mod, unsigned long *len) 2442 + { 2443 + return 0; 2444 + } 2445 + #endif /* !CONFIG_MODULE_SIG */ 2446 + 2447 + /* Sets info->hdr, info->len and info->sig_ok. */ 2423 2448 static int copy_and_check(struct load_info *info, 2424 2449 const void __user *umod, unsigned long len, 2425 2450 const char __user *uargs) ··· 2483 2418 err = -EFAULT; 2484 2419 goto free_hdr; 2485 2420 } 2421 + 2422 + err = module_sig_check(info, hdr, &len); 2423 + if (err) 2424 + goto free_hdr; 2486 2425 2487 2426 /* Sanity checks against insmoding binaries or wrong arch, 2488 2427 weird elf version */ ··· 2799 2730 if (strcmp(mod->name, "driverloader") == 0) 2800 2731 add_taint_module(mod, TAINT_PROPRIETARY_MODULE); 2801 2732 2733 + /* lve claims to be GPL but upstream won't provide source */ 2734 + if (strcmp(mod->name, "lve") == 0) 2735 + add_taint_module(mod, TAINT_PROPRIETARY_MODULE); 2736 + 2802 2737 #ifdef CONFIG_MODVERSIONS 2803 2738 if ((mod->num_syms && !mod->crcs) 2804 2739 || (mod->num_gpl_syms && !mod->gpl_crcs) ··· 2934 2861 return module_finalize(info->hdr, info->sechdrs, mod); 2935 2862 } 2936 2863 2864 + /* Is this module of this name done loading? No locks held. */ 2865 + static bool finished_loading(const char *name) 2866 + { 2867 + struct module *mod; 2868 + bool ret; 2869 + 2870 + mutex_lock(&module_mutex); 2871 + mod = find_module(name); 2872 + ret = !mod || mod->state != MODULE_STATE_COMING; 2873 + mutex_unlock(&module_mutex); 2874 + 2875 + return ret; 2876 + } 2877 + 2937 2878 /* Allocate and load the module: note that size of section 0 is always 2938 2879 zero, and we rely on this for optional sections. */ 2939 2880 static struct module *load_module(void __user *umod, ··· 2955 2868 const char __user *uargs) 2956 2869 { 2957 2870 struct load_info info = { NULL, }; 2958 - struct module *mod; 2871 + struct module *mod, *old; 2959 2872 long err; 2960 2873 2961 2874 pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", ··· 2972 2885 err = PTR_ERR(mod); 2973 2886 goto free_copy; 2974 2887 } 2888 + 2889 + #ifdef CONFIG_MODULE_SIG 2890 + mod->sig_ok = info.sig_ok; 2891 + if (!mod->sig_ok) 2892 + add_taint_module(mod, TAINT_FORCED_MODULE); 2893 + #endif 2975 2894 2976 2895 /* Now module is in final location, initialize linked lists, etc. */ 2977 2896 err = module_unload_init(mod); ··· 3027 2934 * function to insert in a way safe to concurrent readers. 3028 2935 * The mutex protects against concurrent writers. 3029 2936 */ 2937 + again: 3030 2938 mutex_lock(&module_mutex); 3031 - if (find_module(mod->name)) { 2939 + if ((old = find_module(mod->name)) != NULL) { 2940 + if (old->state == MODULE_STATE_COMING) { 2941 + /* Wait in case it fails to load. */ 2942 + mutex_unlock(&module_mutex); 2943 + err = wait_event_interruptible(module_wq, 2944 + finished_loading(mod->name)); 2945 + if (err) 2946 + goto free_arch_cleanup; 2947 + goto again; 2948 + } 3032 2949 err = -EEXIST; 3033 2950 goto unlock; 3034 2951 } ··· 3078 2975 /* Unlink carefully: kallsyms could be walking list. */ 3079 2976 list_del_rcu(&mod->list); 3080 2977 module_bug_cleanup(mod); 3081 - 2978 + wake_up_all(&module_wq); 3082 2979 ddebug: 3083 2980 dynamic_debug_remove(info.debug); 3084 2981 unlock: ··· 3153 3050 blocking_notifier_call_chain(&module_notify_list, 3154 3051 MODULE_STATE_GOING, mod); 3155 3052 free_module(mod); 3156 - wake_up(&module_wq); 3053 + wake_up_all(&module_wq); 3157 3054 return ret; 3158 3055 } 3159 3056 if (ret > 0) { ··· 3165 3062 dump_stack(); 3166 3063 } 3167 3064 3168 - /* Now it's a first class citizen! Wake up anyone waiting for it. */ 3065 + /* Now it's a first class citizen! */ 3169 3066 mod->state = MODULE_STATE_LIVE; 3170 - wake_up(&module_wq); 3171 3067 blocking_notifier_call_chain(&module_notify_list, 3172 3068 MODULE_STATE_LIVE, mod); 3173 3069 ··· 3189 3087 mod->init_ro_size = 0; 3190 3088 mod->init_text_size = 0; 3191 3089 mutex_unlock(&module_mutex); 3090 + wake_up_all(&module_wq); 3192 3091 3193 3092 return 0; 3194 3093 }
+243
kernel/module_signing.c
··· 1 + /* Module signature checker 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 + #include <linux/kernel.h> 13 + #include <linux/err.h> 14 + #include <crypto/public_key.h> 15 + #include <crypto/hash.h> 16 + #include <keys/asymmetric-type.h> 17 + #include "module-internal.h" 18 + 19 + /* 20 + * Module signature information block. 21 + * 22 + * The constituents of the signature section are, in order: 23 + * 24 + * - Signer's name 25 + * - Key identifier 26 + * - Signature data 27 + * - Information block 28 + */ 29 + struct module_signature { 30 + enum pkey_algo algo : 8; /* Public-key crypto algorithm */ 31 + enum pkey_hash_algo hash : 8; /* Digest algorithm */ 32 + enum pkey_id_type id_type : 8; /* Key identifier type */ 33 + u8 signer_len; /* Length of signer's name */ 34 + u8 key_id_len; /* Length of key identifier */ 35 + u8 __pad[3]; 36 + __be32 sig_len; /* Length of signature data */ 37 + }; 38 + 39 + /* 40 + * Digest the module contents. 41 + */ 42 + static struct public_key_signature *mod_make_digest(enum pkey_hash_algo hash, 43 + const void *mod, 44 + unsigned long modlen) 45 + { 46 + struct public_key_signature *pks; 47 + struct crypto_shash *tfm; 48 + struct shash_desc *desc; 49 + size_t digest_size, desc_size; 50 + int ret; 51 + 52 + pr_devel("==>%s()\n", __func__); 53 + 54 + /* Allocate the hashing algorithm we're going to need and find out how 55 + * big the hash operational data will be. 56 + */ 57 + tfm = crypto_alloc_shash(pkey_hash_algo[hash], 0, 0); 58 + if (IS_ERR(tfm)) 59 + return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm); 60 + 61 + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 62 + digest_size = crypto_shash_digestsize(tfm); 63 + 64 + /* We allocate the hash operational data storage on the end of our 65 + * context data and the digest output buffer on the end of that. 66 + */ 67 + ret = -ENOMEM; 68 + pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL); 69 + if (!pks) 70 + goto error_no_pks; 71 + 72 + pks->pkey_hash_algo = hash; 73 + pks->digest = (u8 *)pks + sizeof(*pks) + desc_size; 74 + pks->digest_size = digest_size; 75 + 76 + desc = (void *)pks + sizeof(*pks); 77 + desc->tfm = tfm; 78 + desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 79 + 80 + ret = crypto_shash_init(desc); 81 + if (ret < 0) 82 + goto error; 83 + 84 + ret = crypto_shash_finup(desc, mod, modlen, pks->digest); 85 + if (ret < 0) 86 + goto error; 87 + 88 + crypto_free_shash(tfm); 89 + pr_devel("<==%s() = ok\n", __func__); 90 + return pks; 91 + 92 + error: 93 + kfree(pks); 94 + error_no_pks: 95 + crypto_free_shash(tfm); 96 + pr_devel("<==%s() = %d\n", __func__, ret); 97 + return ERR_PTR(ret); 98 + } 99 + 100 + /* 101 + * Extract an MPI array from the signature data. This represents the actual 102 + * signature. Each raw MPI is prefaced by a BE 2-byte value indicating the 103 + * size of the MPI in bytes. 104 + * 105 + * RSA signatures only have one MPI, so currently we only read one. 106 + */ 107 + static int mod_extract_mpi_array(struct public_key_signature *pks, 108 + const void *data, size_t len) 109 + { 110 + size_t nbytes; 111 + MPI mpi; 112 + 113 + if (len < 3) 114 + return -EBADMSG; 115 + nbytes = ((const u8 *)data)[0] << 8 | ((const u8 *)data)[1]; 116 + data += 2; 117 + len -= 2; 118 + if (len != nbytes) 119 + return -EBADMSG; 120 + 121 + mpi = mpi_read_raw_data(data, nbytes); 122 + if (!mpi) 123 + return -ENOMEM; 124 + pks->mpi[0] = mpi; 125 + pks->nr_mpi = 1; 126 + return 0; 127 + } 128 + 129 + /* 130 + * Request an asymmetric key. 131 + */ 132 + static struct key *request_asymmetric_key(const char *signer, size_t signer_len, 133 + const u8 *key_id, size_t key_id_len) 134 + { 135 + key_ref_t key; 136 + size_t i; 137 + char *id, *q; 138 + 139 + pr_devel("==>%s(,%zu,,%zu)\n", __func__, signer_len, key_id_len); 140 + 141 + /* Construct an identifier. */ 142 + id = kmalloc(signer_len + 2 + key_id_len * 2 + 1, GFP_KERNEL); 143 + if (!id) 144 + return ERR_PTR(-ENOKEY); 145 + 146 + memcpy(id, signer, signer_len); 147 + 148 + q = id + signer_len; 149 + *q++ = ':'; 150 + *q++ = ' '; 151 + for (i = 0; i < key_id_len; i++) { 152 + *q++ = hex_asc[*key_id >> 4]; 153 + *q++ = hex_asc[*key_id++ & 0x0f]; 154 + } 155 + 156 + *q = 0; 157 + 158 + pr_debug("Look up: \"%s\"\n", id); 159 + 160 + key = keyring_search(make_key_ref(modsign_keyring, 1), 161 + &key_type_asymmetric, id); 162 + if (IS_ERR(key)) 163 + pr_warn("Request for unknown module key '%s' err %ld\n", 164 + id, PTR_ERR(key)); 165 + kfree(id); 166 + 167 + if (IS_ERR(key)) { 168 + switch (PTR_ERR(key)) { 169 + /* Hide some search errors */ 170 + case -EACCES: 171 + case -ENOTDIR: 172 + case -EAGAIN: 173 + return ERR_PTR(-ENOKEY); 174 + default: 175 + return ERR_CAST(key); 176 + } 177 + } 178 + 179 + pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key))); 180 + return key_ref_to_ptr(key); 181 + } 182 + 183 + /* 184 + * Verify the signature on a module. 185 + */ 186 + int mod_verify_sig(const void *mod, unsigned long modlen, 187 + const void *sig, unsigned long siglen) 188 + { 189 + struct public_key_signature *pks; 190 + struct module_signature ms; 191 + struct key *key; 192 + size_t sig_len; 193 + int ret; 194 + 195 + pr_devel("==>%s(,%lu,,%lu,)\n", __func__, modlen, siglen); 196 + 197 + if (siglen <= sizeof(ms)) 198 + return -EBADMSG; 199 + 200 + memcpy(&ms, sig + (siglen - sizeof(ms)), sizeof(ms)); 201 + siglen -= sizeof(ms); 202 + 203 + sig_len = be32_to_cpu(ms.sig_len); 204 + if (sig_len >= siglen || 205 + siglen - sig_len != (size_t)ms.signer_len + ms.key_id_len) 206 + return -EBADMSG; 207 + 208 + /* For the moment, only support RSA and X.509 identifiers */ 209 + if (ms.algo != PKEY_ALGO_RSA || 210 + ms.id_type != PKEY_ID_X509) 211 + return -ENOPKG; 212 + 213 + if (ms.hash >= PKEY_HASH__LAST || 214 + !pkey_hash_algo[ms.hash]) 215 + return -ENOPKG; 216 + 217 + key = request_asymmetric_key(sig, ms.signer_len, 218 + sig + ms.signer_len, ms.key_id_len); 219 + if (IS_ERR(key)) 220 + return PTR_ERR(key); 221 + 222 + pks = mod_make_digest(ms.hash, mod, modlen); 223 + if (IS_ERR(pks)) { 224 + ret = PTR_ERR(pks); 225 + goto error_put_key; 226 + } 227 + 228 + ret = mod_extract_mpi_array(pks, sig + ms.signer_len + ms.key_id_len, 229 + sig_len); 230 + if (ret < 0) 231 + goto error_free_pks; 232 + 233 + ret = verify_signature(key, pks); 234 + pr_devel("verify_signature() = %d\n", ret); 235 + 236 + error_free_pks: 237 + mpi_free(pks->rsa.s); 238 + kfree(pks); 239 + error_put_key: 240 + key_put(key); 241 + pr_devel("<==%s() = %d\n", __func__, ret); 242 + return ret; 243 + }
+1 -1
lib/.gitignore
··· 3 3 # 4 4 gen_crc32table 5 5 crc32table.h 6 - 6 + oid_registry_data.c
+5
lib/Kconfig
··· 396 396 config LIBFDT 397 397 bool 398 398 399 + config OID_REGISTRY 400 + tristate 401 + help 402 + Enable fast lookup object identifier registry. 403 + 399 404 endmenu
+18
lib/Makefile
··· 145 145 146 146 interval_tree_test-objs := interval_tree_test_main.o interval_tree.o 147 147 148 + obj-$(CONFIG_ASN1) += asn1_decoder.o 149 + 148 150 hostprogs-y := gen_crc32table 149 151 clean-files := crc32table.h 150 152 ··· 157 155 158 156 $(obj)/crc32table.h: $(obj)/gen_crc32table 159 157 $(call cmd,crc32) 158 + 159 + # 160 + # Build a fast OID lookip registry from include/linux/oid_registry.h 161 + # 162 + obj-$(CONFIG_OID_REGISTRY) += oid_registry.o 163 + 164 + $(obj)/oid_registry.c: $(obj)/oid_registry_data.c 165 + 166 + $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ 167 + $(src)/build_OID_registry 168 + $(call cmd,build_OID_registry) 169 + 170 + quiet_cmd_build_OID_registry = GEN $@ 171 + cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@ 172 + 173 + clean-files += oid_registry_data.c
+487
lib/asn1_decoder.c
··· 1 + /* Decoder for ASN.1 BER/DER/CER encoded bytestream 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 + #include <linux/export.h> 13 + #include <linux/kernel.h> 14 + #include <linux/errno.h> 15 + #include <linux/asn1_decoder.h> 16 + #include <linux/asn1_ber_bytecode.h> 17 + 18 + static const unsigned char asn1_op_lengths[ASN1_OP__NR] = { 19 + /* OPC TAG JMP ACT */ 20 + [ASN1_OP_MATCH] = 1 + 1, 21 + [ASN1_OP_MATCH_OR_SKIP] = 1 + 1, 22 + [ASN1_OP_MATCH_ACT] = 1 + 1 + 1, 23 + [ASN1_OP_MATCH_ACT_OR_SKIP] = 1 + 1 + 1, 24 + [ASN1_OP_MATCH_JUMP] = 1 + 1 + 1, 25 + [ASN1_OP_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1, 26 + [ASN1_OP_MATCH_ANY] = 1, 27 + [ASN1_OP_MATCH_ANY_ACT] = 1 + 1, 28 + [ASN1_OP_COND_MATCH_OR_SKIP] = 1 + 1, 29 + [ASN1_OP_COND_MATCH_ACT_OR_SKIP] = 1 + 1 + 1, 30 + [ASN1_OP_COND_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1, 31 + [ASN1_OP_COND_MATCH_ANY] = 1, 32 + [ASN1_OP_COND_MATCH_ANY_ACT] = 1 + 1, 33 + [ASN1_OP_COND_FAIL] = 1, 34 + [ASN1_OP_COMPLETE] = 1, 35 + [ASN1_OP_ACT] = 1 + 1, 36 + [ASN1_OP_RETURN] = 1, 37 + [ASN1_OP_END_SEQ] = 1, 38 + [ASN1_OP_END_SEQ_OF] = 1 + 1, 39 + [ASN1_OP_END_SET] = 1, 40 + [ASN1_OP_END_SET_OF] = 1 + 1, 41 + [ASN1_OP_END_SEQ_ACT] = 1 + 1, 42 + [ASN1_OP_END_SEQ_OF_ACT] = 1 + 1 + 1, 43 + [ASN1_OP_END_SET_ACT] = 1 + 1, 44 + [ASN1_OP_END_SET_OF_ACT] = 1 + 1 + 1, 45 + }; 46 + 47 + /* 48 + * Find the length of an indefinite length object 49 + * @data: The data buffer 50 + * @datalen: The end of the innermost containing element in the buffer 51 + * @_dp: The data parse cursor (updated before returning) 52 + * @_len: Where to return the size of the element. 53 + * @_errmsg: Where to return a pointer to an error message on error 54 + */ 55 + static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen, 56 + size_t *_dp, size_t *_len, 57 + const char **_errmsg) 58 + { 59 + unsigned char tag, tmp; 60 + size_t dp = *_dp, len, n; 61 + int indef_level = 1; 62 + 63 + next_tag: 64 + if (unlikely(datalen - dp < 2)) { 65 + if (datalen == dp) 66 + goto missing_eoc; 67 + goto data_overrun_error; 68 + } 69 + 70 + /* Extract a tag from the data */ 71 + tag = data[dp++]; 72 + if (tag == 0) { 73 + /* It appears to be an EOC. */ 74 + if (data[dp++] != 0) 75 + goto invalid_eoc; 76 + if (--indef_level <= 0) { 77 + *_len = dp - *_dp; 78 + *_dp = dp; 79 + return 0; 80 + } 81 + goto next_tag; 82 + } 83 + 84 + if (unlikely((tag & 0x1f) == 0x1f)) { 85 + do { 86 + if (unlikely(datalen - dp < 2)) 87 + goto data_overrun_error; 88 + tmp = data[dp++]; 89 + } while (tmp & 0x80); 90 + } 91 + 92 + /* Extract the length */ 93 + len = data[dp++]; 94 + if (len < 0x7f) { 95 + dp += len; 96 + goto next_tag; 97 + } 98 + 99 + if (unlikely(len == 0x80)) { 100 + /* Indefinite length */ 101 + if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5)) 102 + goto indefinite_len_primitive; 103 + indef_level++; 104 + goto next_tag; 105 + } 106 + 107 + n = len - 0x80; 108 + if (unlikely(n > sizeof(size_t) - 1)) 109 + goto length_too_long; 110 + if (unlikely(n > datalen - dp)) 111 + goto data_overrun_error; 112 + for (len = 0; n > 0; n--) { 113 + len <<= 8; 114 + len |= data[dp++]; 115 + } 116 + dp += len; 117 + goto next_tag; 118 + 119 + length_too_long: 120 + *_errmsg = "Unsupported length"; 121 + goto error; 122 + indefinite_len_primitive: 123 + *_errmsg = "Indefinite len primitive not permitted"; 124 + goto error; 125 + invalid_eoc: 126 + *_errmsg = "Invalid length EOC"; 127 + goto error; 128 + data_overrun_error: 129 + *_errmsg = "Data overrun error"; 130 + goto error; 131 + missing_eoc: 132 + *_errmsg = "Missing EOC in indefinite len cons"; 133 + error: 134 + *_dp = dp; 135 + return -1; 136 + } 137 + 138 + /** 139 + * asn1_ber_decoder - Decoder BER/DER/CER ASN.1 according to pattern 140 + * @decoder: The decoder definition (produced by asn1_compiler) 141 + * @context: The caller's context (to be passed to the action functions) 142 + * @data: The encoded data 143 + * @datasize: The size of the encoded data 144 + * 145 + * Decode BER/DER/CER encoded ASN.1 data according to a bytecode pattern 146 + * produced by asn1_compiler. Action functions are called on marked tags to 147 + * allow the caller to retrieve significant data. 148 + * 149 + * LIMITATIONS: 150 + * 151 + * To keep down the amount of stack used by this function, the following limits 152 + * have been imposed: 153 + * 154 + * (1) This won't handle datalen > 65535 without increasing the size of the 155 + * cons stack elements and length_too_long checking. 156 + * 157 + * (2) The stack of constructed types is 10 deep. If the depth of non-leaf 158 + * constructed types exceeds this, the decode will fail. 159 + * 160 + * (3) The SET type (not the SET OF type) isn't really supported as tracking 161 + * what members of the set have been seen is a pain. 162 + */ 163 + int asn1_ber_decoder(const struct asn1_decoder *decoder, 164 + void *context, 165 + const unsigned char *data, 166 + size_t datalen) 167 + { 168 + const unsigned char *machine = decoder->machine; 169 + const asn1_action_t *actions = decoder->actions; 170 + size_t machlen = decoder->machlen; 171 + enum asn1_opcode op; 172 + unsigned char tag = 0, csp = 0, jsp = 0, optag = 0, hdr = 0; 173 + const char *errmsg; 174 + size_t pc = 0, dp = 0, tdp = 0, len = 0; 175 + int ret; 176 + 177 + unsigned char flags = 0; 178 + #define FLAG_INDEFINITE_LENGTH 0x01 179 + #define FLAG_MATCHED 0x02 180 + #define FLAG_CONS 0x20 /* Corresponds to CONS bit in the opcode tag 181 + * - ie. whether or not we are going to parse 182 + * a compound type. 183 + */ 184 + 185 + #define NR_CONS_STACK 10 186 + unsigned short cons_dp_stack[NR_CONS_STACK]; 187 + unsigned short cons_datalen_stack[NR_CONS_STACK]; 188 + unsigned char cons_hdrlen_stack[NR_CONS_STACK]; 189 + #define NR_JUMP_STACK 10 190 + unsigned char jump_stack[NR_JUMP_STACK]; 191 + 192 + if (datalen > 65535) 193 + return -EMSGSIZE; 194 + 195 + next_op: 196 + pr_debug("next_op: pc=\e[32m%zu\e[m/%zu dp=\e[33m%zu\e[m/%zu C=%d J=%d\n", 197 + pc, machlen, dp, datalen, csp, jsp); 198 + if (unlikely(pc >= machlen)) 199 + goto machine_overrun_error; 200 + op = machine[pc]; 201 + if (unlikely(pc + asn1_op_lengths[op] > machlen)) 202 + goto machine_overrun_error; 203 + 204 + /* If this command is meant to match a tag, then do that before 205 + * evaluating the command. 206 + */ 207 + if (op <= ASN1_OP__MATCHES_TAG) { 208 + unsigned char tmp; 209 + 210 + /* Skip conditional matches if possible */ 211 + if ((op & ASN1_OP_MATCH__COND && 212 + flags & FLAG_MATCHED) || 213 + dp == datalen) { 214 + pc += asn1_op_lengths[op]; 215 + goto next_op; 216 + } 217 + 218 + flags = 0; 219 + hdr = 2; 220 + 221 + /* Extract a tag from the data */ 222 + if (unlikely(dp >= datalen - 1)) 223 + goto data_overrun_error; 224 + tag = data[dp++]; 225 + if (unlikely((tag & 0x1f) == 0x1f)) 226 + goto long_tag_not_supported; 227 + 228 + if (op & ASN1_OP_MATCH__ANY) { 229 + pr_debug("- any %02x\n", tag); 230 + } else { 231 + /* Extract the tag from the machine 232 + * - Either CONS or PRIM are permitted in the data if 233 + * CONS is not set in the op stream, otherwise CONS 234 + * is mandatory. 235 + */ 236 + optag = machine[pc + 1]; 237 + flags |= optag & FLAG_CONS; 238 + 239 + /* Determine whether the tag matched */ 240 + tmp = optag ^ tag; 241 + tmp &= ~(optag & ASN1_CONS_BIT); 242 + pr_debug("- match? %02x %02x %02x\n", tag, optag, tmp); 243 + if (tmp != 0) { 244 + /* All odd-numbered tags are MATCH_OR_SKIP. */ 245 + if (op & ASN1_OP_MATCH__SKIP) { 246 + pc += asn1_op_lengths[op]; 247 + dp--; 248 + goto next_op; 249 + } 250 + goto tag_mismatch; 251 + } 252 + } 253 + flags |= FLAG_MATCHED; 254 + 255 + len = data[dp++]; 256 + if (len > 0x7f) { 257 + if (unlikely(len == 0x80)) { 258 + /* Indefinite length */ 259 + if (unlikely(!(tag & ASN1_CONS_BIT))) 260 + goto indefinite_len_primitive; 261 + flags |= FLAG_INDEFINITE_LENGTH; 262 + if (unlikely(2 > datalen - dp)) 263 + goto data_overrun_error; 264 + } else { 265 + int n = len - 0x80; 266 + if (unlikely(n > 2)) 267 + goto length_too_long; 268 + if (unlikely(dp >= datalen - n)) 269 + goto data_overrun_error; 270 + hdr += n; 271 + for (len = 0; n > 0; n--) { 272 + len <<= 8; 273 + len |= data[dp++]; 274 + } 275 + if (unlikely(len > datalen - dp)) 276 + goto data_overrun_error; 277 + } 278 + } 279 + 280 + if (flags & FLAG_CONS) { 281 + /* For expected compound forms, we stack the positions 282 + * of the start and end of the data. 283 + */ 284 + if (unlikely(csp >= NR_CONS_STACK)) 285 + goto cons_stack_overflow; 286 + cons_dp_stack[csp] = dp; 287 + cons_hdrlen_stack[csp] = hdr; 288 + if (!(flags & FLAG_INDEFINITE_LENGTH)) { 289 + cons_datalen_stack[csp] = datalen; 290 + datalen = dp + len; 291 + } else { 292 + cons_datalen_stack[csp] = 0; 293 + } 294 + csp++; 295 + } 296 + 297 + pr_debug("- TAG: %02x %zu%s\n", 298 + tag, len, flags & FLAG_CONS ? " CONS" : ""); 299 + tdp = dp; 300 + } 301 + 302 + /* Decide how to handle the operation */ 303 + switch (op) { 304 + case ASN1_OP_MATCH_ANY_ACT: 305 + case ASN1_OP_COND_MATCH_ANY_ACT: 306 + ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len); 307 + if (ret < 0) 308 + return ret; 309 + goto skip_data; 310 + 311 + case ASN1_OP_MATCH_ACT: 312 + case ASN1_OP_MATCH_ACT_OR_SKIP: 313 + case ASN1_OP_COND_MATCH_ACT_OR_SKIP: 314 + ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len); 315 + if (ret < 0) 316 + return ret; 317 + goto skip_data; 318 + 319 + case ASN1_OP_MATCH: 320 + case ASN1_OP_MATCH_OR_SKIP: 321 + case ASN1_OP_MATCH_ANY: 322 + case ASN1_OP_COND_MATCH_OR_SKIP: 323 + case ASN1_OP_COND_MATCH_ANY: 324 + skip_data: 325 + if (!(flags & FLAG_CONS)) { 326 + if (flags & FLAG_INDEFINITE_LENGTH) { 327 + ret = asn1_find_indefinite_length( 328 + data, datalen, &dp, &len, &errmsg); 329 + if (ret < 0) 330 + goto error; 331 + } else { 332 + dp += len; 333 + } 334 + pr_debug("- LEAF: %zu\n", len); 335 + } 336 + pc += asn1_op_lengths[op]; 337 + goto next_op; 338 + 339 + case ASN1_OP_MATCH_JUMP: 340 + case ASN1_OP_MATCH_JUMP_OR_SKIP: 341 + case ASN1_OP_COND_MATCH_JUMP_OR_SKIP: 342 + pr_debug("- MATCH_JUMP\n"); 343 + if (unlikely(jsp == NR_JUMP_STACK)) 344 + goto jump_stack_overflow; 345 + jump_stack[jsp++] = pc + asn1_op_lengths[op]; 346 + pc = machine[pc + 2]; 347 + goto next_op; 348 + 349 + case ASN1_OP_COND_FAIL: 350 + if (unlikely(!(flags & FLAG_MATCHED))) 351 + goto tag_mismatch; 352 + pc += asn1_op_lengths[op]; 353 + goto next_op; 354 + 355 + case ASN1_OP_COMPLETE: 356 + if (unlikely(jsp != 0 || csp != 0)) { 357 + pr_err("ASN.1 decoder error: Stacks not empty at completion (%u, %u)\n", 358 + jsp, csp); 359 + return -EBADMSG; 360 + } 361 + return 0; 362 + 363 + case ASN1_OP_END_SET: 364 + case ASN1_OP_END_SET_ACT: 365 + if (unlikely(!(flags & FLAG_MATCHED))) 366 + goto tag_mismatch; 367 + case ASN1_OP_END_SEQ: 368 + case ASN1_OP_END_SET_OF: 369 + case ASN1_OP_END_SEQ_OF: 370 + case ASN1_OP_END_SEQ_ACT: 371 + case ASN1_OP_END_SET_OF_ACT: 372 + case ASN1_OP_END_SEQ_OF_ACT: 373 + if (unlikely(csp <= 0)) 374 + goto cons_stack_underflow; 375 + csp--; 376 + tdp = cons_dp_stack[csp]; 377 + hdr = cons_hdrlen_stack[csp]; 378 + len = datalen; 379 + datalen = cons_datalen_stack[csp]; 380 + pr_debug("- end cons t=%zu dp=%zu l=%zu/%zu\n", 381 + tdp, dp, len, datalen); 382 + if (datalen == 0) { 383 + /* Indefinite length - check for the EOC. */ 384 + datalen = len; 385 + if (unlikely(datalen - dp < 2)) 386 + goto data_overrun_error; 387 + if (data[dp++] != 0) { 388 + if (op & ASN1_OP_END__OF) { 389 + dp--; 390 + csp++; 391 + pc = machine[pc + 1]; 392 + pr_debug("- continue\n"); 393 + goto next_op; 394 + } 395 + goto missing_eoc; 396 + } 397 + if (data[dp++] != 0) 398 + goto invalid_eoc; 399 + len = dp - tdp - 2; 400 + } else { 401 + if (dp < len && (op & ASN1_OP_END__OF)) { 402 + datalen = len; 403 + csp++; 404 + pc = machine[pc + 1]; 405 + pr_debug("- continue\n"); 406 + goto next_op; 407 + } 408 + if (dp != len) 409 + goto cons_length_error; 410 + len -= tdp; 411 + pr_debug("- cons len l=%zu d=%zu\n", len, dp - tdp); 412 + } 413 + 414 + if (op & ASN1_OP_END__ACT) { 415 + unsigned char act; 416 + if (op & ASN1_OP_END__OF) 417 + act = machine[pc + 2]; 418 + else 419 + act = machine[pc + 1]; 420 + ret = actions[act](context, hdr, 0, data + tdp, len); 421 + } 422 + pc += asn1_op_lengths[op]; 423 + goto next_op; 424 + 425 + case ASN1_OP_ACT: 426 + ret = actions[machine[pc + 1]](context, hdr, tag, data + tdp, len); 427 + pc += asn1_op_lengths[op]; 428 + goto next_op; 429 + 430 + case ASN1_OP_RETURN: 431 + if (unlikely(jsp <= 0)) 432 + goto jump_stack_underflow; 433 + pc = jump_stack[--jsp]; 434 + goto next_op; 435 + 436 + default: 437 + break; 438 + } 439 + 440 + /* Shouldn't reach here */ 441 + pr_err("ASN.1 decoder error: Found reserved opcode (%u)\n", op); 442 + return -EBADMSG; 443 + 444 + data_overrun_error: 445 + errmsg = "Data overrun error"; 446 + goto error; 447 + machine_overrun_error: 448 + errmsg = "Machine overrun error"; 449 + goto error; 450 + jump_stack_underflow: 451 + errmsg = "Jump stack underflow"; 452 + goto error; 453 + jump_stack_overflow: 454 + errmsg = "Jump stack overflow"; 455 + goto error; 456 + cons_stack_underflow: 457 + errmsg = "Cons stack underflow"; 458 + goto error; 459 + cons_stack_overflow: 460 + errmsg = "Cons stack overflow"; 461 + goto error; 462 + cons_length_error: 463 + errmsg = "Cons length error"; 464 + goto error; 465 + missing_eoc: 466 + errmsg = "Missing EOC in indefinite len cons"; 467 + goto error; 468 + invalid_eoc: 469 + errmsg = "Invalid length EOC"; 470 + goto error; 471 + length_too_long: 472 + errmsg = "Unsupported length"; 473 + goto error; 474 + indefinite_len_primitive: 475 + errmsg = "Indefinite len primitive not permitted"; 476 + goto error; 477 + tag_mismatch: 478 + errmsg = "Unexpected tag"; 479 + goto error; 480 + long_tag_not_supported: 481 + errmsg = "Long tag not supported"; 482 + error: 483 + pr_debug("\nASN1: %s [m=%zu d=%zu ot=%02x t=%02x l=%zu]\n", 484 + errmsg, pc, dp, optag, tag, len); 485 + return -EBADMSG; 486 + } 487 + EXPORT_SYMBOL_GPL(asn1_ber_decoder);
+209
lib/build_OID_registry
··· 1 + #!/usr/bin/perl -w 2 + # 3 + # Build a static ASN.1 Object Identified (OID) registry 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 + use strict; 15 + 16 + my @names = (); 17 + my @oids = (); 18 + 19 + if ($#ARGV != 1) { 20 + print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n"; 21 + exit(2); 22 + } 23 + 24 + # 25 + # Open the file to read from 26 + # 27 + open IN_FILE, "<$ARGV[0]" || die; 28 + while (<IN_FILE>) { 29 + chomp; 30 + if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) { 31 + push @names, $1; 32 + push @oids, $2; 33 + } 34 + } 35 + close IN_FILE || die; 36 + 37 + # 38 + # Open the files to write into 39 + # 40 + open C_FILE, ">$ARGV[1]" or die; 41 + print C_FILE "/*\n"; 42 + print C_FILE " * Automatically generated by ", $0, ". Do not edit\n"; 43 + print C_FILE " */\n"; 44 + 45 + # 46 + # Split the data up into separate lists and also determine the lengths of the 47 + # encoded data arrays. 48 + # 49 + my @indices = (); 50 + my @lengths = (); 51 + my $total_length = 0; 52 + 53 + print "Compiling ", $#names + 1, " OIDs\n"; 54 + 55 + for (my $i = 0; $i <= $#names; $i++) { 56 + my $name = $names[$i]; 57 + my $oid = $oids[$i]; 58 + 59 + my @components = split(/[.]/, $oid); 60 + 61 + # Determine the encoded length of this OID 62 + my $size = $#components; 63 + for (my $loop = 2; $loop <= $#components; $loop++) { 64 + my $c = $components[$loop]; 65 + 66 + # We will base128 encode the number 67 + my $tmp = ($c == 0) ? 0 : int(log($c)/log(2)); 68 + $tmp = int($tmp / 7); 69 + $size += $tmp; 70 + } 71 + push @lengths, $size; 72 + push @indices, $total_length; 73 + $total_length += $size; 74 + } 75 + 76 + # 77 + # Emit the look-up-by-OID index table 78 + # 79 + print C_FILE "\n"; 80 + if ($total_length <= 255) { 81 + print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n"; 82 + } else { 83 + print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n"; 84 + } 85 + for (my $i = 0; $i <= $#names; $i++) { 86 + print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n" 87 + } 88 + print C_FILE "\t[OID__NR] = ", $total_length, "\n"; 89 + print C_FILE "};\n"; 90 + 91 + # 92 + # Encode the OIDs 93 + # 94 + my @encoded_oids = (); 95 + 96 + for (my $i = 0; $i <= $#names; $i++) { 97 + my @octets = (); 98 + 99 + my @components = split(/[.]/, $oids[$i]); 100 + 101 + push @octets, $components[0] * 40 + $components[1]; 102 + 103 + for (my $loop = 2; $loop <= $#components; $loop++) { 104 + my $c = $components[$loop]; 105 + 106 + # Base128 encode the number 107 + my $tmp = ($c == 0) ? 0 : int(log($c)/log(2)); 108 + $tmp = int($tmp / 7); 109 + 110 + for (; $tmp > 0; $tmp--) { 111 + push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80; 112 + } 113 + push @octets, $c & 0x7f; 114 + } 115 + 116 + push @encoded_oids, \@octets; 117 + } 118 + 119 + # 120 + # Create a hash value for each OID 121 + # 122 + my @hash_values = (); 123 + for (my $i = 0; $i <= $#names; $i++) { 124 + my @octets = @{$encoded_oids[$i]}; 125 + 126 + my $hash = $#octets; 127 + foreach (@octets) { 128 + $hash += $_ * 33; 129 + } 130 + 131 + $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash); 132 + 133 + push @hash_values, $hash & 0xff; 134 + } 135 + 136 + # 137 + # Emit the OID data 138 + # 139 + print C_FILE "\n"; 140 + print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n"; 141 + for (my $i = 0; $i <= $#names; $i++) { 142 + my @octets = @{$encoded_oids[$i]}; 143 + print C_FILE "\t"; 144 + print C_FILE $_, ", " foreach (@octets); 145 + print C_FILE "\t// ", $names[$i]; 146 + print C_FILE "\n"; 147 + } 148 + print C_FILE "};\n"; 149 + 150 + # 151 + # Build the search index table (ordered by length then hash then content) 152 + # 153 + my @index_table = ( 0 .. $#names ); 154 + 155 + @index_table = sort { 156 + my @octets_a = @{$encoded_oids[$a]}; 157 + my @octets_b = @{$encoded_oids[$b]}; 158 + 159 + return $hash_values[$a] <=> $hash_values[$b] 160 + if ($hash_values[$a] != $hash_values[$b]); 161 + return $#octets_a <=> $#octets_b 162 + if ($#octets_a != $#octets_b); 163 + for (my $i = $#octets_a; $i >= 0; $i--) { 164 + return $octets_a[$i] <=> $octets_b[$i] 165 + if ($octets_a[$i] != $octets_b[$i]); 166 + } 167 + return 0; 168 + 169 + } @index_table; 170 + 171 + # 172 + # Emit the search index and hash value table 173 + # 174 + print C_FILE "\n"; 175 + print C_FILE "static const struct {\n"; 176 + print C_FILE "\tunsigned char hash;\n"; 177 + if ($#names <= 255) { 178 + print C_FILE "\tenum OID oid : 8;\n"; 179 + } else { 180 + print C_FILE "\tenum OID oid : 16;\n"; 181 + } 182 + print C_FILE "} oid_search_table[OID__NR] = {\n"; 183 + for (my $i = 0; $i <= $#names; $i++) { 184 + my @octets = @{$encoded_oids[$index_table[$i]]}; 185 + printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ", 186 + $i, 187 + $hash_values[$index_table[$i]], 188 + $names[$index_table[$i]]); 189 + printf C_FILE "%02x", $_ foreach (@octets); 190 + print C_FILE "\n"; 191 + } 192 + print C_FILE "};\n"; 193 + 194 + # 195 + # Emit the OID debugging name table 196 + # 197 + #print C_FILE "\n"; 198 + #print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n"; 199 + # 200 + #for (my $i = 0; $i <= $#names; $i++) { 201 + # print C_FILE "\t\"", $names[$i], "\",\n" 202 + #} 203 + #print C_FILE "\t\"Unknown-OID\"\n"; 204 + #print C_FILE "};\n"; 205 + 206 + # 207 + # Polish off 208 + # 209 + close C_FILE or die;
+1
lib/mpi/Makefile
··· 14 14 generic_mpih-add1.o \ 15 15 mpicoder.o \ 16 16 mpi-bit.o \ 17 + mpi-cmp.o \ 17 18 mpih-cmp.o \ 18 19 mpih-div.o \ 19 20 mpih-mul.o \
+2 -136
lib/mpi/longlong.h
··· 19 19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 20 20 * MA 02111-1307, USA. */ 21 21 22 + #include <asm-generic/bitops/count_zeros.h> 23 + 22 24 /* You have to define the following before including this file: 23 25 * 24 26 * UWtype -- An unsigned type, default type for operations (typically a "word") ··· 148 146 : "1" ((USItype)(n1)), \ 149 147 "r" ((USItype)(n0)), \ 150 148 "r" ((USItype)(d))) 151 - 152 - #define count_leading_zeros(count, x) \ 153 - __asm__ ("clz %0,%1" \ 154 - : "=r" ((USItype)(count)) \ 155 - : "r" ((USItype)(x))) 156 - #define COUNT_LEADING_ZEROS_0 32 157 149 #endif /* __a29k__ */ 158 150 159 151 #if defined(__alpha) && W_TYPE_SIZE == 64 ··· 294 298 : "1" ((USItype)(nh)), \ 295 299 "0" ((USItype)(nl)), \ 296 300 "g" ((USItype)(d))) 297 - #define count_leading_zeros(count, x) \ 298 - __asm__ ("bsch/1 %1,%0" \ 299 - : "=g" (count) \ 300 - : "g" ((USItype)(x)), \ 301 - "0" ((USItype)0)) 302 301 #endif 303 302 304 303 /*************************************** ··· 345 354 } while (0) 346 355 extern USItype __udiv_qrnnd(); 347 356 #endif /* LONGLONG_STANDALONE */ 348 - #define count_leading_zeros(count, x) \ 349 - do { \ 350 - USItype __tmp; \ 351 - __asm__ ( \ 352 - "ldi 1,%0\n" \ 353 - "extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ 354 - "extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \ 355 - "ldo 16(%0),%0 ; Yes. Perform add.\n" \ 356 - "extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ 357 - "extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \ 358 - "ldo 8(%0),%0 ; Yes. Perform add.\n" \ 359 - "extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ 360 - "extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \ 361 - "ldo 4(%0),%0 ; Yes. Perform add.\n" \ 362 - "extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ 363 - "extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \ 364 - "ldo 2(%0),%0 ; Yes. Perform add.\n" \ 365 - "extru %1,30,1,%1 ; Extract bit 1.\n" \ 366 - "sub %0,%1,%0 ; Subtract it. " \ 367 - : "=r" (count), "=r" (__tmp) : "1" (x)); \ 368 - } while (0) 369 357 #endif /* hppa */ 370 358 371 359 /*************************************** ··· 427 457 : "0" ((USItype)(n0)), \ 428 458 "1" ((USItype)(n1)), \ 429 459 "rm" ((USItype)(d))) 430 - #define count_leading_zeros(count, x) \ 431 - do { \ 432 - USItype __cbtmp; \ 433 - __asm__ ("bsrl %1,%0" \ 434 - : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ 435 - (count) = __cbtmp ^ 31; \ 436 - } while (0) 437 - #define count_trailing_zeros(count, x) \ 438 - __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) 439 460 #ifndef UMUL_TIME 440 461 #define UMUL_TIME 40 441 462 #endif ··· 497 536 "dI" ((USItype)(d))); \ 498 537 (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ 499 538 } while (0) 500 - #define count_leading_zeros(count, x) \ 501 - do { \ 502 - USItype __cbtmp; \ 503 - __asm__ ("scanbit %1,%0" \ 504 - : "=r" (__cbtmp) \ 505 - : "r" ((USItype)(x))); \ 506 - (count) = __cbtmp ^ 31; \ 507 - } while (0) 508 - #define COUNT_LEADING_ZEROS_0 (-32) /* sic */ 509 539 #if defined(__i960mx) /* what is the proper symbol to test??? */ 510 540 #define rshift_rhlc(r, h, l, c) \ 511 541 do { \ ··· 555 603 : "0" ((USItype)(n0)), \ 556 604 "1" ((USItype)(n1)), \ 557 605 "dmi" ((USItype)(d))) 558 - #define count_leading_zeros(count, x) \ 559 - __asm__ ("bfffo %1{%b2:%b2},%0" \ 560 - : "=d" ((USItype)(count)) \ 561 - : "od" ((USItype)(x)), "n" (0)) 562 - #define COUNT_LEADING_ZEROS_0 32 563 606 #else /* not mc68020 */ 564 607 #define umul_ppmm(xh, xl, a, b) \ 565 608 do { USItype __umul_tmp1, __umul_tmp2; \ ··· 611 664 "rJ" ((USItype)(bh)), \ 612 665 "rJ" ((USItype)(al)), \ 613 666 "rJ" ((USItype)(bl))) 614 - #define count_leading_zeros(count, x) \ 615 - do { \ 616 - USItype __cbtmp; \ 617 - __asm__ ("ff1 %0,%1" \ 618 - : "=r" (__cbtmp) \ 619 - : "r" ((USItype)(x))); \ 620 - (count) = __cbtmp ^ 31; \ 621 - } while (0) 622 - #define COUNT_LEADING_ZEROS_0 63 /* sic */ 623 667 #if defined(__m88110__) 624 668 #define umul_ppmm(wh, wl, u, v) \ 625 669 do { \ ··· 717 779 : "0" (__xx.__ll), \ 718 780 "g" ((USItype)(d))); \ 719 781 (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) 720 - #define count_trailing_zeros(count, x) \ 721 - do { \ 722 - __asm__("ffsd %2,%0" \ 723 - : "=r"((USItype) (count)) \ 724 - : "0"((USItype) 0), "r"((USItype) (x))); \ 725 - } while (0) 726 782 #endif /* __ns32000__ */ 727 783 728 784 /*************************************** ··· 787 855 "rI" ((USItype)(al)), \ 788 856 "r" ((USItype)(bl))); \ 789 857 } while (0) 790 - #define count_leading_zeros(count, x) \ 791 - __asm__ ("{cntlz|cntlzw} %0,%1" \ 792 - : "=r" ((USItype)(count)) \ 793 - : "r" ((USItype)(x))) 794 - #define COUNT_LEADING_ZEROS_0 32 795 858 #if defined(_ARCH_PPC) 796 859 #define umul_ppmm(ph, pl, m0, m1) \ 797 860 do { \ ··· 928 1001 } while (0) 929 1002 #define UMUL_TIME 20 930 1003 #define UDIV_TIME 200 931 - #define count_leading_zeros(count, x) \ 932 - do { \ 933 - if ((x) >= 0x10000) \ 934 - __asm__ ("clz %0,%1" \ 935 - : "=r" ((USItype)(count)) \ 936 - : "r" ((USItype)(x) >> 16)); \ 937 - else { \ 938 - __asm__ ("clz %0,%1" \ 939 - : "=r" ((USItype)(count)) \ 940 - : "r" ((USItype)(x))); \ 941 - (count) += 16; \ 942 - } \ 943 - } while (0) 944 1004 #endif /* RT/ROMP */ 945 1005 946 1006 /*************************************** ··· 1056 1142 "rI" ((USItype)(d)) \ 1057 1143 : "%g1" __AND_CLOBBER_CC) 1058 1144 #define UDIV_TIME 37 1059 - #define count_leading_zeros(count, x) \ 1060 - __asm__ ("scan %1,0,%0" \ 1061 - : "=r" ((USItype)(x)) \ 1062 - : "r" ((USItype)(count))) 1063 - /* Early sparclites return 63 for an argument of 0, but they warn that future 1064 - implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 1065 - undefined. */ 1066 1145 #endif /* __sparclite__ */ 1067 1146 #endif /* __sparc_v8__ */ 1068 1147 /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ ··· 1359 1452 #if !defined(udiv_qrnnd) 1360 1453 #define UDIV_NEEDS_NORMALIZATION 1 1361 1454 #define udiv_qrnnd __udiv_qrnnd_c 1362 - #endif 1363 - 1364 - #undef count_leading_zeros 1365 - #if !defined(count_leading_zeros) 1366 - extern 1367 - #ifdef __STDC__ 1368 - const 1369 - #endif 1370 - unsigned char __clz_tab[]; 1371 - #define count_leading_zeros(count, x) \ 1372 - do { \ 1373 - UWtype __xr = (x); \ 1374 - UWtype __a; \ 1375 - \ 1376 - if (W_TYPE_SIZE <= 32) { \ 1377 - __a = __xr < ((UWtype) 1 << 2*__BITS4) \ 1378 - ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \ 1379 - : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 1380 - } \ 1381 - else { \ 1382 - for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ 1383 - if (((__xr >> __a) & 0xff) != 0) \ 1384 - break; \ 1385 - } \ 1386 - \ 1387 - (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ 1388 - } while (0) 1389 - /* This version gives a well-defined value for zero. */ 1390 - #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE 1391 - #endif 1392 - 1393 - #if !defined(count_trailing_zeros) 1394 - /* Define count_trailing_zeros using count_leading_zeros. The latter might be 1395 - defined in asm, but if it is not, the C version above is good enough. */ 1396 - #define count_trailing_zeros(count, x) \ 1397 - do { \ 1398 - UWtype __ctz_x = (x); \ 1399 - UWtype __ctz_c; \ 1400 - count_leading_zeros(__ctz_c, __ctz_x & -__ctz_x); \ 1401 - (count) = W_TYPE_SIZE - 1 - __ctz_c; \ 1402 - } while (0) 1403 1455 #endif 1404 1456 1405 1457 #ifndef UDIV_NEEDS_NORMALIZATION
+1 -1
lib/mpi/mpi-bit.c
··· 45 45 if (a->nlimbs) { 46 46 mpi_limb_t alimb = a->d[a->nlimbs - 1]; 47 47 if (alimb) 48 - count_leading_zeros(n, alimb); 48 + n = count_leading_zeros(alimb); 49 49 else 50 50 n = BITS_PER_MPI_LIMB; 51 51 n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB;
+70
lib/mpi/mpi-cmp.c
··· 1 + /* mpi-cmp.c - MPI functions 2 + * Copyright (C) 1998, 1999 Free Software Foundation, Inc. 3 + * 4 + * This file is part of GnuPG. 5 + * 6 + * GnuPG is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * GnuPG is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 + */ 20 + 21 + #include "mpi-internal.h" 22 + 23 + int mpi_cmp_ui(MPI u, unsigned long v) 24 + { 25 + mpi_limb_t limb = v; 26 + 27 + mpi_normalize(u); 28 + if (!u->nlimbs && !limb) 29 + return 0; 30 + if (u->sign) 31 + return -1; 32 + if (u->nlimbs > 1) 33 + return 1; 34 + 35 + if (u->d[0] == limb) 36 + return 0; 37 + else if (u->d[0] > limb) 38 + return 1; 39 + else 40 + return -1; 41 + } 42 + EXPORT_SYMBOL_GPL(mpi_cmp_ui); 43 + 44 + int mpi_cmp(MPI u, MPI v) 45 + { 46 + mpi_size_t usize, vsize; 47 + int cmp; 48 + 49 + mpi_normalize(u); 50 + mpi_normalize(v); 51 + usize = u->nlimbs; 52 + vsize = v->nlimbs; 53 + if (!u->sign && v->sign) 54 + return 1; 55 + if (u->sign && !v->sign) 56 + return -1; 57 + if (usize != vsize && !u->sign && !v->sign) 58 + return usize - vsize; 59 + if (usize != vsize && u->sign && v->sign) 60 + return vsize + usize; 61 + if (!usize) 62 + return 0; 63 + cmp = mpihelp_cmp(u->d, v->d, usize); 64 + if (!cmp) 65 + return 0; 66 + if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0)) 67 + return 1; 68 + return -1; 69 + } 70 + EXPORT_SYMBOL_GPL(mpi_cmp);
+2 -2
lib/mpi/mpi-pow.c
··· 77 77 mp = mp_marker = mpi_alloc_limb_space(msize); 78 78 if (!mp) 79 79 goto enomem; 80 - count_leading_zeros(mod_shift_cnt, mod->d[msize - 1]); 80 + mod_shift_cnt = count_leading_zeros(mod->d[msize - 1]); 81 81 if (mod_shift_cnt) 82 82 mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt); 83 83 else ··· 169 169 170 170 i = esize - 1; 171 171 e = ep[i]; 172 - count_leading_zeros(c, e); 172 + c = count_leading_zeros(e); 173 173 e = (e << c) << 1; /* shift the exp bits to the left, lose msb */ 174 174 c = BITS_PER_MPI_LIMB - 1 - c; 175 175
+55
lib/mpi/mpicoder.c
··· 18 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 19 */ 20 20 21 + #include <linux/bitops.h> 22 + #include <asm-generic/bitops/count_zeros.h> 21 23 #include "mpi-internal.h" 22 24 23 25 #define MAX_EXTERN_MPI_BITS 16384 26 + 27 + /** 28 + * mpi_read_raw_data - Read a raw byte stream as a positive integer 29 + * @xbuffer: The data to read 30 + * @nbytes: The amount of data to read 31 + */ 32 + MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes) 33 + { 34 + const uint8_t *buffer = xbuffer; 35 + int i, j; 36 + unsigned nbits, nlimbs; 37 + mpi_limb_t a; 38 + MPI val = NULL; 39 + 40 + while (nbytes >= 0 && buffer[0] == 0) { 41 + buffer++; 42 + nbytes--; 43 + } 44 + 45 + nbits = nbytes * 8; 46 + if (nbits > MAX_EXTERN_MPI_BITS) { 47 + pr_info("MPI: mpi too large (%u bits)\n", nbits); 48 + return NULL; 49 + } 50 + if (nbytes > 0) 51 + nbits -= count_leading_zeros(buffer[0]); 52 + else 53 + nbits = 0; 54 + 55 + nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; 56 + val = mpi_alloc(nlimbs); 57 + if (!val) 58 + return NULL; 59 + val->nbits = nbits; 60 + val->sign = 0; 61 + val->nlimbs = nlimbs; 62 + 63 + if (nbytes > 0) { 64 + i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; 65 + i %= BYTES_PER_MPI_LIMB; 66 + for (j = nlimbs; j > 0; j--) { 67 + a = 0; 68 + for (; i < BYTES_PER_MPI_LIMB; i++) { 69 + a <<= 8; 70 + a |= *buffer++; 71 + } 72 + i = 0; 73 + val->d[j - 1] = a; 74 + } 75 + } 76 + return val; 77 + } 78 + EXPORT_SYMBOL_GPL(mpi_read_raw_data); 24 79 25 80 MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) 26 81 {
+170
lib/oid_registry.c
··· 1 + /* ASN.1 Object identifier (OID) registry 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 + #include <linux/export.h> 13 + #include <linux/oid_registry.h> 14 + #include <linux/kernel.h> 15 + #include <linux/errno.h> 16 + #include <linux/bug.h> 17 + #include "oid_registry_data.c" 18 + 19 + /** 20 + * look_up_OID - Find an OID registration for the specified data 21 + * @data: Binary representation of the OID 22 + * @datasize: Size of the binary representation 23 + */ 24 + enum OID look_up_OID(const void *data, size_t datasize) 25 + { 26 + const unsigned char *octets = data; 27 + enum OID oid; 28 + unsigned char xhash; 29 + unsigned i, j, k, hash; 30 + size_t len; 31 + 32 + /* Hash the OID data */ 33 + hash = datasize - 1; 34 + 35 + for (i = 0; i < datasize; i++) 36 + hash += octets[i] * 33; 37 + hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash; 38 + hash &= 0xff; 39 + 40 + /* Binary search the OID registry. OIDs are stored in ascending order 41 + * of hash value then ascending order of size and then in ascending 42 + * order of reverse value. 43 + */ 44 + i = 0; 45 + k = OID__NR; 46 + while (i < k) { 47 + j = (i + k) / 2; 48 + 49 + xhash = oid_search_table[j].hash; 50 + if (xhash > hash) { 51 + k = j; 52 + continue; 53 + } 54 + if (xhash < hash) { 55 + i = j + 1; 56 + continue; 57 + } 58 + 59 + oid = oid_search_table[j].oid; 60 + len = oid_index[oid + 1] - oid_index[oid]; 61 + if (len > datasize) { 62 + k = j; 63 + continue; 64 + } 65 + if (len < datasize) { 66 + i = j + 1; 67 + continue; 68 + } 69 + 70 + /* Variation is most likely to be at the tail end of the 71 + * OID, so do the comparison in reverse. 72 + */ 73 + while (len > 0) { 74 + unsigned char a = oid_data[oid_index[oid] + --len]; 75 + unsigned char b = octets[len]; 76 + if (a > b) { 77 + k = j; 78 + goto next; 79 + } 80 + if (a < b) { 81 + i = j + 1; 82 + goto next; 83 + } 84 + } 85 + return oid; 86 + next: 87 + ; 88 + } 89 + 90 + return OID__NR; 91 + } 92 + EXPORT_SYMBOL_GPL(look_up_OID); 93 + 94 + /* 95 + * sprint_OID - Print an Object Identifier into a buffer 96 + * @data: The encoded OID to print 97 + * @datasize: The size of the encoded OID 98 + * @buffer: The buffer to render into 99 + * @bufsize: The size of the buffer 100 + * 101 + * The OID is rendered into the buffer in "a.b.c.d" format and the number of 102 + * bytes is returned. -EBADMSG is returned if the data could not be intepreted 103 + * and -ENOBUFS if the buffer was too small. 104 + */ 105 + int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) 106 + { 107 + const unsigned char *v = data, *end = v + datasize; 108 + unsigned long num; 109 + unsigned char n; 110 + size_t ret; 111 + int count; 112 + 113 + if (v >= end) 114 + return -EBADMSG; 115 + 116 + n = *v++; 117 + ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40); 118 + buffer += count; 119 + bufsize -= count; 120 + if (bufsize == 0) 121 + return -ENOBUFS; 122 + 123 + while (v < end) { 124 + num = 0; 125 + n = *v++; 126 + if (!(n & 0x80)) { 127 + num = n; 128 + } else { 129 + num = n & 0x7f; 130 + do { 131 + if (v >= end) 132 + return -EBADMSG; 133 + n = *v++; 134 + num <<= 7; 135 + num |= n & 0x7f; 136 + } while (n & 0x80); 137 + } 138 + ret += count = snprintf(buffer, bufsize, ".%lu", num); 139 + buffer += count; 140 + bufsize -= count; 141 + if (bufsize == 0) 142 + return -ENOBUFS; 143 + } 144 + 145 + return ret; 146 + } 147 + EXPORT_SYMBOL_GPL(sprint_oid); 148 + 149 + /** 150 + * sprint_OID - Print an Object Identifier into a buffer 151 + * @oid: The OID to print 152 + * @buffer: The buffer to render into 153 + * @bufsize: The size of the buffer 154 + * 155 + * The OID is rendered into the buffer in "a.b.c.d" format and the number of 156 + * bytes is returned. 157 + */ 158 + int sprint_OID(enum OID oid, char *buffer, size_t bufsize) 159 + { 160 + int ret; 161 + 162 + BUG_ON(oid >= OID__NR); 163 + 164 + ret = sprint_oid(oid_data + oid_index[oid], 165 + oid_index[oid + 1] - oid_index[oid], 166 + buffer, bufsize); 167 + BUG_ON(ret == -EBADMSG); 168 + return ret; 169 + } 170 + EXPORT_SYMBOL_GPL(sprint_OID);
+5 -4
net/ceph/crypto.c
··· 423 423 } 424 424 } 425 425 426 - int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) 426 + int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 427 427 { 428 428 struct ceph_crypto_key *ckey; 429 + size_t datalen = prep->datalen; 429 430 int ret; 430 431 void *p; 431 432 432 433 ret = -EINVAL; 433 - if (datalen <= 0 || datalen > 32767 || !data) 434 + if (datalen <= 0 || datalen > 32767 || !prep->data) 434 435 goto err; 435 436 436 437 ret = key_payload_reserve(key, datalen); ··· 444 443 goto err; 445 444 446 445 /* TODO ceph_crypto_key_decode should really take const input */ 447 - p = (void *)data; 448 - ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); 446 + p = (void *)prep->data; 447 + ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen); 449 448 if (ret < 0) 450 449 goto err_ckey; 451 450
+3 -3
net/dns_resolver/dns_key.c
··· 59 59 * "ip1,ip2,...#foo=bar" 60 60 */ 61 61 static int 62 - dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen) 62 + dns_resolver_instantiate(struct key *key, struct key_preparsed_payload *prep) 63 63 { 64 64 struct user_key_payload *upayload; 65 65 unsigned long derrno; 66 66 int ret; 67 - size_t result_len = 0; 68 - const char *data = _data, *end, *opt; 67 + size_t datalen = prep->datalen, result_len = 0; 68 + const char *data = prep->data, *end, *opt; 69 69 70 70 kenter("%%%d,%s,'%*.*s',%zu", 71 71 key->serial, key->description,
+20 -20
net/rxrpc/ar-key.c
··· 26 26 #include "ar-internal.h" 27 27 28 28 static int rxrpc_vet_description_s(const char *); 29 - static int rxrpc_instantiate(struct key *, const void *, size_t); 30 - static int rxrpc_instantiate_s(struct key *, const void *, size_t); 29 + static int rxrpc_instantiate(struct key *, struct key_preparsed_payload *); 30 + static int rxrpc_instantiate_s(struct key *, struct key_preparsed_payload *); 31 31 static void rxrpc_destroy(struct key *); 32 32 static void rxrpc_destroy_s(struct key *); 33 33 static void rxrpc_describe(const struct key *, struct seq_file *); ··· 678 678 * 679 679 * if no data is provided, then a no-security key is made 680 680 */ 681 - static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) 681 + static int rxrpc_instantiate(struct key *key, struct key_preparsed_payload *prep) 682 682 { 683 683 const struct rxrpc_key_data_v1 *v1; 684 684 struct rxrpc_key_token *token, **pp; ··· 686 686 u32 kver; 687 687 int ret; 688 688 689 - _enter("{%x},,%zu", key_serial(key), datalen); 689 + _enter("{%x},,%zu", key_serial(key), prep->datalen); 690 690 691 691 /* handle a no-security key */ 692 - if (!data && datalen == 0) 692 + if (!prep->data && prep->datalen == 0) 693 693 return 0; 694 694 695 695 /* determine if the XDR payload format is being used */ 696 - if (datalen > 7 * 4) { 697 - ret = rxrpc_instantiate_xdr(key, data, datalen); 696 + if (prep->datalen > 7 * 4) { 697 + ret = rxrpc_instantiate_xdr(key, prep->data, prep->datalen); 698 698 if (ret != -EPROTO) 699 699 return ret; 700 700 } 701 701 702 702 /* get the key interface version number */ 703 703 ret = -EINVAL; 704 - if (datalen <= 4 || !data) 704 + if (prep->datalen <= 4 || !prep->data) 705 705 goto error; 706 - memcpy(&kver, data, sizeof(kver)); 707 - data += sizeof(kver); 708 - datalen -= sizeof(kver); 706 + memcpy(&kver, prep->data, sizeof(kver)); 707 + prep->data += sizeof(kver); 708 + prep->datalen -= sizeof(kver); 709 709 710 710 _debug("KEY I/F VERSION: %u", kver); 711 711 ··· 715 715 716 716 /* deal with a version 1 key */ 717 717 ret = -EINVAL; 718 - if (datalen < sizeof(*v1)) 718 + if (prep->datalen < sizeof(*v1)) 719 719 goto error; 720 720 721 - v1 = data; 722 - if (datalen != sizeof(*v1) + v1->ticket_length) 721 + v1 = prep->data; 722 + if (prep->datalen != sizeof(*v1) + v1->ticket_length) 723 723 goto error; 724 724 725 725 _debug("SCIX: %u", v1->security_index); ··· 784 784 * instantiate a server secret key 785 785 * data should be a pointer to the 8-byte secret key 786 786 */ 787 - static int rxrpc_instantiate_s(struct key *key, const void *data, 788 - size_t datalen) 787 + static int rxrpc_instantiate_s(struct key *key, 788 + struct key_preparsed_payload *prep) 789 789 { 790 790 struct crypto_blkcipher *ci; 791 791 792 - _enter("{%x},,%zu", key_serial(key), datalen); 792 + _enter("{%x},,%zu", key_serial(key), prep->datalen); 793 793 794 - if (datalen != 8) 794 + if (prep->datalen != 8) 795 795 return -EINVAL; 796 796 797 - memcpy(&key->type_data, data, 8); 797 + memcpy(&key->type_data, prep->data, 8); 798 798 799 799 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 800 800 if (IS_ERR(ci)) { ··· 802 802 return PTR_ERR(ci); 803 803 } 804 804 805 - if (crypto_blkcipher_setkey(ci, data, 8) < 0) 805 + if (crypto_blkcipher_setkey(ci, prep->data, 8) < 0) 806 806 BUG(); 807 807 808 808 key->payload.data = ci;
+1
scripts/.gitignore
··· 10 10 recordmcount 11 11 docproc 12 12 sortextable 13 + asn1_compiler
+2
scripts/Makefile
··· 16 16 hostprogs-$(CONFIG_IKCONFIG) += bin2c 17 17 hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount 18 18 hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable 19 + hostprogs-$(CONFIG_ASN1) += asn1_compiler 19 20 20 21 HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include 22 + HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include 21 23 22 24 always := $(hostprogs-y) $(hostprogs-m) 23 25
+11
scripts/Makefile.build
··· 354 354 $(obj)/%.lds: $(src)/%.lds.S FORCE 355 355 $(call if_changed_dep,cpp_lds_S) 356 356 357 + # ASN.1 grammar 358 + # --------------------------------------------------------------------------- 359 + quiet_cmd_asn1_compiler = ASN.1 $@ 360 + cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \ 361 + $(subst .h,.c,$@) $(subst .c,.h,$@) 362 + 363 + .PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h 364 + 365 + $(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler 366 + $(call cmd,asn1_compiler) 367 + 357 368 # Build the compiled-in targets 358 369 # --------------------------------------------------------------------------- 359 370
+76 -1
scripts/Makefile.modpost
··· 14 14 # 3) create one <module>.mod.c file pr. module 15 15 # 4) create one Module.symvers file with CRC for all exported symbols 16 16 # 5) compile all <module>.mod.c files 17 - # 6) final link of the module to a <module.ko> file 17 + # 6) final link of the module to a <module.ko> (or <module.unsigned>) file 18 + # 7) signs the modules to a <module.ko> file 18 19 19 20 # Step 3 is used to place certain information in the module's ELF 20 21 # section, including information such as: ··· 32 31 33 32 # Step 4 is solely used to allow module versioning in external modules, 34 33 # where the CRC of each module is retrieved from the Module.symvers file. 34 + 35 + # Step 7 is dependent on CONFIG_MODULE_SIG being enabled. 35 36 36 37 # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined 37 38 # symbols in the final module linking stage ··· 119 116 targets += $(modules:.ko=.mod.o) 120 117 121 118 # Step 6), final link of the modules 119 + ifneq ($(CONFIG_MODULE_SIG),y) 122 120 quiet_cmd_ld_ko_o = LD [M] $@ 123 121 cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \ 124 122 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ ··· 129 125 $(call if_changed,ld_ko_o) 130 126 131 127 targets += $(modules) 128 + else 129 + quiet_cmd_ld_ko_unsigned_o = LD [M] $@ 130 + cmd_ld_ko_unsigned_o = \ 131 + $(LD) -r $(LDFLAGS) \ 132 + $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ 133 + -o $@ $(filter-out FORCE,$^) \ 134 + $(if $(AFTER_LINK),; $(AFTER_LINK)) 132 135 136 + $(modules:.ko=.ko.unsigned): %.ko.unsigned :%.o %.mod.o FORCE 137 + $(call if_changed,ld_ko_unsigned_o) 138 + 139 + targets += $(modules:.ko=.ko.unsigned) 140 + 141 + # Step 7), sign the modules 142 + MODSECKEY = ./signing_key.priv 143 + MODPUBKEY = ./signing_key.x509 144 + 145 + ifeq ($(wildcard $(MODSECKEY))+$(wildcard $(MODPUBKEY)),$(MODSECKEY)+$(MODPUBKEY)) 146 + ifeq ($(KBUILD_SRC),) 147 + # no O= is being used 148 + SCRIPTS_DIR := scripts 149 + else 150 + SCRIPTS_DIR := $(KBUILD_SRC)/scripts 151 + endif 152 + SIGN_MODULES := 1 153 + else 154 + SIGN_MODULES := 0 155 + endif 156 + 157 + # only sign if it's an in-tree module 158 + ifneq ($(KBUILD_EXTMOD),) 159 + SIGN_MODULES := 0 160 + endif 161 + 162 + # We strip the module as best we can - note that using both strip and eu-strip 163 + # results in a smaller module than using either alone. 164 + EU_STRIP = $(shell which eu-strip || echo true) 165 + 166 + quiet_cmd_sign_ko_stripped_ko_unsigned = STRIP [M] $@ 167 + cmd_sign_ko_stripped_ko_unsigned = \ 168 + cp $< $@ && \ 169 + strip -x -g $@ && \ 170 + $(EU_STRIP) $@ 171 + 172 + ifeq ($(SIGN_MODULES),1) 173 + 174 + quiet_cmd_genkeyid = GENKEYID $@ 175 + cmd_genkeyid = \ 176 + perl $(SCRIPTS_DIR)/x509keyid $< $<.signer $<.keyid 177 + 178 + %.signer %.keyid: % 179 + $(call if_changed,genkeyid) 180 + 181 + KEYRING_DEP := $(MODSECKEY) $(MODPUBKEY) $(MODPUBKEY).signer $(MODPUBKEY).keyid 182 + quiet_cmd_sign_ko_ko_stripped = SIGN [M] $@ 183 + cmd_sign_ko_ko_stripped = \ 184 + sh $(SCRIPTS_DIR)/sign-file $(MODSECKEY) $(MODPUBKEY) $< $@ 185 + else 186 + KEYRING_DEP := 187 + quiet_cmd_sign_ko_ko_unsigned = NO SIGN [M] $@ 188 + cmd_sign_ko_ko_unsigned = \ 189 + cp $< $@ 190 + endif 191 + 192 + $(modules): %.ko :%.ko.stripped $(KEYRING_DEP) FORCE 193 + $(call if_changed,sign_ko_ko_stripped) 194 + 195 + $(patsubst %.ko,%.ko.stripped,$(modules)): %.ko.stripped :%.ko.unsigned FORCE 196 + $(call if_changed,sign_ko_stripped_ko_unsigned) 197 + 198 + targets += $(modules) 199 + endif 133 200 134 201 # Add FORCE to the prequisites of a target to force it to be always rebuilt. 135 202 # ---------------------------------------------------------------------------
+1545
scripts/asn1_compiler.c
··· 1 + /* Simplified ASN.1 notation parser 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 + #include <stdarg.h> 13 + #include <stdio.h> 14 + #include <stdlib.h> 15 + #include <stdint.h> 16 + #include <string.h> 17 + #include <ctype.h> 18 + #include <unistd.h> 19 + #include <fcntl.h> 20 + #include <sys/stat.h> 21 + #include <linux/asn1_ber_bytecode.h> 22 + 23 + enum token_type { 24 + DIRECTIVE_ABSENT, 25 + DIRECTIVE_ALL, 26 + DIRECTIVE_ANY, 27 + DIRECTIVE_APPLICATION, 28 + DIRECTIVE_AUTOMATIC, 29 + DIRECTIVE_BEGIN, 30 + DIRECTIVE_BIT, 31 + DIRECTIVE_BMPString, 32 + DIRECTIVE_BOOLEAN, 33 + DIRECTIVE_BY, 34 + DIRECTIVE_CHARACTER, 35 + DIRECTIVE_CHOICE, 36 + DIRECTIVE_CLASS, 37 + DIRECTIVE_COMPONENT, 38 + DIRECTIVE_COMPONENTS, 39 + DIRECTIVE_CONSTRAINED, 40 + DIRECTIVE_CONTAINING, 41 + DIRECTIVE_DEFAULT, 42 + DIRECTIVE_DEFINED, 43 + DIRECTIVE_DEFINITIONS, 44 + DIRECTIVE_EMBEDDED, 45 + DIRECTIVE_ENCODED, 46 + DIRECTIVE_ENCODING_CONTROL, 47 + DIRECTIVE_END, 48 + DIRECTIVE_ENUMERATED, 49 + DIRECTIVE_EXCEPT, 50 + DIRECTIVE_EXPLICIT, 51 + DIRECTIVE_EXPORTS, 52 + DIRECTIVE_EXTENSIBILITY, 53 + DIRECTIVE_EXTERNAL, 54 + DIRECTIVE_FALSE, 55 + DIRECTIVE_FROM, 56 + DIRECTIVE_GeneralString, 57 + DIRECTIVE_GeneralizedTime, 58 + DIRECTIVE_GraphicString, 59 + DIRECTIVE_IA5String, 60 + DIRECTIVE_IDENTIFIER, 61 + DIRECTIVE_IMPLICIT, 62 + DIRECTIVE_IMPLIED, 63 + DIRECTIVE_IMPORTS, 64 + DIRECTIVE_INCLUDES, 65 + DIRECTIVE_INSTANCE, 66 + DIRECTIVE_INSTRUCTIONS, 67 + DIRECTIVE_INTEGER, 68 + DIRECTIVE_INTERSECTION, 69 + DIRECTIVE_ISO646String, 70 + DIRECTIVE_MAX, 71 + DIRECTIVE_MIN, 72 + DIRECTIVE_MINUS_INFINITY, 73 + DIRECTIVE_NULL, 74 + DIRECTIVE_NumericString, 75 + DIRECTIVE_OBJECT, 76 + DIRECTIVE_OCTET, 77 + DIRECTIVE_OF, 78 + DIRECTIVE_OPTIONAL, 79 + DIRECTIVE_ObjectDescriptor, 80 + DIRECTIVE_PATTERN, 81 + DIRECTIVE_PDV, 82 + DIRECTIVE_PLUS_INFINITY, 83 + DIRECTIVE_PRESENT, 84 + DIRECTIVE_PRIVATE, 85 + DIRECTIVE_PrintableString, 86 + DIRECTIVE_REAL, 87 + DIRECTIVE_RELATIVE_OID, 88 + DIRECTIVE_SEQUENCE, 89 + DIRECTIVE_SET, 90 + DIRECTIVE_SIZE, 91 + DIRECTIVE_STRING, 92 + DIRECTIVE_SYNTAX, 93 + DIRECTIVE_T61String, 94 + DIRECTIVE_TAGS, 95 + DIRECTIVE_TRUE, 96 + DIRECTIVE_TeletexString, 97 + DIRECTIVE_UNION, 98 + DIRECTIVE_UNIQUE, 99 + DIRECTIVE_UNIVERSAL, 100 + DIRECTIVE_UTCTime, 101 + DIRECTIVE_UTF8String, 102 + DIRECTIVE_UniversalString, 103 + DIRECTIVE_VideotexString, 104 + DIRECTIVE_VisibleString, 105 + DIRECTIVE_WITH, 106 + NR__DIRECTIVES, 107 + TOKEN_ASSIGNMENT = NR__DIRECTIVES, 108 + TOKEN_OPEN_CURLY, 109 + TOKEN_CLOSE_CURLY, 110 + TOKEN_OPEN_SQUARE, 111 + TOKEN_CLOSE_SQUARE, 112 + TOKEN_OPEN_ACTION, 113 + TOKEN_CLOSE_ACTION, 114 + TOKEN_COMMA, 115 + TOKEN_NUMBER, 116 + TOKEN_TYPE_NAME, 117 + TOKEN_ELEMENT_NAME, 118 + NR__TOKENS 119 + }; 120 + 121 + static const unsigned char token_to_tag[NR__TOKENS] = { 122 + /* EOC goes first */ 123 + [DIRECTIVE_BOOLEAN] = ASN1_BOOL, 124 + [DIRECTIVE_INTEGER] = ASN1_INT, 125 + [DIRECTIVE_BIT] = ASN1_BTS, 126 + [DIRECTIVE_OCTET] = ASN1_OTS, 127 + [DIRECTIVE_NULL] = ASN1_NULL, 128 + [DIRECTIVE_OBJECT] = ASN1_OID, 129 + [DIRECTIVE_ObjectDescriptor] = ASN1_ODE, 130 + [DIRECTIVE_EXTERNAL] = ASN1_EXT, 131 + [DIRECTIVE_REAL] = ASN1_REAL, 132 + [DIRECTIVE_ENUMERATED] = ASN1_ENUM, 133 + [DIRECTIVE_EMBEDDED] = 0, 134 + [DIRECTIVE_UTF8String] = ASN1_UTF8STR, 135 + [DIRECTIVE_RELATIVE_OID] = ASN1_RELOID, 136 + /* 14 */ 137 + /* 15 */ 138 + [DIRECTIVE_SEQUENCE] = ASN1_SEQ, 139 + [DIRECTIVE_SET] = ASN1_SET, 140 + [DIRECTIVE_NumericString] = ASN1_NUMSTR, 141 + [DIRECTIVE_PrintableString] = ASN1_PRNSTR, 142 + [DIRECTIVE_T61String] = ASN1_TEXSTR, 143 + [DIRECTIVE_TeletexString] = ASN1_TEXSTR, 144 + [DIRECTIVE_VideotexString] = ASN1_VIDSTR, 145 + [DIRECTIVE_IA5String] = ASN1_IA5STR, 146 + [DIRECTIVE_UTCTime] = ASN1_UNITIM, 147 + [DIRECTIVE_GeneralizedTime] = ASN1_GENTIM, 148 + [DIRECTIVE_GraphicString] = ASN1_GRASTR, 149 + [DIRECTIVE_VisibleString] = ASN1_VISSTR, 150 + [DIRECTIVE_GeneralString] = ASN1_GENSTR, 151 + [DIRECTIVE_UniversalString] = ASN1_UNITIM, 152 + [DIRECTIVE_CHARACTER] = ASN1_CHRSTR, 153 + [DIRECTIVE_BMPString] = ASN1_BMPSTR, 154 + }; 155 + 156 + static const char asn1_classes[4][5] = { 157 + [ASN1_UNIV] = "UNIV", 158 + [ASN1_APPL] = "APPL", 159 + [ASN1_CONT] = "CONT", 160 + [ASN1_PRIV] = "PRIV" 161 + }; 162 + 163 + static const char asn1_methods[2][5] = { 164 + [ASN1_UNIV] = "PRIM", 165 + [ASN1_APPL] = "CONS" 166 + }; 167 + 168 + static const char *const asn1_universal_tags[32] = { 169 + "EOC", 170 + "BOOL", 171 + "INT", 172 + "BTS", 173 + "OTS", 174 + "NULL", 175 + "OID", 176 + "ODE", 177 + "EXT", 178 + "REAL", 179 + "ENUM", 180 + "EPDV", 181 + "UTF8STR", 182 + "RELOID", 183 + NULL, /* 14 */ 184 + NULL, /* 15 */ 185 + "SEQ", 186 + "SET", 187 + "NUMSTR", 188 + "PRNSTR", 189 + "TEXSTR", 190 + "VIDSTR", 191 + "IA5STR", 192 + "UNITIM", 193 + "GENTIM", 194 + "GRASTR", 195 + "VISSTR", 196 + "GENSTR", 197 + "UNISTR", 198 + "CHRSTR", 199 + "BMPSTR", 200 + NULL /* 31 */ 201 + }; 202 + 203 + static const char *filename; 204 + static const char *grammar_name; 205 + static const char *outputname; 206 + static const char *headername; 207 + 208 + static const char *const directives[NR__DIRECTIVES] = { 209 + #define _(X) [DIRECTIVE_##X] = #X 210 + _(ABSENT), 211 + _(ALL), 212 + _(ANY), 213 + _(APPLICATION), 214 + _(AUTOMATIC), 215 + _(BEGIN), 216 + _(BIT), 217 + _(BMPString), 218 + _(BOOLEAN), 219 + _(BY), 220 + _(CHARACTER), 221 + _(CHOICE), 222 + _(CLASS), 223 + _(COMPONENT), 224 + _(COMPONENTS), 225 + _(CONSTRAINED), 226 + _(CONTAINING), 227 + _(DEFAULT), 228 + _(DEFINED), 229 + _(DEFINITIONS), 230 + _(EMBEDDED), 231 + _(ENCODED), 232 + [DIRECTIVE_ENCODING_CONTROL] = "ENCODING-CONTROL", 233 + _(END), 234 + _(ENUMERATED), 235 + _(EXCEPT), 236 + _(EXPLICIT), 237 + _(EXPORTS), 238 + _(EXTENSIBILITY), 239 + _(EXTERNAL), 240 + _(FALSE), 241 + _(FROM), 242 + _(GeneralString), 243 + _(GeneralizedTime), 244 + _(GraphicString), 245 + _(IA5String), 246 + _(IDENTIFIER), 247 + _(IMPLICIT), 248 + _(IMPLIED), 249 + _(IMPORTS), 250 + _(INCLUDES), 251 + _(INSTANCE), 252 + _(INSTRUCTIONS), 253 + _(INTEGER), 254 + _(INTERSECTION), 255 + _(ISO646String), 256 + _(MAX), 257 + _(MIN), 258 + [DIRECTIVE_MINUS_INFINITY] = "MINUS-INFINITY", 259 + [DIRECTIVE_NULL] = "NULL", 260 + _(NumericString), 261 + _(OBJECT), 262 + _(OCTET), 263 + _(OF), 264 + _(OPTIONAL), 265 + _(ObjectDescriptor), 266 + _(PATTERN), 267 + _(PDV), 268 + [DIRECTIVE_PLUS_INFINITY] = "PLUS-INFINITY", 269 + _(PRESENT), 270 + _(PRIVATE), 271 + _(PrintableString), 272 + _(REAL), 273 + [DIRECTIVE_RELATIVE_OID] = "RELATIVE-OID", 274 + _(SEQUENCE), 275 + _(SET), 276 + _(SIZE), 277 + _(STRING), 278 + _(SYNTAX), 279 + _(T61String), 280 + _(TAGS), 281 + _(TRUE), 282 + _(TeletexString), 283 + _(UNION), 284 + _(UNIQUE), 285 + _(UNIVERSAL), 286 + _(UTCTime), 287 + _(UTF8String), 288 + _(UniversalString), 289 + _(VideotexString), 290 + _(VisibleString), 291 + _(WITH) 292 + }; 293 + 294 + struct action { 295 + struct action *next; 296 + unsigned char index; 297 + char name[]; 298 + }; 299 + 300 + static struct action *action_list; 301 + static unsigned nr_actions; 302 + 303 + struct token { 304 + unsigned short line; 305 + enum token_type token_type : 8; 306 + unsigned char size; 307 + struct action *action; 308 + const char *value; 309 + struct type *type; 310 + }; 311 + 312 + static struct token *token_list; 313 + static unsigned nr_tokens; 314 + 315 + static int directive_compare(const void *_key, const void *_pdir) 316 + { 317 + const struct token *token = _key; 318 + const char *const *pdir = _pdir, *dir = *pdir; 319 + size_t dlen, clen; 320 + int val; 321 + 322 + dlen = strlen(dir); 323 + clen = (dlen < token->size) ? dlen : token->size; 324 + 325 + //printf("cmp(%*.*s,%s) = ", 326 + // (int)token->size, (int)token->size, token->value, 327 + // dir); 328 + 329 + val = memcmp(token->value, dir, clen); 330 + if (val != 0) { 331 + //printf("%d [cmp]\n", val); 332 + return val; 333 + } 334 + 335 + if (dlen == token->size) { 336 + //printf("0\n"); 337 + return 0; 338 + } 339 + //printf("%d\n", (int)dlen - (int)token->size); 340 + return dlen - token->size; /* shorter -> negative */ 341 + } 342 + 343 + /* 344 + * Tokenise an ASN.1 grammar 345 + */ 346 + static void tokenise(char *buffer, char *end) 347 + { 348 + struct token *tokens; 349 + char *line, *nl, *p, *q; 350 + unsigned tix, lineno; 351 + 352 + /* Assume we're going to have half as many tokens as we have 353 + * characters 354 + */ 355 + token_list = tokens = calloc((end - buffer) / 2, sizeof(struct token)); 356 + if (!tokens) { 357 + perror(NULL); 358 + exit(1); 359 + } 360 + tix = 0; 361 + 362 + lineno = 0; 363 + while (buffer < end) { 364 + /* First of all, break out a line */ 365 + lineno++; 366 + line = buffer; 367 + nl = memchr(line, '\n', end - buffer); 368 + if (!nl) { 369 + buffer = nl = end; 370 + } else { 371 + buffer = nl + 1; 372 + *nl = '\0'; 373 + } 374 + 375 + /* Remove "--" comments */ 376 + p = line; 377 + next_comment: 378 + while ((p = memchr(p, '-', nl - p))) { 379 + if (p[1] == '-') { 380 + /* Found a comment; see if there's a terminator */ 381 + q = p + 2; 382 + while ((q = memchr(q, '-', nl - q))) { 383 + if (q[1] == '-') { 384 + /* There is - excise the comment */ 385 + q += 2; 386 + memmove(p, q, nl - q); 387 + goto next_comment; 388 + } 389 + q++; 390 + } 391 + *p = '\0'; 392 + nl = p; 393 + break; 394 + } else { 395 + p++; 396 + } 397 + } 398 + 399 + p = line; 400 + while (p < nl) { 401 + /* Skip white space */ 402 + while (p < nl && isspace(*p)) 403 + *(p++) = 0; 404 + if (p >= nl) 405 + break; 406 + 407 + tokens[tix].line = lineno; 408 + tokens[tix].value = p; 409 + 410 + /* Handle string tokens */ 411 + if (isalpha(*p)) { 412 + const char **dir; 413 + 414 + /* Can be a directive, type name or element 415 + * name. Find the end of the name. 416 + */ 417 + q = p + 1; 418 + while (q < nl && (isalnum(*q) || *q == '-' || *q == '_')) 419 + q++; 420 + tokens[tix].size = q - p; 421 + p = q; 422 + 423 + /* If it begins with a lowercase letter then 424 + * it's an element name 425 + */ 426 + if (islower(tokens[tix].value[0])) { 427 + tokens[tix++].token_type = TOKEN_ELEMENT_NAME; 428 + continue; 429 + } 430 + 431 + /* Otherwise we need to search the directive 432 + * table 433 + */ 434 + dir = bsearch(&tokens[tix], directives, 435 + sizeof(directives) / sizeof(directives[1]), 436 + sizeof(directives[1]), 437 + directive_compare); 438 + if (dir) { 439 + tokens[tix++].token_type = dir - directives; 440 + continue; 441 + } 442 + 443 + tokens[tix++].token_type = TOKEN_TYPE_NAME; 444 + continue; 445 + } 446 + 447 + /* Handle numbers */ 448 + if (isdigit(*p)) { 449 + /* Find the end of the number */ 450 + q = p + 1; 451 + while (q < nl && (isdigit(*q))) 452 + q++; 453 + tokens[tix].size = q - p; 454 + p = q; 455 + tokens[tix++].token_type = TOKEN_NUMBER; 456 + continue; 457 + } 458 + 459 + if (nl - p >= 3) { 460 + if (memcmp(p, "::=", 3) == 0) { 461 + p += 3; 462 + tokens[tix].size = 3; 463 + tokens[tix++].token_type = TOKEN_ASSIGNMENT; 464 + continue; 465 + } 466 + } 467 + 468 + if (nl - p >= 2) { 469 + if (memcmp(p, "({", 2) == 0) { 470 + p += 2; 471 + tokens[tix].size = 2; 472 + tokens[tix++].token_type = TOKEN_OPEN_ACTION; 473 + continue; 474 + } 475 + if (memcmp(p, "})", 2) == 0) { 476 + p += 2; 477 + tokens[tix].size = 2; 478 + tokens[tix++].token_type = TOKEN_CLOSE_ACTION; 479 + continue; 480 + } 481 + } 482 + 483 + if (nl - p >= 1) { 484 + tokens[tix].size = 1; 485 + switch (*p) { 486 + case '{': 487 + p += 1; 488 + tokens[tix++].token_type = TOKEN_OPEN_CURLY; 489 + continue; 490 + case '}': 491 + p += 1; 492 + tokens[tix++].token_type = TOKEN_CLOSE_CURLY; 493 + continue; 494 + case '[': 495 + p += 1; 496 + tokens[tix++].token_type = TOKEN_OPEN_SQUARE; 497 + continue; 498 + case ']': 499 + p += 1; 500 + tokens[tix++].token_type = TOKEN_CLOSE_SQUARE; 501 + continue; 502 + case ',': 503 + p += 1; 504 + tokens[tix++].token_type = TOKEN_COMMA; 505 + continue; 506 + default: 507 + break; 508 + } 509 + } 510 + 511 + fprintf(stderr, "%s:%u: Unknown character in grammar: '%c'\n", 512 + filename, lineno, *p); 513 + exit(1); 514 + } 515 + } 516 + 517 + nr_tokens = tix; 518 + printf("Extracted %u tokens\n", nr_tokens); 519 + 520 + #if 0 521 + { 522 + int n; 523 + for (n = 0; n < nr_tokens; n++) 524 + printf("Token %3u: '%*.*s'\n", 525 + n, 526 + (int)token_list[n].size, (int)token_list[n].size, 527 + token_list[n].value); 528 + } 529 + #endif 530 + } 531 + 532 + static void build_type_list(void); 533 + static void parse(void); 534 + static void render(FILE *out, FILE *hdr); 535 + 536 + /* 537 + * 538 + */ 539 + int main(int argc, char **argv) 540 + { 541 + struct stat st; 542 + ssize_t readlen; 543 + FILE *out, *hdr; 544 + char *buffer, *p; 545 + int fd; 546 + 547 + if (argc != 4) { 548 + fprintf(stderr, "Format: %s <grammar-file> <c-file> <hdr-file>\n", 549 + argv[0]); 550 + exit(2); 551 + } 552 + 553 + filename = argv[1]; 554 + outputname = argv[2]; 555 + headername = argv[3]; 556 + 557 + fd = open(filename, O_RDONLY); 558 + if (fd < 0) { 559 + perror(filename); 560 + exit(1); 561 + } 562 + 563 + if (fstat(fd, &st) < 0) { 564 + perror(filename); 565 + exit(1); 566 + } 567 + 568 + if (!(buffer = malloc(st.st_size + 1))) { 569 + perror(NULL); 570 + exit(1); 571 + } 572 + 573 + if ((readlen = read(fd, buffer, st.st_size)) < 0) { 574 + perror(filename); 575 + exit(1); 576 + } 577 + 578 + if (close(fd) < 0) { 579 + perror(filename); 580 + exit(1); 581 + } 582 + 583 + if (readlen != st.st_size) { 584 + fprintf(stderr, "%s: Short read\n", filename); 585 + exit(1); 586 + } 587 + 588 + p = strrchr(argv[1], '/'); 589 + p = p ? p + 1 : argv[1]; 590 + grammar_name = strdup(p); 591 + if (!p) { 592 + perror(NULL); 593 + exit(1); 594 + } 595 + p = strchr(grammar_name, '.'); 596 + if (p) 597 + *p = '\0'; 598 + 599 + buffer[readlen] = 0; 600 + tokenise(buffer, buffer + readlen); 601 + build_type_list(); 602 + parse(); 603 + 604 + out = fopen(outputname, "w"); 605 + if (!out) { 606 + perror(outputname); 607 + exit(1); 608 + } 609 + 610 + hdr = fopen(headername, "w"); 611 + if (!out) { 612 + perror(headername); 613 + exit(1); 614 + } 615 + 616 + render(out, hdr); 617 + 618 + if (fclose(out) < 0) { 619 + perror(outputname); 620 + exit(1); 621 + } 622 + 623 + if (fclose(hdr) < 0) { 624 + perror(headername); 625 + exit(1); 626 + } 627 + 628 + return 0; 629 + } 630 + 631 + enum compound { 632 + NOT_COMPOUND, 633 + SET, 634 + SET_OF, 635 + SEQUENCE, 636 + SEQUENCE_OF, 637 + CHOICE, 638 + ANY, 639 + TYPE_REF, 640 + TAG_OVERRIDE 641 + }; 642 + 643 + struct element { 644 + struct type *type_def; 645 + struct token *name; 646 + struct token *type; 647 + struct action *action; 648 + struct element *children; 649 + struct element *next; 650 + struct element *render_next; 651 + struct element *list_next; 652 + uint8_t n_elements; 653 + enum compound compound : 8; 654 + enum asn1_class class : 8; 655 + enum asn1_method method : 8; 656 + uint8_t tag; 657 + unsigned entry_index; 658 + unsigned flags; 659 + #define ELEMENT_IMPLICIT 0x0001 660 + #define ELEMENT_EXPLICIT 0x0002 661 + #define ELEMENT_MARKED 0x0004 662 + #define ELEMENT_RENDERED 0x0008 663 + #define ELEMENT_SKIPPABLE 0x0010 664 + #define ELEMENT_CONDITIONAL 0x0020 665 + }; 666 + 667 + struct type { 668 + struct token *name; 669 + struct token *def; 670 + struct element *element; 671 + unsigned ref_count; 672 + unsigned flags; 673 + #define TYPE_STOP_MARKER 0x0001 674 + #define TYPE_BEGIN 0x0002 675 + }; 676 + 677 + static struct type *type_list; 678 + static struct type **type_index; 679 + static unsigned nr_types; 680 + 681 + static int type_index_compare(const void *_a, const void *_b) 682 + { 683 + const struct type *const *a = _a, *const *b = _b; 684 + 685 + if ((*a)->name->size != (*b)->name->size) 686 + return (*a)->name->size - (*b)->name->size; 687 + else 688 + return memcmp((*a)->name->value, (*b)->name->value, 689 + (*a)->name->size); 690 + } 691 + 692 + static int type_finder(const void *_key, const void *_ti) 693 + { 694 + const struct token *token = _key; 695 + const struct type *const *ti = _ti; 696 + const struct type *type = *ti; 697 + 698 + if (token->size != type->name->size) 699 + return token->size - type->name->size; 700 + else 701 + return memcmp(token->value, type->name->value, 702 + token->size); 703 + } 704 + 705 + /* 706 + * Build up a list of types and a sorted index to that list. 707 + */ 708 + static void build_type_list(void) 709 + { 710 + struct type *types; 711 + unsigned nr, t, n; 712 + 713 + nr = 0; 714 + for (n = 0; n < nr_tokens - 1; n++) 715 + if (token_list[n + 0].token_type == TOKEN_TYPE_NAME && 716 + token_list[n + 1].token_type == TOKEN_ASSIGNMENT) 717 + nr++; 718 + 719 + if (nr == 0) { 720 + fprintf(stderr, "%s: No defined types\n", filename); 721 + exit(1); 722 + } 723 + 724 + nr_types = nr; 725 + types = type_list = calloc(nr + 1, sizeof(type_list[0])); 726 + if (!type_list) { 727 + perror(NULL); 728 + exit(1); 729 + } 730 + type_index = calloc(nr, sizeof(type_index[0])); 731 + if (!type_index) { 732 + perror(NULL); 733 + exit(1); 734 + } 735 + 736 + t = 0; 737 + types[t].flags |= TYPE_BEGIN; 738 + for (n = 0; n < nr_tokens - 1; n++) { 739 + if (token_list[n + 0].token_type == TOKEN_TYPE_NAME && 740 + token_list[n + 1].token_type == TOKEN_ASSIGNMENT) { 741 + types[t].name = &token_list[n]; 742 + type_index[t] = &types[t]; 743 + t++; 744 + } 745 + } 746 + types[t].name = &token_list[n + 1]; 747 + types[t].flags |= TYPE_STOP_MARKER; 748 + 749 + qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); 750 + 751 + printf("Extracted %u types\n", nr_types); 752 + #if 0 753 + for (n = 0; n < nr_types; n++) { 754 + struct type *type = type_index[n]; 755 + printf("- %*.*s\n", 756 + (int)type->name->size, 757 + (int)type->name->size, 758 + type->name->value); 759 + } 760 + #endif 761 + } 762 + 763 + static struct element *parse_type(struct token **_cursor, struct token *stop, 764 + struct token *name); 765 + 766 + /* 767 + * Parse the token stream 768 + */ 769 + static void parse(void) 770 + { 771 + struct token *cursor; 772 + struct type *type; 773 + 774 + /* Parse one type definition statement at a time */ 775 + type = type_list; 776 + do { 777 + cursor = type->name; 778 + 779 + if (cursor[0].token_type != TOKEN_TYPE_NAME || 780 + cursor[1].token_type != TOKEN_ASSIGNMENT) 781 + abort(); 782 + cursor += 2; 783 + 784 + type->element = parse_type(&cursor, type[1].name, NULL); 785 + type->element->type_def = type; 786 + 787 + if (cursor != type[1].name) { 788 + fprintf(stderr, "%s:%d: Parse error at token '%*.*s'\n", 789 + filename, cursor->line, 790 + (int)cursor->size, (int)cursor->size, cursor->value); 791 + exit(1); 792 + } 793 + 794 + } while (type++, !(type->flags & TYPE_STOP_MARKER)); 795 + 796 + printf("Extracted %u actions\n", nr_actions); 797 + } 798 + 799 + static struct element *element_list; 800 + 801 + static struct element *alloc_elem(struct token *type) 802 + { 803 + struct element *e = calloc(1, sizeof(*e)); 804 + if (!e) { 805 + perror(NULL); 806 + exit(1); 807 + } 808 + e->list_next = element_list; 809 + element_list = e; 810 + return e; 811 + } 812 + 813 + static struct element *parse_compound(struct token **_cursor, struct token *end, 814 + int alternates); 815 + 816 + /* 817 + * Parse one type definition statement 818 + */ 819 + static struct element *parse_type(struct token **_cursor, struct token *end, 820 + struct token *name) 821 + { 822 + struct element *top, *element; 823 + struct action *action, **ppaction; 824 + struct token *cursor = *_cursor; 825 + struct type **ref; 826 + char *p; 827 + int labelled = 0, implicit = 0; 828 + 829 + top = element = alloc_elem(cursor); 830 + element->class = ASN1_UNIV; 831 + element->method = ASN1_PRIM; 832 + element->tag = token_to_tag[cursor->token_type]; 833 + element->name = name; 834 + 835 + /* Extract the tag value if one given */ 836 + if (cursor->token_type == TOKEN_OPEN_SQUARE) { 837 + cursor++; 838 + if (cursor >= end) 839 + goto overrun_error; 840 + switch (cursor->token_type) { 841 + case DIRECTIVE_UNIVERSAL: 842 + element->class = ASN1_UNIV; 843 + cursor++; 844 + break; 845 + case DIRECTIVE_APPLICATION: 846 + element->class = ASN1_APPL; 847 + cursor++; 848 + break; 849 + case TOKEN_NUMBER: 850 + element->class = ASN1_CONT; 851 + break; 852 + case DIRECTIVE_PRIVATE: 853 + element->class = ASN1_PRIV; 854 + cursor++; 855 + break; 856 + default: 857 + fprintf(stderr, "%s:%d: Unrecognised tag class token '%*.*s'\n", 858 + filename, cursor->line, 859 + (int)cursor->size, (int)cursor->size, cursor->value); 860 + exit(1); 861 + } 862 + 863 + if (cursor >= end) 864 + goto overrun_error; 865 + if (cursor->token_type != TOKEN_NUMBER) { 866 + fprintf(stderr, "%s:%d: Missing tag number '%*.*s'\n", 867 + filename, cursor->line, 868 + (int)cursor->size, (int)cursor->size, cursor->value); 869 + exit(1); 870 + } 871 + 872 + element->tag &= ~0x1f; 873 + element->tag |= strtoul(cursor->value, &p, 10); 874 + if (p - cursor->value != cursor->size) 875 + abort(); 876 + cursor++; 877 + 878 + if (cursor >= end) 879 + goto overrun_error; 880 + if (cursor->token_type != TOKEN_CLOSE_SQUARE) { 881 + fprintf(stderr, "%s:%d: Missing closing square bracket '%*.*s'\n", 882 + filename, cursor->line, 883 + (int)cursor->size, (int)cursor->size, cursor->value); 884 + exit(1); 885 + } 886 + cursor++; 887 + if (cursor >= end) 888 + goto overrun_error; 889 + labelled = 1; 890 + } 891 + 892 + /* Handle implicit and explicit markers */ 893 + if (cursor->token_type == DIRECTIVE_IMPLICIT) { 894 + element->flags |= ELEMENT_IMPLICIT; 895 + implicit = 1; 896 + cursor++; 897 + if (cursor >= end) 898 + goto overrun_error; 899 + } else if (cursor->token_type == DIRECTIVE_EXPLICIT) { 900 + element->flags |= ELEMENT_EXPLICIT; 901 + cursor++; 902 + if (cursor >= end) 903 + goto overrun_error; 904 + } 905 + 906 + if (labelled) { 907 + if (!implicit) 908 + element->method |= ASN1_CONS; 909 + element->compound = implicit ? TAG_OVERRIDE : SEQUENCE; 910 + element->children = alloc_elem(cursor); 911 + element = element->children; 912 + element->class = ASN1_UNIV; 913 + element->method = ASN1_PRIM; 914 + element->tag = token_to_tag[cursor->token_type]; 915 + element->name = name; 916 + } 917 + 918 + /* Extract the type we're expecting here */ 919 + element->type = cursor; 920 + switch (cursor->token_type) { 921 + case DIRECTIVE_ANY: 922 + element->compound = ANY; 923 + cursor++; 924 + break; 925 + 926 + case DIRECTIVE_NULL: 927 + case DIRECTIVE_BOOLEAN: 928 + case DIRECTIVE_ENUMERATED: 929 + case DIRECTIVE_INTEGER: 930 + element->compound = NOT_COMPOUND; 931 + cursor++; 932 + break; 933 + 934 + case DIRECTIVE_EXTERNAL: 935 + element->method = ASN1_CONS; 936 + 937 + case DIRECTIVE_BMPString: 938 + case DIRECTIVE_GeneralString: 939 + case DIRECTIVE_GraphicString: 940 + case DIRECTIVE_IA5String: 941 + case DIRECTIVE_ISO646String: 942 + case DIRECTIVE_NumericString: 943 + case DIRECTIVE_PrintableString: 944 + case DIRECTIVE_T61String: 945 + case DIRECTIVE_TeletexString: 946 + case DIRECTIVE_UniversalString: 947 + case DIRECTIVE_UTF8String: 948 + case DIRECTIVE_VideotexString: 949 + case DIRECTIVE_VisibleString: 950 + case DIRECTIVE_ObjectDescriptor: 951 + case DIRECTIVE_GeneralizedTime: 952 + case DIRECTIVE_UTCTime: 953 + element->compound = NOT_COMPOUND; 954 + cursor++; 955 + break; 956 + 957 + case DIRECTIVE_BIT: 958 + case DIRECTIVE_OCTET: 959 + element->compound = NOT_COMPOUND; 960 + cursor++; 961 + if (cursor >= end) 962 + goto overrun_error; 963 + if (cursor->token_type != DIRECTIVE_STRING) 964 + goto parse_error; 965 + cursor++; 966 + break; 967 + 968 + case DIRECTIVE_OBJECT: 969 + element->compound = NOT_COMPOUND; 970 + cursor++; 971 + if (cursor >= end) 972 + goto overrun_error; 973 + if (cursor->token_type != DIRECTIVE_IDENTIFIER) 974 + goto parse_error; 975 + cursor++; 976 + break; 977 + 978 + case TOKEN_TYPE_NAME: 979 + element->compound = TYPE_REF; 980 + ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]), 981 + type_finder); 982 + if (!ref) { 983 + fprintf(stderr, "%s:%d: Type '%*.*s' undefined\n", 984 + filename, cursor->line, 985 + (int)cursor->size, (int)cursor->size, cursor->value); 986 + exit(1); 987 + } 988 + cursor->type = *ref; 989 + (*ref)->ref_count++; 990 + cursor++; 991 + break; 992 + 993 + case DIRECTIVE_CHOICE: 994 + element->compound = CHOICE; 995 + cursor++; 996 + element->children = parse_compound(&cursor, end, 1); 997 + break; 998 + 999 + case DIRECTIVE_SEQUENCE: 1000 + element->compound = SEQUENCE; 1001 + element->method = ASN1_CONS; 1002 + cursor++; 1003 + if (cursor >= end) 1004 + goto overrun_error; 1005 + if (cursor->token_type == DIRECTIVE_OF) { 1006 + element->compound = SEQUENCE_OF; 1007 + cursor++; 1008 + if (cursor >= end) 1009 + goto overrun_error; 1010 + element->children = parse_type(&cursor, end, NULL); 1011 + } else { 1012 + element->children = parse_compound(&cursor, end, 0); 1013 + } 1014 + break; 1015 + 1016 + case DIRECTIVE_SET: 1017 + element->compound = SET; 1018 + element->method = ASN1_CONS; 1019 + cursor++; 1020 + if (cursor >= end) 1021 + goto overrun_error; 1022 + if (cursor->token_type == DIRECTIVE_OF) { 1023 + element->compound = SET_OF; 1024 + cursor++; 1025 + if (cursor >= end) 1026 + goto parse_error; 1027 + element->children = parse_type(&cursor, end, NULL); 1028 + } else { 1029 + element->children = parse_compound(&cursor, end, 1); 1030 + } 1031 + break; 1032 + 1033 + default: 1034 + fprintf(stderr, "%s:%d: Token '%*.*s' does not introduce a type\n", 1035 + filename, cursor->line, 1036 + (int)cursor->size, (int)cursor->size, cursor->value); 1037 + exit(1); 1038 + } 1039 + 1040 + /* Handle elements that are optional */ 1041 + if (cursor < end && (cursor->token_type == DIRECTIVE_OPTIONAL || 1042 + cursor->token_type == DIRECTIVE_DEFAULT) 1043 + ) { 1044 + cursor++; 1045 + top->flags |= ELEMENT_SKIPPABLE; 1046 + } 1047 + 1048 + if (cursor < end && cursor->token_type == TOKEN_OPEN_ACTION) { 1049 + cursor++; 1050 + if (cursor >= end) 1051 + goto overrun_error; 1052 + if (cursor->token_type != TOKEN_ELEMENT_NAME) { 1053 + fprintf(stderr, "%s:%d: Token '%*.*s' is not an action function name\n", 1054 + filename, cursor->line, 1055 + (int)cursor->size, (int)cursor->size, cursor->value); 1056 + exit(1); 1057 + } 1058 + 1059 + action = malloc(sizeof(struct action) + cursor->size + 1); 1060 + if (!action) { 1061 + perror(NULL); 1062 + exit(1); 1063 + } 1064 + action->index = 0; 1065 + memcpy(action->name, cursor->value, cursor->size); 1066 + action->name[cursor->size] = 0; 1067 + 1068 + for (ppaction = &action_list; 1069 + *ppaction; 1070 + ppaction = &(*ppaction)->next 1071 + ) { 1072 + int cmp = strcmp(action->name, (*ppaction)->name); 1073 + if (cmp == 0) { 1074 + free(action); 1075 + action = *ppaction; 1076 + goto found; 1077 + } 1078 + if (cmp < 0) { 1079 + action->next = *ppaction; 1080 + *ppaction = action; 1081 + nr_actions++; 1082 + goto found; 1083 + } 1084 + } 1085 + action->next = NULL; 1086 + *ppaction = action; 1087 + nr_actions++; 1088 + found: 1089 + 1090 + element->action = action; 1091 + cursor->action = action; 1092 + cursor++; 1093 + if (cursor >= end) 1094 + goto overrun_error; 1095 + if (cursor->token_type != TOKEN_CLOSE_ACTION) { 1096 + fprintf(stderr, "%s:%d: Missing close action, got '%*.*s'\n", 1097 + filename, cursor->line, 1098 + (int)cursor->size, (int)cursor->size, cursor->value); 1099 + exit(1); 1100 + } 1101 + cursor++; 1102 + } 1103 + 1104 + *_cursor = cursor; 1105 + return top; 1106 + 1107 + parse_error: 1108 + fprintf(stderr, "%s:%d: Unexpected token '%*.*s'\n", 1109 + filename, cursor->line, 1110 + (int)cursor->size, (int)cursor->size, cursor->value); 1111 + exit(1); 1112 + 1113 + overrun_error: 1114 + fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename); 1115 + exit(1); 1116 + } 1117 + 1118 + /* 1119 + * Parse a compound type list 1120 + */ 1121 + static struct element *parse_compound(struct token **_cursor, struct token *end, 1122 + int alternates) 1123 + { 1124 + struct element *children, **child_p = &children, *element; 1125 + struct token *cursor = *_cursor, *name; 1126 + 1127 + if (cursor->token_type != TOKEN_OPEN_CURLY) { 1128 + fprintf(stderr, "%s:%d: Expected compound to start with brace not '%*.*s'\n", 1129 + filename, cursor->line, 1130 + (int)cursor->size, (int)cursor->size, cursor->value); 1131 + exit(1); 1132 + } 1133 + cursor++; 1134 + if (cursor >= end) 1135 + goto overrun_error; 1136 + 1137 + if (cursor->token_type == TOKEN_OPEN_CURLY) { 1138 + fprintf(stderr, "%s:%d: Empty compound\n", 1139 + filename, cursor->line); 1140 + exit(1); 1141 + } 1142 + 1143 + for (;;) { 1144 + name = NULL; 1145 + if (cursor->token_type == TOKEN_ELEMENT_NAME) { 1146 + name = cursor; 1147 + cursor++; 1148 + if (cursor >= end) 1149 + goto overrun_error; 1150 + } 1151 + 1152 + element = parse_type(&cursor, end, name); 1153 + if (alternates) 1154 + element->flags |= ELEMENT_SKIPPABLE | ELEMENT_CONDITIONAL; 1155 + 1156 + *child_p = element; 1157 + child_p = &element->next; 1158 + 1159 + if (cursor >= end) 1160 + goto overrun_error; 1161 + if (cursor->token_type != TOKEN_COMMA) 1162 + break; 1163 + cursor++; 1164 + if (cursor >= end) 1165 + goto overrun_error; 1166 + } 1167 + 1168 + children->flags &= ~ELEMENT_CONDITIONAL; 1169 + 1170 + if (cursor->token_type != TOKEN_CLOSE_CURLY) { 1171 + fprintf(stderr, "%s:%d: Expected compound closure, got '%*.*s'\n", 1172 + filename, cursor->line, 1173 + (int)cursor->size, (int)cursor->size, cursor->value); 1174 + exit(1); 1175 + } 1176 + cursor++; 1177 + 1178 + *_cursor = cursor; 1179 + return children; 1180 + 1181 + overrun_error: 1182 + fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename); 1183 + exit(1); 1184 + } 1185 + 1186 + static void render_element(FILE *out, struct element *e, struct element *tag); 1187 + static void render_out_of_line_list(FILE *out); 1188 + 1189 + static int nr_entries; 1190 + static int render_depth = 1; 1191 + static struct element *render_list, **render_list_p = &render_list; 1192 + 1193 + __attribute__((format(printf, 2, 3))) 1194 + static void render_opcode(FILE *out, const char *fmt, ...) 1195 + { 1196 + va_list va; 1197 + 1198 + if (out) { 1199 + fprintf(out, "\t[%4d] =%*s", nr_entries, render_depth, ""); 1200 + va_start(va, fmt); 1201 + vfprintf(out, fmt, va); 1202 + va_end(va); 1203 + } 1204 + nr_entries++; 1205 + } 1206 + 1207 + __attribute__((format(printf, 2, 3))) 1208 + static void render_more(FILE *out, const char *fmt, ...) 1209 + { 1210 + va_list va; 1211 + 1212 + if (out) { 1213 + va_start(va, fmt); 1214 + vfprintf(out, fmt, va); 1215 + va_end(va); 1216 + } 1217 + } 1218 + 1219 + /* 1220 + * Render the grammar into a state machine definition. 1221 + */ 1222 + static void render(FILE *out, FILE *hdr) 1223 + { 1224 + struct element *e; 1225 + struct action *action; 1226 + struct type *root; 1227 + int index; 1228 + 1229 + fprintf(hdr, "/*\n"); 1230 + fprintf(hdr, " * Automatically generated by asn1_compiler. Do not edit\n"); 1231 + fprintf(hdr, " *\n"); 1232 + fprintf(hdr, " * ASN.1 parser for %s\n", grammar_name); 1233 + fprintf(hdr, " */\n"); 1234 + fprintf(hdr, "#include <linux/asn1_decoder.h>\n"); 1235 + fprintf(hdr, "\n"); 1236 + fprintf(hdr, "extern const struct asn1_decoder %s_decoder;\n", grammar_name); 1237 + if (ferror(hdr)) { 1238 + perror(headername); 1239 + exit(1); 1240 + } 1241 + 1242 + fprintf(out, "/*\n"); 1243 + fprintf(out, " * Automatically generated by asn1_compiler. Do not edit\n"); 1244 + fprintf(out, " *\n"); 1245 + fprintf(out, " * ASN.1 parser for %s\n", grammar_name); 1246 + fprintf(out, " */\n"); 1247 + fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n"); 1248 + fprintf(out, "#include \"%s-asn1.h\"\n", grammar_name); 1249 + fprintf(out, "\n"); 1250 + if (ferror(out)) { 1251 + perror(outputname); 1252 + exit(1); 1253 + } 1254 + 1255 + /* Tabulate the action functions we might have to call */ 1256 + fprintf(hdr, "\n"); 1257 + index = 0; 1258 + for (action = action_list; action; action = action->next) { 1259 + action->index = index++; 1260 + fprintf(hdr, 1261 + "extern int %s(void *, size_t, unsigned char," 1262 + " const void *, size_t);\n", 1263 + action->name); 1264 + } 1265 + fprintf(hdr, "\n"); 1266 + 1267 + fprintf(out, "enum %s_actions {\n", grammar_name); 1268 + for (action = action_list; action; action = action->next) 1269 + fprintf(out, "\tACT_%s = %u,\n", 1270 + action->name, action->index); 1271 + fprintf(out, "\tNR__%s_actions = %u\n", grammar_name, nr_actions); 1272 + fprintf(out, "};\n"); 1273 + 1274 + fprintf(out, "\n"); 1275 + fprintf(out, "static const asn1_action_t %s_action_table[NR__%s_actions] = {\n", 1276 + grammar_name, grammar_name); 1277 + for (action = action_list; action; action = action->next) 1278 + fprintf(out, "\t[%4u] = %s,\n", action->index, action->name); 1279 + fprintf(out, "};\n"); 1280 + 1281 + if (ferror(out)) { 1282 + perror(outputname); 1283 + exit(1); 1284 + } 1285 + 1286 + /* We do two passes - the first one calculates all the offsets */ 1287 + printf("Pass 1\n"); 1288 + nr_entries = 0; 1289 + root = &type_list[0]; 1290 + render_element(NULL, root->element, NULL); 1291 + render_opcode(NULL, "ASN1_OP_COMPLETE,\n"); 1292 + render_out_of_line_list(NULL); 1293 + 1294 + for (e = element_list; e; e = e->list_next) 1295 + e->flags &= ~ELEMENT_RENDERED; 1296 + 1297 + /* And then we actually render */ 1298 + printf("Pass 2\n"); 1299 + fprintf(out, "\n"); 1300 + fprintf(out, "static const unsigned char %s_machine[] = {\n", 1301 + grammar_name); 1302 + 1303 + nr_entries = 0; 1304 + root = &type_list[0]; 1305 + render_element(out, root->element, NULL); 1306 + render_opcode(out, "ASN1_OP_COMPLETE,\n"); 1307 + render_out_of_line_list(out); 1308 + 1309 + fprintf(out, "};\n"); 1310 + 1311 + fprintf(out, "\n"); 1312 + fprintf(out, "const struct asn1_decoder %s_decoder = {\n", grammar_name); 1313 + fprintf(out, "\t.machine = %s_machine,\n", grammar_name); 1314 + fprintf(out, "\t.machlen = sizeof(%s_machine),\n", grammar_name); 1315 + fprintf(out, "\t.actions = %s_action_table,\n", grammar_name); 1316 + fprintf(out, "};\n"); 1317 + } 1318 + 1319 + /* 1320 + * Render the out-of-line elements 1321 + */ 1322 + static void render_out_of_line_list(FILE *out) 1323 + { 1324 + struct element *e, *ce; 1325 + const char *act; 1326 + int entry; 1327 + 1328 + while ((e = render_list)) { 1329 + render_list = e->render_next; 1330 + if (!render_list) 1331 + render_list_p = &render_list; 1332 + 1333 + render_more(out, "\n"); 1334 + e->entry_index = entry = nr_entries; 1335 + render_depth++; 1336 + for (ce = e->children; ce; ce = ce->next) 1337 + render_element(out, ce, NULL); 1338 + render_depth--; 1339 + 1340 + act = e->action ? "_ACT" : ""; 1341 + switch (e->compound) { 1342 + case SEQUENCE: 1343 + render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act); 1344 + break; 1345 + case SEQUENCE_OF: 1346 + render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act); 1347 + render_opcode(out, "_jump_target(%u),\n", entry); 1348 + break; 1349 + case SET: 1350 + render_opcode(out, "ASN1_OP_END_SET%s,\n", act); 1351 + break; 1352 + case SET_OF: 1353 + render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act); 1354 + render_opcode(out, "_jump_target(%u),\n", entry); 1355 + break; 1356 + } 1357 + if (e->action) 1358 + render_opcode(out, "_action(ACT_%s),\n", 1359 + e->action->name); 1360 + render_opcode(out, "ASN1_OP_RETURN,\n"); 1361 + } 1362 + } 1363 + 1364 + /* 1365 + * Render an element. 1366 + */ 1367 + static void render_element(FILE *out, struct element *e, struct element *tag) 1368 + { 1369 + struct element *ec; 1370 + const char *cond, *act; 1371 + int entry, skippable = 0, outofline = 0; 1372 + 1373 + if (e->flags & ELEMENT_SKIPPABLE || 1374 + (tag && tag->flags & ELEMENT_SKIPPABLE)) 1375 + skippable = 1; 1376 + 1377 + if ((e->type_def && e->type_def->ref_count > 1) || 1378 + skippable) 1379 + outofline = 1; 1380 + 1381 + if (e->type_def && out) { 1382 + render_more(out, "\t// %*.*s\n", 1383 + (int)e->type_def->name->size, (int)e->type_def->name->size, 1384 + e->type_def->name->value); 1385 + } 1386 + 1387 + /* Render the operation */ 1388 + cond = (e->flags & ELEMENT_CONDITIONAL || 1389 + (tag && tag->flags & ELEMENT_CONDITIONAL)) ? "COND_" : ""; 1390 + act = e->action ? "_ACT" : ""; 1391 + switch (e->compound) { 1392 + case ANY: 1393 + render_opcode(out, "ASN1_OP_%sMATCH_ANY%s,", cond, act); 1394 + if (e->name) 1395 + render_more(out, "\t\t// %*.*s", 1396 + (int)e->name->size, (int)e->name->size, 1397 + e->name->value); 1398 + render_more(out, "\n"); 1399 + goto dont_render_tag; 1400 + 1401 + case TAG_OVERRIDE: 1402 + render_element(out, e->children, e); 1403 + return; 1404 + 1405 + case SEQUENCE: 1406 + case SEQUENCE_OF: 1407 + case SET: 1408 + case SET_OF: 1409 + render_opcode(out, "ASN1_OP_%sMATCH%s%s,", 1410 + cond, 1411 + outofline ? "_JUMP" : "", 1412 + skippable ? "_OR_SKIP" : ""); 1413 + break; 1414 + 1415 + case CHOICE: 1416 + goto dont_render_tag; 1417 + 1418 + case TYPE_REF: 1419 + if (e->class == ASN1_UNIV && e->method == ASN1_PRIM && e->tag == 0) 1420 + goto dont_render_tag; 1421 + default: 1422 + render_opcode(out, "ASN1_OP_%sMATCH%s%s,", 1423 + cond, act, 1424 + skippable ? "_OR_SKIP" : ""); 1425 + break; 1426 + } 1427 + 1428 + if (e->name) 1429 + render_more(out, "\t\t// %*.*s", 1430 + (int)e->name->size, (int)e->name->size, 1431 + e->name->value); 1432 + render_more(out, "\n"); 1433 + 1434 + /* Render the tag */ 1435 + if (!tag) 1436 + tag = e; 1437 + if (tag->class == ASN1_UNIV && 1438 + tag->tag != 14 && 1439 + tag->tag != 15 && 1440 + tag->tag != 31) 1441 + render_opcode(out, "_tag(%s, %s, %s),\n", 1442 + asn1_classes[tag->class], 1443 + asn1_methods[tag->method | e->method], 1444 + asn1_universal_tags[tag->tag]); 1445 + else 1446 + render_opcode(out, "_tagn(%s, %s, %2u),\n", 1447 + asn1_classes[tag->class], 1448 + asn1_methods[tag->method | e->method], 1449 + tag->tag); 1450 + tag = NULL; 1451 + dont_render_tag: 1452 + 1453 + /* Deal with compound types */ 1454 + switch (e->compound) { 1455 + case TYPE_REF: 1456 + render_element(out, e->type->type->element, tag); 1457 + if (e->action) 1458 + render_opcode(out, "ASN1_OP_ACT,\n"); 1459 + break; 1460 + 1461 + case SEQUENCE: 1462 + if (outofline) { 1463 + /* Render out-of-line for multiple use or 1464 + * skipability */ 1465 + render_opcode(out, "_jump_target(%u),", e->entry_index); 1466 + if (e->type_def && e->type_def->name) 1467 + render_more(out, "\t\t// --> %*.*s", 1468 + (int)e->type_def->name->size, 1469 + (int)e->type_def->name->size, 1470 + e->type_def->name->value); 1471 + render_more(out, "\n"); 1472 + if (!(e->flags & ELEMENT_RENDERED)) { 1473 + e->flags |= ELEMENT_RENDERED; 1474 + *render_list_p = e; 1475 + render_list_p = &e->render_next; 1476 + } 1477 + return; 1478 + } else { 1479 + /* Render inline for single use */ 1480 + render_depth++; 1481 + for (ec = e->children; ec; ec = ec->next) 1482 + render_element(out, ec, NULL); 1483 + render_depth--; 1484 + render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act); 1485 + } 1486 + break; 1487 + 1488 + case SEQUENCE_OF: 1489 + case SET_OF: 1490 + if (outofline) { 1491 + /* Render out-of-line for multiple use or 1492 + * skipability */ 1493 + render_opcode(out, "_jump_target(%u),", e->entry_index); 1494 + if (e->type_def && e->type_def->name) 1495 + render_more(out, "\t\t// --> %*.*s", 1496 + (int)e->type_def->name->size, 1497 + (int)e->type_def->name->size, 1498 + e->type_def->name->value); 1499 + render_more(out, "\n"); 1500 + if (!(e->flags & ELEMENT_RENDERED)) { 1501 + e->flags |= ELEMENT_RENDERED; 1502 + *render_list_p = e; 1503 + render_list_p = &e->render_next; 1504 + } 1505 + return; 1506 + } else { 1507 + /* Render inline for single use */ 1508 + entry = nr_entries; 1509 + render_depth++; 1510 + render_element(out, e->children, NULL); 1511 + render_depth--; 1512 + if (e->compound == SEQUENCE_OF) 1513 + render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act); 1514 + else 1515 + render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act); 1516 + render_opcode(out, "_jump_target(%u),\n", entry); 1517 + } 1518 + break; 1519 + 1520 + case SET: 1521 + /* I can't think of a nice way to do SET support without having 1522 + * a stack of bitmasks to make sure no element is repeated. 1523 + * The bitmask has also to be checked that no non-optional 1524 + * elements are left out whilst not preventing optional 1525 + * elements from being left out. 1526 + */ 1527 + fprintf(stderr, "The ASN.1 SET type is not currently supported.\n"); 1528 + exit(1); 1529 + 1530 + case CHOICE: 1531 + for (ec = e->children; ec; ec = ec->next) 1532 + render_element(out, ec, NULL); 1533 + if (!skippable) 1534 + render_opcode(out, "ASN1_OP_COND_FAIL,\n"); 1535 + if (e->action) 1536 + render_opcode(out, "ASN1_OP_ACT,\n"); 1537 + break; 1538 + 1539 + default: 1540 + break; 1541 + } 1542 + 1543 + if (e->action) 1544 + render_opcode(out, "_action(ACT_%s),\n", e->action->name); 1545 + }
+115
scripts/sign-file
··· 1 + #!/bin/sh 2 + # 3 + # Sign a module file using the given key. 4 + # 5 + # Format: sign-file <key> <x509> <src-file> <dst-file> 6 + # 7 + 8 + scripts=`dirname $0` 9 + 10 + CONFIG_MODULE_SIG_SHA512=y 11 + if [ -r .config ] 12 + then 13 + . ./.config 14 + fi 15 + 16 + key="$1" 17 + x509="$2" 18 + src="$3" 19 + dst="$4" 20 + 21 + if [ ! -r "$key" ] 22 + then 23 + echo "Can't read private key" >&2 24 + exit 2 25 + fi 26 + 27 + if [ ! -r "$x509" ] 28 + then 29 + echo "Can't read X.509 certificate" >&2 30 + exit 2 31 + fi 32 + if [ ! -r "$x509.signer" ] 33 + then 34 + echo "Can't read Signer name" >&2 35 + exit 2; 36 + fi 37 + if [ ! -r "$x509.keyid" ] 38 + then 39 + echo "Can't read Key identifier" >&2 40 + exit 2; 41 + fi 42 + 43 + # 44 + # Signature parameters 45 + # 46 + algo=1 # Public-key crypto algorithm: RSA 47 + hash= # Digest algorithm 48 + id_type=1 # Identifier type: X.509 49 + 50 + # 51 + # Digest the data 52 + # 53 + dgst= 54 + if [ "$CONFIG_MODULE_SIG_SHA1" = "y" ] 55 + then 56 + prologue="0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14" 57 + dgst=-sha1 58 + hash=2 59 + elif [ "$CONFIG_MODULE_SIG_SHA224" = "y" ] 60 + then 61 + prologue="0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C" 62 + dgst=-sha224 63 + hash=7 64 + elif [ "$CONFIG_MODULE_SIG_SHA256" = "y" ] 65 + then 66 + prologue="0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20" 67 + dgst=-sha256 68 + hash=4 69 + elif [ "$CONFIG_MODULE_SIG_SHA384" = "y" ] 70 + then 71 + prologue="0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30" 72 + dgst=-sha384 73 + hash=5 74 + elif [ "$CONFIG_MODULE_SIG_SHA512" = "y" ] 75 + then 76 + prologue="0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40" 77 + dgst=-sha512 78 + hash=6 79 + else 80 + echo "$0: Can't determine hash algorithm" >&2 81 + exit 2 82 + fi 83 + 84 + ( 85 + perl -e "binmode STDOUT; print pack(\"C*\", $prologue)" || exit $? 86 + openssl dgst $dgst -binary $src || exit $? 87 + ) >$src.dig || exit $? 88 + 89 + # 90 + # Generate the binary signature, which will be just the integer that comprises 91 + # the signature with no metadata attached. 92 + # 93 + openssl rsautl -sign -inkey $key -keyform PEM -in $src.dig -out $src.sig || exit $? 94 + signerlen=`stat -c %s $x509.signer` 95 + keyidlen=`stat -c %s $x509.keyid` 96 + siglen=`stat -c %s $src.sig` 97 + 98 + # 99 + # Build the signed binary 100 + # 101 + ( 102 + cat $src || exit $? 103 + echo '~Module signature appended~' || exit $? 104 + cat $x509.signer $x509.keyid || exit $? 105 + 106 + # Preface each signature integer with a 2-byte BE length 107 + perl -e "binmode STDOUT; print pack(\"n\", $siglen)" || exit $? 108 + cat $src.sig || exit $? 109 + 110 + # Generate the information block 111 + perl -e "binmode STDOUT; print pack(\"CCCCCxxxN\", $algo, $hash, $id_type, $signerlen, $keyidlen, $siglen + 2)" || exit $? 112 + ) >$dst~ || exit $? 113 + 114 + # Permit in-place signing 115 + mv $dst~ $dst || exit $?
+268
scripts/x509keyid
··· 1 + #!/usr/bin/perl -w 2 + # 3 + # Generate an identifier from an X.509 certificate that can be placed in a 4 + # module signature to indentify the key to use. 5 + # 6 + # Format: 7 + # 8 + # ./scripts/x509keyid <x509-cert> <signer's-name> <key-id> 9 + # 10 + # We read the DER-encoded X509 certificate and parse it to extract the Subject 11 + # name and Subject Key Identifier. The provide the data we need to build the 12 + # certificate identifier. 13 + # 14 + # The signer's name part of the identifier is fabricated from the commonName, 15 + # the organizationName or the emailAddress components of the X.509 subject 16 + # name and written to the second named file. 17 + # 18 + # The subject key ID to select which of that signer's certificates we're 19 + # intending to use to sign the module is written to the third named file. 20 + # 21 + use strict; 22 + 23 + my $raw_data; 24 + 25 + die "Need three filenames\n" if ($#ARGV != 2); 26 + 27 + my $src = $ARGV[0]; 28 + 29 + open(FD, "<$src") || die $src; 30 + binmode FD; 31 + my @st = stat(FD); 32 + die $src if (!@st); 33 + read(FD, $raw_data, $st[7]) || die $src; 34 + close(FD); 35 + 36 + my $UNIV = 0 << 6; 37 + my $APPL = 1 << 6; 38 + my $CONT = 2 << 6; 39 + my $PRIV = 3 << 6; 40 + 41 + my $CONS = 0x20; 42 + 43 + my $BOOLEAN = 0x01; 44 + my $INTEGER = 0x02; 45 + my $BIT_STRING = 0x03; 46 + my $OCTET_STRING = 0x04; 47 + my $NULL = 0x05; 48 + my $OBJ_ID = 0x06; 49 + my $UTF8String = 0x0c; 50 + my $SEQUENCE = 0x10; 51 + my $SET = 0x11; 52 + my $UTCTime = 0x17; 53 + my $GeneralizedTime = 0x18; 54 + 55 + my %OIDs = ( 56 + pack("CCC", 85, 4, 3) => "commonName", 57 + pack("CCC", 85, 4, 6) => "countryName", 58 + pack("CCC", 85, 4, 10) => "organizationName", 59 + pack("CCC", 85, 4, 11) => "organizationUnitName", 60 + pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption", 61 + pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption", 62 + pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress", 63 + pack("CCC", 85, 29, 35) => "authorityKeyIdentifier", 64 + pack("CCC", 85, 29, 14) => "subjectKeyIdentifier", 65 + pack("CCC", 85, 29, 19) => "basicConstraints" 66 + ); 67 + 68 + ############################################################################### 69 + # 70 + # Extract an ASN.1 element from a string and return information about it. 71 + # 72 + ############################################################################### 73 + sub asn1_extract($$@) 74 + { 75 + my ($cursor, $expected_tag, $optional) = @_; 76 + 77 + return [ -1 ] 78 + if ($cursor->[1] == 0 && $optional); 79 + 80 + die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n" 81 + if ($cursor->[1] < 2); 82 + 83 + my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2)); 84 + 85 + if ($expected_tag != -1 && $tag != $expected_tag) { 86 + return [ -1 ] 87 + if ($optional); 88 + die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag, 89 + " not ", $expected_tag, ")\n"; 90 + } 91 + 92 + $cursor->[0] += 2; 93 + $cursor->[1] -= 2; 94 + 95 + die $src, ": ", $cursor->[0], ": ASN.1 long tag\n" 96 + if (($tag & 0x1f) == 0x1f); 97 + die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n" 98 + if ($len == 0x80); 99 + 100 + if ($len > 0x80) { 101 + my $l = $len - 0x80; 102 + die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n" 103 + if ($cursor->[1] < $l); 104 + 105 + if ($l == 0x1) { 106 + $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); 107 + } elsif ($l = 0x2) { 108 + $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); 109 + } elsif ($l = 0x3) { 110 + $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; 111 + $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); 112 + } elsif ($l = 0x4) { 113 + $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); 114 + } else { 115 + die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; 116 + } 117 + 118 + $cursor->[0] += $l; 119 + $cursor->[1] -= $l; 120 + } 121 + 122 + die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n" 123 + if ($cursor->[1] < $len); 124 + 125 + my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ]; 126 + $cursor->[0] += $len; 127 + $cursor->[1] -= $len; 128 + 129 + return $ret; 130 + } 131 + 132 + ############################################################################### 133 + # 134 + # Retrieve the data referred to by a cursor 135 + # 136 + ############################################################################### 137 + sub asn1_retrieve($) 138 + { 139 + my ($cursor) = @_; 140 + my ($offset, $len, $data) = @$cursor; 141 + return substr($$data, $offset, $len); 142 + } 143 + 144 + ############################################################################### 145 + # 146 + # Roughly parse the X.509 certificate 147 + # 148 + ############################################################################### 149 + my $cursor = [ 0, length($raw_data), \$raw_data ]; 150 + 151 + my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE); 152 + my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE); 153 + my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1); 154 + my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER); 155 + my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE); 156 + my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE); 157 + my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE); 158 + my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE); 159 + my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE); 160 + my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1); 161 + my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1); 162 + my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1); 163 + 164 + my $subject_key_id = (); 165 + my $authority_key_id = (); 166 + 167 + # 168 + # Parse the extension list 169 + # 170 + if ($extension_list->[0] != -1) { 171 + my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE); 172 + 173 + while ($extensions->[1]->[1] > 0) { 174 + my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE); 175 + my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID); 176 + my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1); 177 + my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING); 178 + 179 + my $raw_oid = asn1_retrieve($x_oid->[1]); 180 + next if (!exists($OIDs{$raw_oid})); 181 + my $x_type = $OIDs{$raw_oid}; 182 + 183 + my $raw_value = asn1_retrieve($x_val->[1]); 184 + 185 + if ($x_type eq "subjectKeyIdentifier") { 186 + my $vcursor = [ 0, length($raw_value), \$raw_value ]; 187 + 188 + $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING); 189 + } 190 + } 191 + } 192 + 193 + ############################################################################### 194 + # 195 + # Determine what we're going to use as the signer's name. In order of 196 + # preference, take one of: commonName, organizationName or emailAddress. 197 + # 198 + ############################################################################### 199 + my $org = ""; 200 + my $cn = ""; 201 + my $email = ""; 202 + 203 + while ($subject->[1]->[1] > 0) { 204 + my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET); 205 + my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE); 206 + my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID); 207 + my $n_val = asn1_extract($attr->[1], -1); 208 + 209 + my $raw_oid = asn1_retrieve($n_oid->[1]); 210 + next if (!exists($OIDs{$raw_oid})); 211 + my $n_type = $OIDs{$raw_oid}; 212 + 213 + my $raw_value = asn1_retrieve($n_val->[1]); 214 + 215 + if ($n_type eq "organizationName") { 216 + $org = $raw_value; 217 + } elsif ($n_type eq "commonName") { 218 + $cn = $raw_value; 219 + } elsif ($n_type eq "emailAddress") { 220 + $email = $raw_value; 221 + } 222 + } 223 + 224 + my $id_name = $email; 225 + 226 + if ($org && $cn) { 227 + # Don't use the organizationName if the commonName repeats it 228 + if (length($org) <= length($cn) && 229 + substr($cn, 0, length($org)) eq $org) { 230 + $id_name = $cn; 231 + goto got_id_name; 232 + } 233 + 234 + # Or a signifcant chunk of it 235 + if (length($org) >= 7 && 236 + length($cn) >= 7 && 237 + substr($cn, 0, 7) eq substr($org, 0, 7)) { 238 + $id_name = $cn; 239 + goto got_id_name; 240 + } 241 + 242 + $id_name = $org . ": " . $cn; 243 + } elsif ($org) { 244 + $id_name = $org; 245 + } elsif ($cn) { 246 + $id_name = $cn; 247 + } 248 + 249 + got_id_name: 250 + 251 + ############################################################################### 252 + # 253 + # Output the signer's name and the key identifier that we're going to include 254 + # in module signatures. 255 + # 256 + ############################################################################### 257 + die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n" 258 + if (!$subject_key_id); 259 + 260 + my $id_key_id = asn1_retrieve($subject_key_id->[1]); 261 + 262 + open(OUTFD, ">$ARGV[1]") || die $ARGV[1]; 263 + print OUTFD $id_name; 264 + close OUTFD || die $ARGV[1]; 265 + 266 + open(OUTFD, ">$ARGV[2]") || die $ARGV[2]; 267 + print OUTFD $id_key_id; 268 + close OUTFD || die $ARGV[2];
+9 -7
security/keys/encrypted-keys/encrypted.c
··· 773 773 * 774 774 * On success, return 0. Otherwise return errno. 775 775 */ 776 - static int encrypted_instantiate(struct key *key, const void *data, 777 - size_t datalen) 776 + static int encrypted_instantiate(struct key *key, 777 + struct key_preparsed_payload *prep) 778 778 { 779 779 struct encrypted_key_payload *epayload = NULL; 780 780 char *datablob = NULL; ··· 782 782 char *master_desc = NULL; 783 783 char *decrypted_datalen = NULL; 784 784 char *hex_encoded_iv = NULL; 785 + size_t datalen = prep->datalen; 785 786 int ret; 786 787 787 - if (datalen <= 0 || datalen > 32767 || !data) 788 + if (datalen <= 0 || datalen > 32767 || !prep->data) 788 789 return -EINVAL; 789 790 790 791 datablob = kmalloc(datalen + 1, GFP_KERNEL); 791 792 if (!datablob) 792 793 return -ENOMEM; 793 794 datablob[datalen] = 0; 794 - memcpy(datablob, data, datalen); 795 + memcpy(datablob, prep->data, datalen); 795 796 ret = datablob_parse(datablob, &format, &master_desc, 796 797 &decrypted_datalen, &hex_encoded_iv); 797 798 if (ret < 0) ··· 835 834 * 836 835 * On success, return 0. Otherwise return errno. 837 836 */ 838 - static int encrypted_update(struct key *key, const void *data, size_t datalen) 837 + static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) 839 838 { 840 839 struct encrypted_key_payload *epayload = key->payload.data; 841 840 struct encrypted_key_payload *new_epayload; 842 841 char *buf; 843 842 char *new_master_desc = NULL; 844 843 const char *format = NULL; 844 + size_t datalen = prep->datalen; 845 845 int ret = 0; 846 846 847 - if (datalen <= 0 || datalen > 32767 || !data) 847 + if (datalen <= 0 || datalen > 32767 || !prep->data) 848 848 return -EINVAL; 849 849 850 850 buf = kmalloc(datalen + 1, GFP_KERNEL); ··· 853 851 return -ENOMEM; 854 852 855 853 buf[datalen] = 0; 856 - memcpy(buf, data, datalen); 854 + memcpy(buf, prep->data, datalen); 857 855 ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); 858 856 if (ret < 0) 859 857 goto out;
+82 -32
security/keys/key.c
··· 405 405 * key_construction_mutex. 406 406 */ 407 407 static int __key_instantiate_and_link(struct key *key, 408 - const void *data, 409 - size_t datalen, 408 + struct key_preparsed_payload *prep, 410 409 struct key *keyring, 411 410 struct key *authkey, 412 411 unsigned long *_prealloc) ··· 423 424 /* can't instantiate twice */ 424 425 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 425 426 /* instantiate the key */ 426 - ret = key->type->instantiate(key, data, datalen); 427 + ret = key->type->instantiate(key, prep); 427 428 428 429 if (ret == 0) { 429 430 /* mark the key as being instantiated */ ··· 474 475 struct key *keyring, 475 476 struct key *authkey) 476 477 { 478 + struct key_preparsed_payload prep; 477 479 unsigned long prealloc; 478 480 int ret; 481 + 482 + memset(&prep, 0, sizeof(prep)); 483 + prep.data = data; 484 + prep.datalen = datalen; 485 + prep.quotalen = key->type->def_datalen; 486 + if (key->type->preparse) { 487 + ret = key->type->preparse(&prep); 488 + if (ret < 0) 489 + goto error; 490 + } 479 491 480 492 if (keyring) { 481 493 ret = __key_link_begin(keyring, key->type, key->description, 482 494 &prealloc); 483 495 if (ret < 0) 484 - return ret; 496 + goto error_free_preparse; 485 497 } 486 498 487 - ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey, 499 + ret = __key_instantiate_and_link(key, &prep, keyring, authkey, 488 500 &prealloc); 489 501 490 502 if (keyring) 491 503 __key_link_end(keyring, key->type, prealloc); 492 504 505 + error_free_preparse: 506 + if (key->type->preparse) 507 + key->type->free_preparse(&prep); 508 + error: 493 509 return ret; 494 510 } 495 511 ··· 713 699 * if we get an error. 714 700 */ 715 701 static inline key_ref_t __key_update(key_ref_t key_ref, 716 - const void *payload, size_t plen) 702 + struct key_preparsed_payload *prep) 717 703 { 718 704 struct key *key = key_ref_to_ptr(key_ref); 719 705 int ret; ··· 729 715 730 716 down_write(&key->sem); 731 717 732 - ret = key->type->update(key, payload, plen); 718 + ret = key->type->update(key, prep); 733 719 if (ret == 0) 734 720 /* updating a negative key instantiates it */ 735 721 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); ··· 781 767 unsigned long flags) 782 768 { 783 769 unsigned long prealloc; 770 + struct key_preparsed_payload prep; 784 771 const struct cred *cred = current_cred(); 785 772 struct key_type *ktype; 786 773 struct key *keyring, *key = NULL; ··· 797 782 } 798 783 799 784 key_ref = ERR_PTR(-EINVAL); 800 - if (!ktype->match || !ktype->instantiate) 801 - goto error_2; 785 + if (!ktype->match || !ktype->instantiate || 786 + (!description && !ktype->preparse)) 787 + goto error_put_type; 802 788 803 789 keyring = key_ref_to_ptr(keyring_ref); 804 790 ··· 807 791 808 792 key_ref = ERR_PTR(-ENOTDIR); 809 793 if (keyring->type != &key_type_keyring) 810 - goto error_2; 794 + goto error_put_type; 795 + 796 + memset(&prep, 0, sizeof(prep)); 797 + prep.data = payload; 798 + prep.datalen = plen; 799 + prep.quotalen = ktype->def_datalen; 800 + if (ktype->preparse) { 801 + ret = ktype->preparse(&prep); 802 + if (ret < 0) { 803 + key_ref = ERR_PTR(ret); 804 + goto error_put_type; 805 + } 806 + if (!description) 807 + description = prep.description; 808 + key_ref = ERR_PTR(-EINVAL); 809 + if (!description) 810 + goto error_free_prep; 811 + } 811 812 812 813 ret = __key_link_begin(keyring, ktype, description, &prealloc); 813 - if (ret < 0) 814 - goto error_2; 814 + if (ret < 0) { 815 + key_ref = ERR_PTR(ret); 816 + goto error_free_prep; 817 + } 815 818 816 819 /* if we're going to allocate a new key, we're going to have 817 820 * to modify the keyring */ 818 821 ret = key_permission(keyring_ref, KEY_WRITE); 819 822 if (ret < 0) { 820 823 key_ref = ERR_PTR(ret); 821 - goto error_3; 824 + goto error_link_end; 822 825 } 823 826 824 827 /* if it's possible to update this type of key, search for an existing ··· 868 833 perm, flags); 869 834 if (IS_ERR(key)) { 870 835 key_ref = ERR_CAST(key); 871 - goto error_3; 836 + goto error_link_end; 872 837 } 873 838 874 839 /* instantiate it and link it into the target keyring */ 875 - ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL, 876 - &prealloc); 840 + ret = __key_instantiate_and_link(key, &prep, keyring, NULL, &prealloc); 877 841 if (ret < 0) { 878 842 key_put(key); 879 843 key_ref = ERR_PTR(ret); 880 - goto error_3; 844 + goto error_link_end; 881 845 } 882 846 883 847 key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); 884 848 885 - error_3: 849 + error_link_end: 886 850 __key_link_end(keyring, ktype, prealloc); 887 - error_2: 851 + error_free_prep: 852 + if (ktype->preparse) 853 + ktype->free_preparse(&prep); 854 + error_put_type: 888 855 key_type_put(ktype); 889 - error: 856 + error: 890 857 return key_ref; 891 858 892 859 found_matching_key: ··· 896 859 * - we can drop the locks first as we have the key pinned 897 860 */ 898 861 __key_link_end(keyring, ktype, prealloc); 899 - key_type_put(ktype); 900 862 901 - key_ref = __key_update(key_ref, payload, plen); 902 - goto error; 863 + key_ref = __key_update(key_ref, &prep); 864 + goto error_free_prep; 903 865 } 904 866 EXPORT_SYMBOL(key_create_or_update); 905 867 ··· 917 881 */ 918 882 int key_update(key_ref_t key_ref, const void *payload, size_t plen) 919 883 { 884 + struct key_preparsed_payload prep; 920 885 struct key *key = key_ref_to_ptr(key_ref); 921 886 int ret; 922 887 ··· 930 893 931 894 /* attempt to update it if supported */ 932 895 ret = -EOPNOTSUPP; 933 - if (key->type->update) { 934 - down_write(&key->sem); 896 + if (!key->type->update) 897 + goto error; 935 898 936 - ret = key->type->update(key, payload, plen); 937 - if (ret == 0) 938 - /* updating a negative key instantiates it */ 939 - clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 940 - 941 - up_write(&key->sem); 899 + memset(&prep, 0, sizeof(prep)); 900 + prep.data = payload; 901 + prep.datalen = plen; 902 + prep.quotalen = key->type->def_datalen; 903 + if (key->type->preparse) { 904 + ret = key->type->preparse(&prep); 905 + if (ret < 0) 906 + goto error; 942 907 } 943 908 944 - error: 909 + down_write(&key->sem); 910 + 911 + ret = key->type->update(key, &prep); 912 + if (ret == 0) 913 + /* updating a negative key instantiates it */ 914 + clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 915 + 916 + up_write(&key->sem); 917 + 918 + if (key->type->preparse) 919 + key->type->free_preparse(&prep); 920 + error: 945 921 return ret; 946 922 } 947 923 EXPORT_SYMBOL(key_update);
+14 -4
security/keys/keyctl.c
··· 46 46 * Extract the description of a new key from userspace and either add it as a 47 47 * new key to the specified keyring or update a matching key in that keyring. 48 48 * 49 + * If the description is NULL or an empty string, the key type is asked to 50 + * generate one from the payload. 51 + * 49 52 * The keyring must be writable so that we can attach the key to it. 50 53 * 51 54 * If successful, the new key's serial number is returned, otherwise an error ··· 75 72 if (ret < 0) 76 73 goto error; 77 74 78 - description = strndup_user(_description, PAGE_SIZE); 79 - if (IS_ERR(description)) { 80 - ret = PTR_ERR(description); 81 - goto error; 75 + description = NULL; 76 + if (_description) { 77 + description = strndup_user(_description, PAGE_SIZE); 78 + if (IS_ERR(description)) { 79 + ret = PTR_ERR(description); 80 + goto error; 81 + } 82 + if (!*description) { 83 + kfree(description); 84 + description = NULL; 85 + } 82 86 } 83 87 84 88 /* pull the payload in if one was supplied */
+3 -3
security/keys/keyring.c
··· 66 66 * operations. 67 67 */ 68 68 static int keyring_instantiate(struct key *keyring, 69 - const void *data, size_t datalen); 69 + struct key_preparsed_payload *prep); 70 70 static int keyring_match(const struct key *keyring, const void *criterion); 71 71 static void keyring_revoke(struct key *keyring); 72 72 static void keyring_destroy(struct key *keyring); ··· 121 121 * Returns 0 on success, -EINVAL if given any data. 122 122 */ 123 123 static int keyring_instantiate(struct key *keyring, 124 - const void *data, size_t datalen) 124 + struct key_preparsed_payload *prep) 125 125 { 126 126 int ret; 127 127 128 128 ret = -EINVAL; 129 - if (datalen == 0) { 129 + if (prep->datalen == 0) { 130 130 /* make the keyring available by name if it has one */ 131 131 keyring_publish_name(keyring); 132 132 ret = 0;
+4 -4
security/keys/request_key_auth.c
··· 19 19 #include <asm/uaccess.h> 20 20 #include "internal.h" 21 21 22 - static int request_key_auth_instantiate(struct key *, const void *, size_t); 22 + static int request_key_auth_instantiate(struct key *, 23 + struct key_preparsed_payload *); 23 24 static void request_key_auth_describe(const struct key *, struct seq_file *); 24 25 static void request_key_auth_revoke(struct key *); 25 26 static void request_key_auth_destroy(struct key *); ··· 43 42 * Instantiate a request-key authorisation key. 44 43 */ 45 44 static int request_key_auth_instantiate(struct key *key, 46 - const void *data, 47 - size_t datalen) 45 + struct key_preparsed_payload *prep) 48 46 { 49 - key->payload.data = (struct request_key_auth *) data; 47 + key->payload.data = (struct request_key_auth *)prep->data; 50 48 return 0; 51 49 } 52 50
+9 -7
security/keys/trusted.c
··· 895 895 * 896 896 * On success, return 0. Otherwise return errno. 897 897 */ 898 - static int trusted_instantiate(struct key *key, const void *data, 899 - size_t datalen) 898 + static int trusted_instantiate(struct key *key, 899 + struct key_preparsed_payload *prep) 900 900 { 901 901 struct trusted_key_payload *payload = NULL; 902 902 struct trusted_key_options *options = NULL; 903 + size_t datalen = prep->datalen; 903 904 char *datablob; 904 905 int ret = 0; 905 906 int key_cmd; 906 907 size_t key_len; 907 908 908 - if (datalen <= 0 || datalen > 32767 || !data) 909 + if (datalen <= 0 || datalen > 32767 || !prep->data) 909 910 return -EINVAL; 910 911 911 912 datablob = kmalloc(datalen + 1, GFP_KERNEL); 912 913 if (!datablob) 913 914 return -ENOMEM; 914 - memcpy(datablob, data, datalen); 915 + memcpy(datablob, prep->data, datalen); 915 916 datablob[datalen] = '\0'; 916 917 917 918 options = trusted_options_alloc(); ··· 982 981 /* 983 982 * trusted_update - reseal an existing key with new PCR values 984 983 */ 985 - static int trusted_update(struct key *key, const void *data, size_t datalen) 984 + static int trusted_update(struct key *key, struct key_preparsed_payload *prep) 986 985 { 987 986 struct trusted_key_payload *p = key->payload.data; 988 987 struct trusted_key_payload *new_p; 989 988 struct trusted_key_options *new_o; 989 + size_t datalen = prep->datalen; 990 990 char *datablob; 991 991 int ret = 0; 992 992 993 993 if (!p->migratable) 994 994 return -EPERM; 995 - if (datalen <= 0 || datalen > 32767 || !data) 995 + if (datalen <= 0 || datalen > 32767 || !prep->data) 996 996 return -EINVAL; 997 997 998 998 datablob = kmalloc(datalen + 1, GFP_KERNEL); ··· 1010 1008 goto out; 1011 1009 } 1012 1010 1013 - memcpy(datablob, data, datalen); 1011 + memcpy(datablob, prep->data, datalen); 1014 1012 datablob[datalen] = '\0'; 1015 1013 ret = datablob_parse(datablob, new_p, new_o); 1016 1014 if (ret != Opt_update) {
+8 -6
security/keys/user_defined.c
··· 58 58 /* 59 59 * instantiate a user defined key 60 60 */ 61 - int user_instantiate(struct key *key, const void *data, size_t datalen) 61 + int user_instantiate(struct key *key, struct key_preparsed_payload *prep) 62 62 { 63 63 struct user_key_payload *upayload; 64 + size_t datalen = prep->datalen; 64 65 int ret; 65 66 66 67 ret = -EINVAL; 67 - if (datalen <= 0 || datalen > 32767 || !data) 68 + if (datalen <= 0 || datalen > 32767 || !prep->data) 68 69 goto error; 69 70 70 71 ret = key_payload_reserve(key, datalen); ··· 79 78 80 79 /* attach the data */ 81 80 upayload->datalen = datalen; 82 - memcpy(upayload->data, data, datalen); 81 + memcpy(upayload->data, prep->data, datalen); 83 82 rcu_assign_keypointer(key, upayload); 84 83 ret = 0; 85 84 ··· 93 92 * update a user defined key 94 93 * - the key's semaphore is write-locked 95 94 */ 96 - int user_update(struct key *key, const void *data, size_t datalen) 95 + int user_update(struct key *key, struct key_preparsed_payload *prep) 97 96 { 98 97 struct user_key_payload *upayload, *zap; 98 + size_t datalen = prep->datalen; 99 99 int ret; 100 100 101 101 ret = -EINVAL; 102 - if (datalen <= 0 || datalen > 32767 || !data) 102 + if (datalen <= 0 || datalen > 32767 || !prep->data) 103 103 goto error; 104 104 105 105 /* construct a replacement payload */ ··· 110 108 goto error; 111 109 112 110 upayload->datalen = datalen; 113 - memcpy(upayload->data, data, datalen); 111 + memcpy(upayload->data, prep->data, datalen); 114 112 115 113 /* check the quota and attach the new data */ 116 114 zap = upayload;