轉自:http://blog.csdn.net/hui872370036/article/details/69950869
最近在調試一個驅動的時候,用insmod加載.ko的時候,提示Required key not available,第一反應是簽名有問題,內核模塊也開始使用類似apk的簽名了嗎?查資料后果然是這樣。這個問題可以說不算是Android的問題,而應該是Linux系統的問題,android本身就是個linux系統。
下來一步一步分析問題的所在。
內核配置
內核從3.7后開始支持模塊簽名,這個功能使能以后,內核只允許安裝特定key簽名的模塊。
內核配置項
CONFIG_MODULE_SIG=y
- 1
- 1
表示開啟了簽名機制,但是這時候模塊簽名或不簽名都可以使用。
CONFIG_MODULE_SIG_FORCE=y
- 1
- 1
如果上述配置項使能,則模塊必須有正確的簽名才能正常使用。
CONFIG_MODULE_SIG_ALL=y
- 1
- 1
內核在編譯的時候,並不會主動去給模塊簽名,除非你把上述配置項打開。
查看內核配置文件,發現上面3個配置項確實都打開了,因此肯定是ko簽名的問題。
內核如何簽名
在內核kernel/kernel下的Makefile中有如下:
signing_key.priv signing_key.x509: x509.genkey
@echo "###" @echo "### Now generating an X.509 key pair to be used for signing modules." @echo "###" @echo "### If this takes a long time, you might wish to run rngd in the" @echo "### background to keep the supply of entropy topped up. It" @echo "### needs to be run as root, and uses a hardware random" @echo "### number generator if one is available." @echo "###" openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \ -batch -x509 -config x509.genkey \ -outform DER -out signing_key.x509 \ -keyout signing_key.priv 2>&1 @echo "###" @echo "### Key pair generated." @echo "###" x509.genkey: @echo Generating X.509 key generation config @echo >x509.genkey "[ req ]" @echo >>x509.genkey "default_bits = 4096" @echo >>x509.genkey "distinguished_name = req_distinguished_name" @echo >>x509.genkey "prompt = no" @echo >>x509.genkey "string_mask = utf8only" @echo >>x509.genkey "x509_extensions = myexts" @echo >>x509.genkey @echo >>x509.genkey "[ req_distinguished_name ]" @echo >>x509.genkey "O = Magrathea" @echo >>x509.genkey "CN = Glacier signing key" @echo >>x509.genkey "emailAddress = slartibartfast@magrathea.h2g2" @echo >>x509.genkey @echo >>x509.genkey "[ myexts ]" @echo >>x509.genkey "basicConstraints=critical,CA:FALSE" @echo >>x509.genkey "keyUsage=digitalSignature" @echo >>x509.genkey "subjectKeyIdentifier=hash" @echo >>x509.genkey "authorityKeyIdentifier=keyid"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
其中,x509.genkey是生成key pair時的配置項,signing_key.priv signing_key.x509分別為private key和數字證書。數字證書會打包進內核,里面有公鑰等,用來解密嘛。每編譯一次,雖然配置文件每次都相同,但是生成的key pair是不同的。
查看簽名信息
利用下面命令查看設備中的ko文件信息:
hexdump -C spidev.ko | tail
- 1
- 1
下面是輸出(內核簽名后會把簽名信息附在模塊的最后面):
00004900 9e 94 0a 08 dd 24 a8 a4 7d 44 a6 63 bc 8a 94 7c |.....$..}D.c...|| 00004910 6d aa 74 28 3c 42 bb df 62 ec ad a6 e8 6e 65 4c |m.t(<B..b....neL| 00004920 bd 79 79 3c 74 60 a3 e4 ef 0f 4d 02 29 fa dc 9a |.yy<t`....M.)...| 00004930 06 b4 b2 1d 78 b9 c2 ff 11 1e c1 e0 4d e3 bb 45 |....x.......M..E| 00004940 02 f9 e6 43 b7 fc 46 9e a6 98 fc a1 12 84 ce d8 |...C..F.........| 00004950 4c 32 d1 b8 ba 6b 4c 4d 3e 33 02 20 01 06 01 1e |L2...kLM>3. ....| 00004960 14 00 00 00 00 00 02 02 7e 4d 6f 64 75 6c 65 20 |........~Module | 00004970 73 69 67 6e 61 74 75 72 65 20 61 70 70 65 6e 64 |signature append| 00004980 65 64 7e 0a |ed~.| 00004984
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
由上面輸出,我們發現這個ko已經有簽名信息(Module signature appended),為何還是提示key不對。於是我將編譯機中版本的spidev.ko和設備中的做比較,發現唯有最后部分不同,我猜一定是兩個ko的簽名不同,這應該就是初步原因。
仔細分析后,得到原因:
設備中的內核是后來編譯的,編譯完成后我將內核單獨燒錄進設備(內核肯定就放在kernel的分區),而未改變文件系統(這樣會造成新kernel中的數字證書已經改變,但是文件系統中的ko未改變,而是用以前的內核中private key進行簽名的)。重新完整燒錄版本后,一切功能正常!