From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Thu, 18 Jan 2018 13:13:59 +0000 Subject: [PATCH v3] fscrypt: add support for the encrypted key type Message-Id: <20180118131359.8365-1-git@andred.net> MIME-Version: 1.0 Content-Type: text/plain; charset="windows-1258" Content-Transfer-Encoding: base64 List-Id: To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Draszik?= , Mimi Zohar , David Howells , James Morris , "Serge E. Hallyn" , "Theodore Y. Ts'o" , Jaegeuk Kim , Kees Cook , Eric Biggers , linux-integrity@vger.kernel.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, linux-fscrypt@vger.kernel.org ZnNjcnlwdCB1c2VzIGEgbWFzdGVyIGtleSBmb3IgZWFjaCBkaXJlY3RvcnkgcG9saWN5IGZyb20K d2hpY2ggYWxsIGZ1cnRoZXIga2V5cyBmb3IgdGhhdCBwb2xpY3kgYXJlIGRlcml2ZWQsIGFuZAph dCB0aGUgbW9tZW50IHN1Y2ggYSBtYXN0ZXIga2V5IGhhcyB0byBiZSBpbnNlcnRlZCBpbnRvCmEg a2VybmVsIGtleXJpbmcgYXMgYSAnbG9nb24nIGtleSBieSB1c2VyLXNwYWNlLgoKV2hpbGUgJ2xv Z29uJyBrZXlzIGhhdmUgdGhlIG5pY2UgcHJvcGVydHkgb2Ygbm90IGJlaW5nCnJlYWRhYmxlIGJ5 IHVzZXItc3BhY2UgKGtleWN0bCBkdW1wIGV0Yy4pLCB0aGUgZnNjcnlwdAptYXN0ZXIga2V5IHN0 aWxsIG5lZWRzIHRvIGJlIGdlbmVyYXRlZCBpbml0aWFsbHksIGluIGEKc2VjdXJlIHdheSwgYW5k IGl0IG5lZWRzIHRvIGJlIHNhdmVkIHNvbWV3aGVyZSBmb3IKc3Vic2VxdWVudCByZWJvb3RzLCBh bmQgaGVuY2UgYWxzbyBuZWVkcyBzZWN1cmluZyBpdHNlbGYuCgpVc2FnZSBvZiB0aGUgJ2xvZ29u JyBrZXkgbWVhbnMgdGhhdCBpdCBpcyB1cCB0byB1c2VyLXNwYWNlCnRvIGRvIGFsbCB0aGF0LCBv cGVuaW5nIHVwIHRoZSBwb3NzaWJpbGl0eSBvZiBjcmVhdGluZwpjcnlwdG9ncmFwaGljYWxseSBu b24tc291bmQgbWFzdGVyIGtleXMsIG9yIG5vdCBzdG9yaW5nCnRoZSBtYXN0ZXIga2V5IHNlY3Vy ZWx5IGFjcm9zcyByZWJvb3RzLgoKT25lIGFwcHJvYWNoIGZvciBzZWN1cmluZyB0aGUgbWFzdGVy IGtleSB3b3VsZCBiZSB0byBkbwp0aGF0IHVzaW5nIGEgVFBNIGFuZCB3aGlsZSBvbmUgY291bGQg bWFudWFsbHkgZG8gc28gZS5nLgp1c2luZyB0cG0tdG9vbHMsIHRoYXQgc3RpbGwgbGVhdmVzIGNy ZWF0aW9uIGFuZCBhY3R1YWwKY29ycmVjdCB1c2FnZSBvZiB0cG0tdG9vbHMgdXAgdG8gdXNlci1z cGFjZSwgdGhvdWdoLiBBcyBhbgphc2lkZSwgdHBtLXRvb2xzIG5lZWRzIHRoZSB0Y3NkIGRhZW1v biBydW5uaW5nLCB3aGljaCBtYWtlcwppdCBhd2t3YXJkIHRvIHVzZSBmcm9tIHdpdGhpbiBhbiBp bml0cmFtZnMsIGFuZCB3aGlsZSBvdGhlcgpsaWJyYXJpZXMgZm9yIGludGVyZmFjaW5nIHdpdGgg YSBUUE0gZG8gZXhpc3QsIHRoZXJlCmFwcGVhcnMgdG8gYmUgYSBiZXR0ZXIgd2F5OgoKVGhlIGtl cm5lbCBhbHJlYWR5IGhhcyBhIGNvbmNlcHQgb2YgdHJ1c3RlZCBhcyB3ZWxsIGFzCmVuY3J5cHRl ZCBrZXlzLiBUcnVzdGVkIGtleXMgYXJlIFRQTSBiYWNrZWQga2V5cywgd2hpY2ggY2FuCmJlIHNl YWxlZCB0byBQQ1JzIGFuZCBhbHNvIGVhc2lseSBiZSByZS1zZWFsZWQgYWdhaW5zdCBuZXcKZnV0 dXJlIFBDUnMsIGFuZCBlbmNyeXB0ZWQga2V5cyBhcmUga2V5cyB0aGF0IGFyZSBlbmNyeXB0ZWQK dXNpbmcgYW5vdGhlciBrZXksIGUuZy4gYSB0cnVzdGVkIGtleS4gQWxsIGFyZSBnZW5lcmF0ZWQK YXV0b21hdGljYWxseSBieSB0aGUga2VybmVsIHVzaW5nIHRoZSBSTkcgYW5kIG5ldmVyIGxlYXZl Cmtlcm5lbCBtZW1vcnkgc3BhY2UgKGJhciBhbnkga2VybmVsIG9yIGhhcmR3YXJlIGJ1Z3MpLgoK U28gaXQgc2VlbXMgcmVhc29uYWJsZSB0byBhbGxvdyB0aGUgZnNjcnlwdCBzdWJzeXN0ZW0gdG8K d29yayB3aXRoIGVuY3J5cHRlZCBrZXlzIGFzIHdlbGwuIFRoaXMgaXMgd2hhdCB0aGlzIGNoYW5n ZQpoZXJlIGRvZXMuCgpXZSBjYW4gdXRpbGlzZSBrZXlzIHRoYXQgbmV2ZXIgZXZlciBleGlzdCBp biB1c2VyLXNwYWNlLApub3QgZXZlbiBhdCBpbml0aWFsIGNyZWF0aW9uIHRpbWUsIGFzIHdlbGwg YXMgc2ltcGxpZnlpbmcKdXNhZ2UgLyBjb25maWd1cmF0aW9uLiBTb21ldGhpbmcgdmVyeSB2ZXJ5 IHNpbWlsYXIgZXhpc3RzCmZvciBlQ3J5cHRzIGFscmVhZHkuCgpXaXRoIHRoZXNlIHBhdGNoZXMs IHdlIGNhbgoKICAgIGtta19pZD0kKGtleWN0bCBhZGQgdHJ1c3RlZCBrbWsgIm5ldyAxMjggW3Bj cmluZm89Li4uXSIgQHUpCiAgICBmc2NyeXB0X2lkPSQoa2V5Y3RsIGFkZCBlbmNyeXB0ZWQgZnNj cnlwdDoxMjM0NTY3ODkwMTIzNDU2ICJuZXcgZGVmYXVsdCB0cnVzdGVkOmttayA2NCIgQHUpCiAg ICBmc2NyeXB0Y3RsIHNldF9wb2xpY3kgMTIzNDU2Nzg5MDEyMzQ1NiAvZW5jcnlwdGVkCgp0aGVu IHdlIGNhbiBzYXZlIHRob3NlIGtleXMgZm9yIGFmdGVyIHJlYm9vdCAob3B0aW9uYWxseQpUUE0t c2VhbGVkIGFzIHBlciB0aGUgcGNyaW5mbz0gYXJndW1lbnQgYWJvdmUpOgoKICAgIGtleWN0bCBw aXBlICR7a21rX2lkfSA+IC9rZXlzL2ttay5ibG9iCiAgICBrZXljdGwgcGlwZSAke2ZzY3J5cHRf aWR9ID4gL2tleXMvZnNjcnlwdC5ibG9iCgphbmQgb24gc3Vic2VxdWVudCBib290cyB3ZSBjYW4g c2ltcGx5IGluc2VydCB0aGVtIGFnYWluCihvcHRpb25hbGx5IGJlbmVmaXR0aW5nIGZyb20gdGhl IFRQTSdzIGNhcGFiaWxpdHkgdG8gb25seQp1bnNlYWwga21rLmJsb2Igd2hlbiB0aGUgc3lzdGVt IGlzIGluIHRoZSBleHBlY3RlZCBzdGF0ZSwKdGhlcmVieSBhbHNvIHByb3RlY3RpbmcgZnNjcnlw dC5ibG9iKToKCiAgICBrZXljdGwgYWRkIHRydXN0ZWQga21rICJsb2FkICQoY2F0IC9rZXlzL2tt ay5ibG9iKSIgQHUKICAgIGtleWN0bCBhZGQgZW5jcnlwdGVkIGZzY3J5cHQ6MTIzNDU2Nzg5MDEy MzQ1NiAibG9hZCAkKGNhdCAva2V5cy9mc2NyeXB0LmJsb2IpIiBAdQoKU2lnbmVkLW9mZi1ieTog QW5kcsOpIERyYXN6aWsgPGdpdEBhbmRyZWQubmV0PgpDYzogTWltaSBab2hhciA8em9oYXJAbGlu dXgudm5ldC5pYm0uY29tPgpDYzogRGF2aWQgSG93ZWxscyA8ZGhvd2VsbHNAcmVkaGF0LmNvbT4K Q2M6IEphbWVzIE1vcnJpcyA8amFtZXMubC5tb3JyaXNAb3JhY2xlLmNvbT4KQ2M6ICJTZXJnZSBF LiBIYWxseW4iIDxzZXJnZUBoYWxseW4uY29tPgpDYzogIlRoZW9kb3JlIFkuIFRzJ28iIDx0eXRz b0BtaXQuZWR1PgpDYzogSmFlZ2V1ayBLaW0gPGphZWdldWtAa2VybmVsLm9yZz4KQ2M6IEtlZXMg Q29vayA8a2Vlc2Nvb2tAY2hyb21pdW0ub3JnPgpDYzogRXJpYyBCaWdnZXJzIDxlYmlnZ2Vyc0Bn b29nbGUuY29tPgpDYzogbGludXgtaW50ZWdyaXR5QHZnZXIua2VybmVsLm9yZwpDYzoga2V5cmlu Z3NAdmdlci5rZXJuZWwub3JnCkNjOiBsaW51eC1zZWN1cml0eS1tb2R1bGVAdmdlci5rZXJuZWwu b3JnCkNjOiBsaW51eC1mc2NyeXB0QHZnZXIua2VybmVsLm9yZwpDYzogbGludXgta2VybmVsQHZn ZXIua2VybmVsLm9yZwoKLS0tCmNoYW5nZXMgaW4gdjM6CiogbWVyZ2UgZG9jdW1lbnRhdGlvbiBj aGFuZ2VzIGludG8gdGhpcyBjb21taXQKKiB1cGRhdGUgZGVyaXZlX2tleV9hZXMoKSBzaWduYXR1 cmUgdG8gbm90IHRha2UKICBhIHN0cnVjdCBmc2NyeXB0X2tleSBhbmQgdXBkYXRlIGFsbCBjYWxs ZXJzCiogdHJ5IHRvIHVzZSB0aGUgJ2VuY3J5cHRlZCcga2V5IGFzIGZhbGxiYWNrIG9ubHkKICBp ZiB0aGUgYSAnbG9nb24nIGtleSBpc24ndCBwcmVzZW50IChFTk9LRVkpCiogdXBkYXRlIGZzY3J5 cHRfZ2V0X2VuY3J5cHRlZF9rZXkoKSB0byB0YWtlIGEKICAnZGVzY3JpcHRpb24nLCBub3QgYSAn c2lnJwoqIHVwZGF0ZSBjb21taXQgbWVzc2FnZQoqIHJlLWFkZCBrZXlyaW5ncyBtYWlsaW5nIGxp c3QgYW5kIGVuY3J5cHRlZC1rZXlzCiAgbWFpbnRhaW5lcnMgdG8gQ2MKCmNoYW5nZXMgaW4gdjI6 CiogZHJvcHBlZCB0aGUgcHJldmlvdXNseSBhZGRlZCAnZnNjcnlwdCcgZW5jcnlwdGVkLWtleSwK ICBhbmQganVzdCB1c2UgdGhlICdkZWZhdWx0JyBmb3JtYXQKLS0tCiBEb2N1bWVudGF0aW9uL2Zp bGVzeXN0ZW1zL2ZzY3J5cHQucnN0IHwgNTYgKysrKysrKysrKysrKysrKysrKy0tCiBmcy9jcnlw dG8va2V5aW5mby5jICAgICAgICAgICAgICAgICAgIHwgOTIgKysrKysrKysrKysrKysrKysrKysr Ky0tLS0tLS0tLS0tLS0KIDIgZmlsZXMgY2hhbmdlZCwgMTEwIGluc2VydGlvbnMoKyksIDM4IGRl bGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZmlsZXN5c3RlbXMvZnNjcnlw dC5yc3QgYi9Eb2N1bWVudGF0aW9uL2ZpbGVzeXN0ZW1zL2ZzY3J5cHQucnN0CmluZGV4IDc3NmRk YzY1NWY3OS4uODUyYWMyOTAwYjY2IDEwMDY0NAotLS0gYS9Eb2N1bWVudGF0aW9uL2ZpbGVzeXN0 ZW1zL2ZzY3J5cHQucnN0CisrKyBiL0RvY3VtZW50YXRpb24vZmlsZXN5c3RlbXMvZnNjcnlwdC5y c3QKQEAgLTM2OCwxMSArMzY4LDE5IEBAIEFkZGluZyBrZXlzCiBUbyBwcm92aWRlIGEgbWFzdGVy IGtleSwgdXNlcnNwYWNlIG11c3QgYWRkIGl0IHRvIGFuIGFwcHJvcHJpYXRlCiBrZXlyaW5nIHVz aW5nIHRoZSBhZGRfa2V5KCkgc3lzdGVtIGNhbGwgKHNlZToKIGBgRG9jdW1lbnRhdGlvbi9zZWN1 cml0eS9rZXlzL2NvcmUucnN0YGApLiAgVGhlIGtleSB0eXBlIG11c3QgYmUKLSJsb2dvbiI7IGtl eXMgb2YgdGhpcyB0eXBlIGFyZSBrZXB0IGluIGtlcm5lbCBtZW1vcnkgYW5kIGNhbm5vdCBiZQot cmVhZCBiYWNrIGJ5IHVzZXJzcGFjZS4gIFRoZSBrZXkgZGVzY3JpcHRpb24gbXVzdCBiZSAiZnNj cnlwdDoiCi1mb2xsb3dlZCBieSB0aGUgMTYtY2hhcmFjdGVyIGxvd2VyIGNhc2UgaGV4IHJlcHJl c2VudGF0aW9uIG9mIHRoZQotYGBtYXN0ZXJfa2V5X2Rlc2NyaXB0b3JgYCB0aGF0IHdhcyBzZXQg aW4gdGhlIGVuY3J5cHRpb24gcG9saWN5LiAgVGhlCi1rZXkgcGF5bG9hZCBtdXN0IGNvbmZvcm0g dG8gdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6OgorZWl0aGVyICJsb2dvbiIgb3IgImVuY3J5cHRl ZCI7ICJsb2dvbiIga2V5cyBhcmUga2VwdCBpbiBrZXJuZWwKK21lbW9yeSBhbmQgY2Fubm90IGJl IHJlYWQgYmFjayBieSB1c2Vyc3BhY2Ugd2hpbGUgImVuY3J5cHRlZCIKK2tleXMgY2FuIGJlIHJv b3RlZCBpbiBhICJ0cnVzdGVkIiBrZXkgYW5kIHRodXMgYXJlIHByb3RlY3RlZCBieQorYSBUUE0g YW5kIGNhbm5vdCBiZSByZWFkIGJ5IHVzZXJzcGFjZSBpbiB1bmVuY3J5cHRlZCBmb3JtLiBOb3Rl Cit0aGF0IHdoaWxlIGFuICJlbmNyeXB0ZWQiIGtleSBjYW4gYWxzbyBiZSByb290ZWQgaW4gYSAi dXNlciIga2V5LAorYW55ICJlbmNyeXB0ZWQiIGtleSByb290ZWQgaW4gYSAidXNlciIga2V5IGNh biBlZmZlY3RpdmVseSBiZQorcmV0cmlldmVkIGluIHRoZSBjbGVhciwgaGVuY2Ugb25seSByb290 aW5nIHRoZSBrZXkgaW4gYSAidHJ1c3RlZCIKK2tleSBoYXMgYW55IHVzZWZ1bCBzZWN1cml0eSBw cm9wZXJ0aWVzIQorCitUaGUga2V5IGRlc2NyaXB0aW9uIG11c3QgYmUgImZzY3J5cHQ6IiBmb2xs b3dlZCBieSB0aGUgMTYtY2hhcmFjdGVyCitsb3dlciBjYXNlIGhleCByZXByZXNlbnRhdGlvbiBv ZiB0aGUgYGBtYXN0ZXJfa2V5X2Rlc2NyaXB0b3JgYCB0aGF0Cit3YXMgc2V0IGluIHRoZSBlbmNy eXB0aW9uIHBvbGljeS4gIEZvciBhICJsb2dvbiIga2V5LCBrZXkgcGF5bG9hZAorbXVzdCBjb25m b3JtIHRvIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOjoKIAogICAgICNkZWZpbmUgRlNfTUFYX0tF WV9TSVpFIDY0CiAKQEAgLTM4Niw2ICszOTQsMTcgQEAga2V5IHBheWxvYWQgbXVzdCBjb25mb3Jt IHRvIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOjoKIGBgcmF3YGAgd2l0aCBgYHNpemVgYCBpbmRp Y2F0aW5nIGl0cyBzaXplIGluIGJ5dGVzLiAgVGhhdCBpcywgdGhlCiBieXRlcyBgYHJhd1swLi5z aXplLTFdYGAgKGluY2x1c2l2ZSkgYXJlIHRoZSBhY3R1YWwga2V5LgogCitXaGVuIHVzaW5nIGFu ICJlbmNyeXB0ZWQiIGtleSwgb25seSB0aGUgYWN0dWFsIGBgcmF3YGAga2V5IGZyb20gYWJvdmUK K2ZzY3J5cHRfa2V5IHN0cnVjdHVyZSBpcyBuZWVkZWQ6OgorCisgICAga2V5Y3RsIGFkZCBlbmNy eXB0ZWQgImZzY3J5cHQ6YGBtYXN0ZXJfa2V5X2Rlc2NyaXB0b3JgYCIgIm5ldyBkZWZhdWx0IHRy dXN0ZWQ6YGBtYXN0ZXIta2V5LW5hbWVgYCBgYHNpemVgYCIgYGByaW5nYGAKKyAgICBrZXljdGwg YWRkIGVuY3J5cHRlZCAiZnNjcnlwdDpgYG1hc3Rlcl9rZXlfZGVzY3JpcHRvcmBgIiAibG9hZCBg YGhleF9ibG9iYGAiIGBgcmluZ2BgCisKK1doZXJlOjoKKworICAgIG1hc3Rlci1rZXktbmFtZTo9 IG5hbWUgb2YgdGhlIHRydXN0ZWQga2V5IHRoaXMgZnNjcnlwdCBtYXN0ZXIga2V5CisgICAgICAg ICAgICAgICAgICAgICAgc2hhbGwgYmUgcm9vdGVkIGluCisKIFRoZSBrZXkgZGVzY3JpcHRpb24g cHJlZml4ICJmc2NyeXB0OiIgbWF5IGFsdGVybmF0aXZlbHkgYmUgcmVwbGFjZWQKIHdpdGggYSBm aWxlc3lzdGVtLXNwZWNpZmljIHByZWZpeCBzdWNoIGFzICJleHQ0OiIuICBIb3dldmVyLCB0aGUK IGZpbGVzeXN0ZW0tc3BlY2lmaWMgcHJlZml4ZXMgYXJlIGRlcHJlY2F0ZWQgYW5kIHNob3VsZCBu b3QgYmUgdXNlZCBpbgpAQCAtNDEyLDYgKzQzMSwzMyBAQCBldmljdGVkLiAgSW4gdGhlIGZ1dHVy ZSB0aGVyZSBwcm9iYWJseSBzaG91bGQgYmUgYSB3YXkgdG8gcHJvdmlkZSBrZXlzCiBkaXJlY3Rs eSB0byB0aGUgZmlsZXN5c3RlbSBpbnN0ZWFkLCB3aGljaCB3b3VsZCBtYWtlIHRoZSBpbnRlbmRl ZAogc2VtYW50aWNzIGNsZWFyZXIuCiAKK0NvbXBsZXRlIEV4YW1wbGVzCistLS0tLS0tLS0tLS0t LS0tLS0KKworU2V0IGZzY3J5cHQgcG9saWN5IG9uIGFuIChlbXB0eSkgZW5jcnlwdGVkIGRpcmVj dG9yeSwgL2VuY3J5cHRlZDo6CisKKyAgICAkIGZzY3J5cHRjdGwgc2V0X3BvbGljeSAxMjM0NTY3 ODkwMTIzNDU2IC9lbmNyeXB0ZWQKKworQ3JlYXRlIGFuIGVuY3J5cHRlZCBrZXkgIjEyMzQ1Njc4 OTAxMjM0NTYiIG9mIGxlbmd0aCA2NCBieXRlcyB3aXRoIGZvcm1hdAorJ2ZzY3J5cHQnIGFuZCBy b290IGl0IGluIGEgcHJldmlvdXNseSBsb2FkZWQgdHJ1c3RlZCAia21rIjo6CisKKyAgICAkIGtl eWN0bCBhZGQgZW5jcnlwdGVkICJmc2NyeXB0OjEyMzQ1Njc4OTAxMjM0NTYiICJuZXcgZGVmYXVs dCB0cnVzdGVkOmttayA2NCIgQHUKKyAgICA4Mzk3MTU0NzMKKworICAgICQga2V5Y3RsIHByaW50 IDgzOTcxNTQ3MworICAgIGRlZmF1bHQgdHJ1c3RlZDprbWsgNjQgZTk4YTQ5ZGMxMWViOTMxMmY0 NjUzMDg3OWFhYzg2OTMwMGVlNzM0MDM1MTAwZjRlZQorICAgIDU0NDEyNzkzNjlhNGM5ZDgzZDZl NTliODE1OGQwYTNkZTAxNzkwYzBiYjk5YWY4MmU5NjAzY2I2OTc3YzdkMTIyOTMzOGNkYQorICAg IDgwMzc1YWFmMDM0Njc4NDA1YTAwYzE5ODA2ZDZmYjEyNDkwZTM5YjFkN2NhNjAzYzQ5MWI1OGE5 NjIzNDUxNjBlMzQ0YWU1MQorICAgIDgzNDgzZTA2NjY5MmQwNWY1YWIzZDhiOWVhMzljYWIwZQor CisgICAgJCBrZXljdGwgcGlwZSA4Mzk3MTU0NzMgPiBmc2NyeXB0LmJsb2IKKworVGhlIGRpcmVj dG9yeSBwb2xpY3kgd2lsbCByZW1haW4gYWNyb3NzIHJlYm9vdHMsIHNvIGFmdGVyIGEgcmVib290 IHRoZSBrZXkKK2dlbmVyYXRlZCBlYXJsaWVyIHdpbGwgc2ltcGx5IGhhdmUgdG8gYmUgbG9hZGVk IGludG8gdGhlIGtlcm5lbCBrZXlyaW5nCithZ2Fpbjo6CisKKyAgICAkIGtleWN0bCBhZGQgZW5j cnlwdGVkIGZzY3J5cHQ6MTIzNDU2Nzg5MDEyMzQ1NiAibG9hZCAkKGNhdCBmc2NyeXB0LmJsb2Ip IiBAdQorCiBBY2Nlc3Mgc2VtYW50aWNzCiA9PT09PT09PQogCmRpZmYgLS1naXQgYS9mcy9jcnlw dG8va2V5aW5mby5jIGIvZnMvY3J5cHRvL2tleWluZm8uYwppbmRleCA1ZTZlODQ2ZjVhMjQuLjNk MjBhZGRhZGNkNCAxMDA2NDQKLS0tIGEvZnMvY3J5cHRvL2tleWluZm8uYworKysgYi9mcy9jcnlw dG8va2V5aW5mby5jCkBAIC0xMCw2ICsxMCw3IEBACiAgKi8KIAogI2luY2x1ZGUgPGtleXMvdXNl ci10eXBlLmg+CisjaW5jbHVkZSA8a2V5cy9lbmNyeXB0ZWQtdHlwZS5oPgogI2luY2x1ZGUgPGxp bnV4L3NjYXR0ZXJsaXN0Lmg+CiAjaW5jbHVkZSA8bGludXgvcmF0ZWxpbWl0Lmg+CiAjaW5jbHVk ZSA8Y3J5cHRvL2Flcy5oPgpAQCAtMjAsMTQgKzIxLDE2IEBAIHN0YXRpYyBzdHJ1Y3QgY3J5cHRv X3NoYXNoICplc3Npdl9oYXNoX3RmbTsKIAogLyoqCiAgKiBkZXJpdmVfa2V5X2FlcygpIC0gRGVy aXZlIGEga2V5IHVzaW5nIEFFUy0xMjgtRUNCCi0gKiBAZGVyaXZpbmdfa2V5OiBFbmNyeXB0aW9u IGtleSB1c2VkIGZvciBkZXJpdmF0aW9uLgotICogQHNvdXJjZV9rZXk6ICAgU291cmNlIGtleSB0 byB3aGljaCB0byBhcHBseSBkZXJpdmF0aW9uLgotICogQGRlcml2ZWRfcmF3X2tleTogIERlcml2 ZWQgcmF3IGtleS4KKyAqIEBkZXJpdmluZ19rZXk6ICAgIEVuY3J5cHRpb24ga2V5IHVzZWQgZm9y IGRlcml2YXRpb24uCisgKiBAc291cmNlX2tleTogICAgICBSYXcgc291cmNlIGtleSB0byB3aGlj aCB0byBhcHBseSBkZXJpdmF0aW9uLgorICogQHNvdXJjZV9rZXlfbGVuOiAgTGVuZ3RoIG9mIHRo ZSBzb3VyY2Uga2V5LgorICogQGRlcml2ZWRfcmF3X2tleTogRGVyaXZlZCByYXcga2V5LgogICoK ICAqIFJldHVybjogWmVybyBvbiBzdWNjZXNzOyBub24temVybyBvdGhlcndpc2UuCiAgKi8KIHN0 YXRpYyBpbnQgZGVyaXZlX2tleV9hZXModTggZGVyaXZpbmdfa2V5W0ZTX0FFU18xMjhfRUNCX0tF WV9TSVpFXSwKLQkJCQljb25zdCBzdHJ1Y3QgZnNjcnlwdF9rZXkgKnNvdXJjZV9rZXksCisJCQkJ Y29uc3QgdTggc291cmNlX2tleVtGU19NQVhfS0VZX1NJWkVdLAorCQkJCXUzMiBzb3VyY2Vfa2V5 X2xlbiwKIAkJCQl1OCBkZXJpdmVkX3Jhd19rZXlbRlNfTUFYX0tFWV9TSVpFXSkKIHsKIAlpbnQg cmVzID0gMDsKQEAgLTU1LDkgKzU4LDkgQEAgc3RhdGljIGludCBkZXJpdmVfa2V5X2Flcyh1OCBk ZXJpdmluZ19rZXlbRlNfQUVTXzEyOF9FQ0JfS0VZX1NJWkVdLAogCWlmIChyZXMgPCAwKQogCQln b3RvIG91dDsKIAotCXNnX2luaXRfb25lKCZzcmNfc2csIHNvdXJjZV9rZXktPnJhdywgc291cmNl X2tleS0+c2l6ZSk7Ci0Jc2dfaW5pdF9vbmUoJmRzdF9zZywgZGVyaXZlZF9yYXdfa2V5LCBzb3Vy Y2Vfa2V5LT5zaXplKTsKLQlza2NpcGhlcl9yZXF1ZXN0X3NldF9jcnlwdChyZXEsICZzcmNfc2cs ICZkc3Rfc2csIHNvdXJjZV9rZXktPnNpemUsCisJc2dfaW5pdF9vbmUoJnNyY19zZywgc291cmNl X2tleSwgc291cmNlX2tleV9sZW4pOworCXNnX2luaXRfb25lKCZkc3Rfc2csIGRlcml2ZWRfcmF3 X2tleSwgc291cmNlX2tleV9sZW4pOworCXNrY2lwaGVyX3JlcXVlc3Rfc2V0X2NyeXB0KHJlcSwg JnNyY19zZywgJmRzdF9zZywgc291cmNlX2tleV9sZW4sCiAJCQkJICAgTlVMTCk7CiAJcmVzID0g Y3J5cHRvX3dhaXRfcmVxKGNyeXB0b19za2NpcGhlcl9lbmNyeXB0KHJlcSksICZ3YWl0KTsKIG91 dDoKQEAgLTY2LDE0ICs2OSwyMSBAQCBzdGF0aWMgaW50IGRlcml2ZV9rZXlfYWVzKHU4IGRlcml2 aW5nX2tleVtGU19BRVNfMTI4X0VDQl9LRVlfU0laRV0sCiAJcmV0dXJuIHJlczsKIH0KIAotc3Rh dGljIGludCB2YWxpZGF0ZV91c2VyX2tleShzdHJ1Y3QgZnNjcnlwdF9pbmZvICpjcnlwdF9pbmZv LAorc3RhdGljIGlubGluZSBzdHJ1Y3Qga2V5ICpmc2NyeXB0X2dldF9lbmNyeXB0ZWRfa2V5KGNv bnN0IGNoYXIgKmRlc2NyaXB0aW9uKQoreworCWlmIChJU19FTkFCTEVEKENPTkZJR19FTkNSWVBU RURfS0VZUykpCisJCXJldHVybiByZXF1ZXN0X2tleSgma2V5X3R5cGVfZW5jcnlwdGVkLCBkZXNj cmlwdGlvbiwgTlVMTCk7CisJcmV0dXJuIEVSUl9QVFIoLUVOT0tFWSk7Cit9CisKK3N0YXRpYyBp bnQgdmFsaWRhdGVfa2V5cmluZ19rZXkoc3RydWN0IGZzY3J5cHRfaW5mbyAqY3J5cHRfaW5mbywK IAkJCXN0cnVjdCBmc2NyeXB0X2NvbnRleHQgKmN0eCwgdTggKnJhd19rZXksCiAJCQljb25zdCBj aGFyICpwcmVmaXgsIGludCBtaW5fa2V5c2l6ZSkKIHsKIAljaGFyICpkZXNjcmlwdGlvbjsKIAlz dHJ1Y3Qga2V5ICprZXlyaW5nX2tleTsKLQlzdHJ1Y3QgZnNjcnlwdF9rZXkgKm1hc3Rlcl9rZXk7 Ci0JY29uc3Qgc3RydWN0IHVzZXJfa2V5X3BheWxvYWQgKnVrcDsKKwljb25zdCB1OCAqbWFzdGVy X2tleTsKKwl1MzIgbWFzdGVyX2tleV9sZW47CiAJaW50IHJlczsKIAogCWRlc2NyaXB0aW9uID0g a2FzcHJpbnRmKEdGUF9OT0ZTLCAiJXMlKnBoTiIsIHByZWZpeCwKQEAgLTgzLDM5ICs5Myw1NSBA QCBzdGF0aWMgaW50IHZhbGlkYXRlX3VzZXJfa2V5KHN0cnVjdCBmc2NyeXB0X2luZm8gKmNyeXB0 X2luZm8sCiAJCXJldHVybiAtRU5PTUVNOwogCiAJa2V5cmluZ19rZXkgPSByZXF1ZXN0X2tleSgm a2V5X3R5cGVfbG9nb24sIGRlc2NyaXB0aW9uLCBOVUxMKTsKKwlpZiAoa2V5cmluZ19rZXkgPSBF UlJfUFRSKC1FTk9LRVkpKQorCQlrZXlyaW5nX2tleSA9IGZzY3J5cHRfZ2V0X2VuY3J5cHRlZF9r ZXkoZGVzY3JpcHRpb24pOwogCWtmcmVlKGRlc2NyaXB0aW9uKTsKIAlpZiAoSVNfRVJSKGtleXJp bmdfa2V5KSkKIAkJcmV0dXJuIFBUUl9FUlIoa2V5cmluZ19rZXkpOwogCWRvd25fcmVhZCgma2V5 cmluZ19rZXktPnNlbSk7CiAKLQlpZiAoa2V5cmluZ19rZXktPnR5cGUgIT0gJmtleV90eXBlX2xv Z29uKSB7CisJaWYgKGtleXJpbmdfa2V5LT50eXBlID0gJmtleV90eXBlX2xvZ29uKSB7CisJCWNv bnN0IHN0cnVjdCB1c2VyX2tleV9wYXlsb2FkICp1a3A7CisJCWNvbnN0IHN0cnVjdCBmc2NyeXB0 X2tleSAqZms7CisKKwkJdWtwID0gdXNlcl9rZXlfcGF5bG9hZF9sb2NrZWQoa2V5cmluZ19rZXkp OworCQlpZiAoIXVrcCkgeworCQkJLyoga2V5IHdhcyByZXZva2VkIGJlZm9yZSB3ZSBhY3F1aXJl ZCBpdHMgc2VtYXBob3JlICovCisJCQlyZXMgPSAtRUtFWVJFVk9LRUQ7CisJCQlnb3RvIG91dDsK KwkJfQorCQlpZiAodWtwLT5kYXRhbGVuICE9IHNpemVvZihzdHJ1Y3QgZnNjcnlwdF9rZXkpKSB7 CisJCQlyZXMgPSAtRUlOVkFMOworCQkJZ290byBvdXQ7CisJCX0KKwkJZmsgPSAoc3RydWN0IGZz Y3J5cHRfa2V5ICopdWtwLT5kYXRhOworCQltYXN0ZXJfa2V5ID0gZmstPnJhdzsKKwkJbWFzdGVy X2tleV9sZW4gPSBmay0+c2l6ZTsKKwl9IGVsc2UgaWYgKGtleXJpbmdfa2V5LT50eXBlID0gJmtl eV90eXBlX2VuY3J5cHRlZCkgeworCQljb25zdCBzdHJ1Y3QgZW5jcnlwdGVkX2tleV9wYXlsb2Fk ICpla3A7CisKKwkJZWtwID0ga2V5cmluZ19rZXktPnBheWxvYWQuZGF0YVswXTsKKwkJbWFzdGVy X2tleSA9IGVrcC0+ZGVjcnlwdGVkX2RhdGE7CisJCW1hc3Rlcl9rZXlfbGVuID0gZWtwLT5kZWNy eXB0ZWRfZGF0YWxlbjsKKwl9IGVsc2UgewogCQlwcmludGtfb25jZShLRVJOX1dBUk5JTkcKLQkJ CQkiJXM6IGtleSB0eXBlIG11c3QgYmUgbG9nb25cbiIsIF9fZnVuY19fKTsKKwkJCQkiJXM6IGtl eSB0eXBlIG11c3QgYmUgbG9nb24gb3IgZW5jcnlwdGVkXG4iLAorCQkJCV9fZnVuY19fKTsKIAkJ cmVzID0gLUVOT0tFWTsKIAkJZ290byBvdXQ7CiAJfQotCXVrcCA9IHVzZXJfa2V5X3BheWxvYWRf bG9ja2VkKGtleXJpbmdfa2V5KTsKLQlpZiAoIXVrcCkgewotCQkvKiBrZXkgd2FzIHJldm9rZWQg YmVmb3JlIHdlIGFjcXVpcmVkIGl0cyBzZW1hcGhvcmUgKi8KLQkJcmVzID0gLUVLRVlSRVZPS0VE OwotCQlnb3RvIG91dDsKLQl9Ci0JaWYgKHVrcC0+ZGF0YWxlbiAhPSBzaXplb2Yoc3RydWN0IGZz Y3J5cHRfa2V5KSkgewotCQlyZXMgPSAtRUlOVkFMOwotCQlnb3RvIG91dDsKLQl9Ci0JbWFzdGVy X2tleSA9IChzdHJ1Y3QgZnNjcnlwdF9rZXkgKil1a3AtPmRhdGE7CiAJQlVJTERfQlVHX09OKEZT X0FFU18xMjhfRUNCX0tFWV9TSVpFICE9IEZTX0tFWV9ERVJJVkFUSU9OX05PTkNFX1NJWkUpOwog Ci0JaWYgKG1hc3Rlcl9rZXktPnNpemUgPCBtaW5fa2V5c2l6ZSB8fCBtYXN0ZXJfa2V5LT5zaXpl ID4gRlNfTUFYX0tFWV9TSVpFCi0JICAgIHx8IG1hc3Rlcl9rZXktPnNpemUgJSBBRVNfQkxPQ0tf U0laRSAhPSAwKSB7CisJaWYgKG1hc3Rlcl9rZXlfbGVuIDwgbWluX2tleXNpemUgfHwgbWFzdGVy X2tleV9sZW4gPiBGU19NQVhfS0VZX1NJWkUKKwkgICAgfHwgbWFzdGVyX2tleV9sZW4gJSBBRVNf QkxPQ0tfU0laRSAhPSAwKSB7CiAJCXByaW50a19vbmNlKEtFUk5fV0FSTklORwotCQkJCSIlczog a2V5IHNpemUgaW5jb3JyZWN0OiAlZFxuIiwKLQkJCQlfX2Z1bmNfXywgbWFzdGVyX2tleS0+c2l6 ZSk7CisJCQkJIiVzOiBrZXkgc2l6ZSBpbmNvcnJlY3Q6ICV1XG4iLAorCQkJCV9fZnVuY19fLCBt YXN0ZXJfa2V5X2xlbik7CiAJCXJlcyA9IC1FTk9LRVk7CiAJCWdvdG8gb3V0OwogCX0KLQlyZXMg PSBkZXJpdmVfa2V5X2FlcyhjdHgtPm5vbmNlLCBtYXN0ZXJfa2V5LCByYXdfa2V5KTsKKwlyZXMg PSBkZXJpdmVfa2V5X2FlcyhjdHgtPm5vbmNlLCBtYXN0ZXJfa2V5LCBtYXN0ZXJfa2V5X2xlbiwg cmF3X2tleSk7CisKIG91dDoKIAl1cF9yZWFkKCZrZXlyaW5nX2tleS0+c2VtKTsKIAlrZXlfcHV0 KGtleXJpbmdfa2V5KTsKQEAgLTMwMiwxMiArMzI4LDEyIEBAIGludCBmc2NyeXB0X2dldF9lbmNy eXB0aW9uX2luZm8oc3RydWN0IGlub2RlICppbm9kZSkKIAlpZiAoIXJhd19rZXkpCiAJCWdvdG8g b3V0OwogCi0JcmVzID0gdmFsaWRhdGVfdXNlcl9rZXkoY3J5cHRfaW5mbywgJmN0eCwgcmF3X2tl eSwgRlNfS0VZX0RFU0NfUFJFRklYLAotCQkJCWtleXNpemUpOworCXJlcyA9IHZhbGlkYXRlX2tl eXJpbmdfa2V5KGNyeXB0X2luZm8sICZjdHgsIHJhd19rZXksCisJCQkJICAgRlNfS0VZX0RFU0Nf UFJFRklYLCBrZXlzaXplKTsKIAlpZiAocmVzICYmIGlub2RlLT5pX3NiLT5zX2NvcC0+a2V5X3By ZWZpeCkgewotCQlpbnQgcmVzMiA9IHZhbGlkYXRlX3VzZXJfa2V5KGNyeXB0X2luZm8sICZjdHgs IHJhd19rZXksCi0JCQkJCSAgICAgaW5vZGUtPmlfc2ItPnNfY29wLT5rZXlfcHJlZml4LAotCQkJ CQkgICAgIGtleXNpemUpOworCQlpbnQgcmVzMiA9IHZhbGlkYXRlX2tleXJpbmdfa2V5KGNyeXB0 X2luZm8sICZjdHgsIHJhd19rZXksCisJCQkJCQlpbm9kZS0+aV9zYi0+c19jb3AtPmtleV9wcmVm aXgsCisJCQkJCQlrZXlzaXplKTsKIAkJaWYgKHJlczIpIHsKIAkJCWlmIChyZXMyID0gLUVOT0tF WSkKIAkJCQlyZXMgPSAtRU5PS0VZOwotLSAKMi4xNS4xCgotLQpUbyB1bnN1YnNjcmliZSBmcm9t IHRoaXMgbGlzdDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUga2V5cmluZ3MiIGluCnRoZSBi b2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnCk1vcmUgbWFqb3Jk b21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbA== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Subject: [PATCH v3] fscrypt: add support for the encrypted key type Date: Thu, 18 Jan 2018 13:13:59 +0000 Message-Id: <20180118131359.8365-1-git@andred.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: keyrings-owner@vger.kernel.org To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Draszik?= , Mimi Zohar , David Howells , James Morris , "Serge E. Hallyn" , "Theodore Y. Ts'o" , Jaegeuk Kim , Kees Cook , Eric Biggers , linux-integrity@vger.kernel.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, linux-fscrypt@vger.kernel.org List-ID: fscrypt uses a master key for each directory policy from which all further keys for that policy are derived, and at the moment such a master key has to be inserted into a kernel keyring as a 'logon' key by user-space. While 'logon' keys have the nice property of not being readable by user-space (keyctl dump etc.), the fscrypt master key still needs to be generated initially, in a secure way, and it needs to be saved somewhere for subsequent reboots, and hence also needs securing itself. Usage of the 'logon' key means that it is up to user-space to do all that, opening up the possibility of creating cryptographically non-sound master keys, or not storing the master key securely across reboots. One approach for securing the master key would be to do that using a TPM and while one could manually do so e.g. using tpm-tools, that still leaves creation and actual correct usage of tpm-tools up to user-space, though. As an aside, tpm-tools needs the tcsd daemon running, which makes it awkward to use from within an initramfs, and while other libraries for interfacing with a TPM do exist, there appears to be a better way: The kernel already has a concept of trusted as well as encrypted keys. Trusted keys are TPM backed keys, which can be sealed to PCRs and also easily be re-sealed against new future PCRs, and encrypted keys are keys that are encrypted using another key, e.g. a trusted key. All are generated automatically by the kernel using the RNG and never leave kernel memory space (bar any kernel or hardware bugs). So it seems reasonable to allow the fscrypt subsystem to work with encrypted keys as well. This is what this change here does. We can utilise keys that never ever exist in user-space, not even at initial creation time, as well as simplifying usage / configuration. Something very very similar exists for eCrypts already. With these patches, we can kmk_id=$(keyctl add trusted kmk "new 128 [pcrinfo=...]" @u) fscrypt_id=$(keyctl add encrypted fscrypt:1234567890123456 "new default trusted:kmk 64" @u) fscryptctl set_policy 1234567890123456 /encrypted then we can save those keys for after reboot (optionally TPM-sealed as per the pcrinfo= argument above): keyctl pipe ${kmk_id} > /keys/kmk.blob keyctl pipe ${fscrypt_id} > /keys/fscrypt.blob and on subsequent boots we can simply insert them again (optionally benefitting from the TPM's capability to only unseal kmk.blob when the system is in the expected state, thereby also protecting fscrypt.blob): keyctl add trusted kmk "load $(cat /keys/kmk.blob)" @u keyctl add encrypted fscrypt:1234567890123456 "load $(cat /keys/fscrypt.blob)" @u Signed-off-by: André Draszik Cc: Mimi Zohar Cc: David Howells Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Theodore Y. Ts'o" Cc: Jaegeuk Kim Cc: Kees Cook Cc: Eric Biggers Cc: linux-integrity@vger.kernel.org Cc: keyrings@vger.kernel.org Cc: linux-security-module@vger.kernel.org Cc: linux-fscrypt@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- changes in v3: * merge documentation changes into this commit * update derive_key_aes() signature to not take a struct fscrypt_key and update all callers * try to use the 'encrypted' key as fallback only if the a 'logon' key isn't present (ENOKEY) * update fscrypt_get_encrypted_key() to take a 'description', not a 'sig' * update commit message * re-add keyrings mailing list and encrypted-keys maintainers to Cc changes in v2: * dropped the previously added 'fscrypt' encrypted-key, and just use the 'default' format --- Documentation/filesystems/fscrypt.rst | 56 +++++++++++++++++++-- fs/crypto/keyinfo.c | 92 ++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 38 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 776ddc655f79..852ac2900b66 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -368,11 +368,19 @@ Adding keys To provide a master key, userspace must add it to an appropriate keyring using the add_key() system call (see: ``Documentation/security/keys/core.rst``). The key type must be -"logon"; keys of this type are kept in kernel memory and cannot be -read back by userspace. The key description must be "fscrypt:" -followed by the 16-character lower case hex representation of the -``master_key_descriptor`` that was set in the encryption policy. The -key payload must conform to the following structure:: +either "logon" or "encrypted"; "logon" keys are kept in kernel +memory and cannot be read back by userspace while "encrypted" +keys can be rooted in a "trusted" key and thus are protected by +a TPM and cannot be read by userspace in unencrypted form. Note +that while an "encrypted" key can also be rooted in a "user" key, +any "encrypted" key rooted in a "user" key can effectively be +retrieved in the clear, hence only rooting the key in a "trusted" +key has any useful security properties! + +The key description must be "fscrypt:" followed by the 16-character +lower case hex representation of the ``master_key_descriptor`` that +was set in the encryption policy. For a "logon" key, key payload +must conform to the following structure:: #define FS_MAX_KEY_SIZE 64 @@ -386,6 +394,17 @@ key payload must conform to the following structure:: ``raw`` with ``size`` indicating its size in bytes. That is, the bytes ``raw[0..size-1]`` (inclusive) are the actual key. +When using an "encrypted" key, only the actual ``raw`` key from above +fscrypt_key structure is needed:: + + keyctl add encrypted "fscrypt:``master_key_descriptor``" "new default trusted:``master-key-name`` ``size``" ``ring`` + keyctl add encrypted "fscrypt:``master_key_descriptor``" "load ``hex_blob``" ``ring`` + +Where:: + + master-key-name:= name of the trusted key this fscrypt master key + shall be rooted in + The key description prefix "fscrypt:" may alternatively be replaced with a filesystem-specific prefix such as "ext4:". However, the filesystem-specific prefixes are deprecated and should not be used in @@ -412,6 +431,33 @@ evicted. In the future there probably should be a way to provide keys directly to the filesystem instead, which would make the intended semantics clearer. +Complete Examples +------------------ + +Set fscrypt policy on an (empty) encrypted directory, /encrypted:: + + $ fscryptctl set_policy 1234567890123456 /encrypted + +Create an encrypted key "1234567890123456" of length 64 bytes with format +'fscrypt' and root it in a previously loaded trusted "kmk":: + + $ keyctl add encrypted "fscrypt:1234567890123456" "new default trusted:kmk 64" @u + 839715473 + + $ keyctl print 839715473 + default trusted:kmk 64 e98a49dc11eb9312f46530879aac869300ee734035100f4ee + 5441279369a4c9d83d6e59b8158d0a3de01790c0bb99af82e9603cb6977c7d1229338cda + 80375aaf034678405a00c19806d6fb12490e39b1d7ca603c491b58a962345160e344ae51 + 83483e066692d05f5ab3d8b9ea39cab0e + + $ keyctl pipe 839715473 > fscrypt.blob + +The directory policy will remain across reboots, so after a reboot the key +generated earlier will simply have to be loaded into the kernel keyring +again:: + + $ keyctl add encrypted fscrypt:1234567890123456 "load $(cat fscrypt.blob)" @u + Access semantics ================ diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 5e6e846f5a24..3d20addadcd4 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -20,14 +21,16 @@ static struct crypto_shash *essiv_hash_tfm; /** * derive_key_aes() - Derive a key using AES-128-ECB - * @deriving_key: Encryption key used for derivation. - * @source_key: Source key to which to apply derivation. - * @derived_raw_key: Derived raw key. + * @deriving_key: Encryption key used for derivation. + * @source_key: Raw source key to which to apply derivation. + * @source_key_len: Length of the source key. + * @derived_raw_key: Derived raw key. * * Return: Zero on success; non-zero otherwise. */ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], - const struct fscrypt_key *source_key, + const u8 source_key[FS_MAX_KEY_SIZE], + u32 source_key_len, u8 derived_raw_key[FS_MAX_KEY_SIZE]) { int res = 0; @@ -55,9 +58,9 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], if (res < 0) goto out; - sg_init_one(&src_sg, source_key->raw, source_key->size); - sg_init_one(&dst_sg, derived_raw_key, source_key->size); - skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size, + sg_init_one(&src_sg, source_key, source_key_len); + sg_init_one(&dst_sg, derived_raw_key, source_key_len); + skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key_len, NULL); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); out: @@ -66,14 +69,21 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], return res; } -static int validate_user_key(struct fscrypt_info *crypt_info, +static inline struct key *fscrypt_get_encrypted_key(const char *description) +{ + if (IS_ENABLED(CONFIG_ENCRYPTED_KEYS)) + return request_key(&key_type_encrypted, description, NULL); + return ERR_PTR(-ENOKEY); +} + +static int validate_keyring_key(struct fscrypt_info *crypt_info, struct fscrypt_context *ctx, u8 *raw_key, const char *prefix, int min_keysize) { char *description; struct key *keyring_key; - struct fscrypt_key *master_key; - const struct user_key_payload *ukp; + const u8 *master_key; + u32 master_key_len; int res; description = kasprintf(GFP_NOFS, "%s%*phN", prefix, @@ -83,39 +93,55 @@ static int validate_user_key(struct fscrypt_info *crypt_info, return -ENOMEM; keyring_key = request_key(&key_type_logon, description, NULL); + if (keyring_key == ERR_PTR(-ENOKEY)) + keyring_key = fscrypt_get_encrypted_key(description); kfree(description); if (IS_ERR(keyring_key)) return PTR_ERR(keyring_key); down_read(&keyring_key->sem); - if (keyring_key->type != &key_type_logon) { + if (keyring_key->type == &key_type_logon) { + const struct user_key_payload *ukp; + const struct fscrypt_key *fk; + + ukp = user_key_payload_locked(keyring_key); + if (!ukp) { + /* key was revoked before we acquired its semaphore */ + res = -EKEYREVOKED; + goto out; + } + if (ukp->datalen != sizeof(struct fscrypt_key)) { + res = -EINVAL; + goto out; + } + fk = (struct fscrypt_key *)ukp->data; + master_key = fk->raw; + master_key_len = fk->size; + } else if (keyring_key->type == &key_type_encrypted) { + const struct encrypted_key_payload *ekp; + + ekp = keyring_key->payload.data[0]; + master_key = ekp->decrypted_data; + master_key_len = ekp->decrypted_datalen; + } else { printk_once(KERN_WARNING - "%s: key type must be logon\n", __func__); + "%s: key type must be logon or encrypted\n", + __func__); res = -ENOKEY; goto out; } - ukp = user_key_payload_locked(keyring_key); - if (!ukp) { - /* key was revoked before we acquired its semaphore */ - res = -EKEYREVOKED; - goto out; - } - if (ukp->datalen != sizeof(struct fscrypt_key)) { - res = -EINVAL; - goto out; - } - master_key = (struct fscrypt_key *)ukp->data; BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE); - if (master_key->size < min_keysize || master_key->size > FS_MAX_KEY_SIZE - || master_key->size % AES_BLOCK_SIZE != 0) { + if (master_key_len < min_keysize || master_key_len > FS_MAX_KEY_SIZE + || master_key_len % AES_BLOCK_SIZE != 0) { printk_once(KERN_WARNING - "%s: key size incorrect: %d\n", - __func__, master_key->size); + "%s: key size incorrect: %u\n", + __func__, master_key_len); res = -ENOKEY; goto out; } - res = derive_key_aes(ctx->nonce, master_key, raw_key); + res = derive_key_aes(ctx->nonce, master_key, master_key_len, raw_key); + out: up_read(&keyring_key->sem); key_put(keyring_key); @@ -302,12 +328,12 @@ int fscrypt_get_encryption_info(struct inode *inode) if (!raw_key) goto out; - res = validate_user_key(crypt_info, &ctx, raw_key, FS_KEY_DESC_PREFIX, - keysize); + res = validate_keyring_key(crypt_info, &ctx, raw_key, + FS_KEY_DESC_PREFIX, keysize); if (res && inode->i_sb->s_cop->key_prefix) { - int res2 = validate_user_key(crypt_info, &ctx, raw_key, - inode->i_sb->s_cop->key_prefix, - keysize); + int res2 = validate_keyring_key(crypt_info, &ctx, raw_key, + inode->i_sb->s_cop->key_prefix, + keysize); if (res2) { if (res2 == -ENOKEY) res = -ENOKEY; -- 2.15.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f45.google.com ([74.125.82.45]:42346 "EHLO mail-wm0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754927AbeARNOM (ORCPT ); Thu, 18 Jan 2018 08:14:12 -0500 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Andr=C3=A9=20Draszik?= , Mimi Zohar , David Howells , James Morris , "Serge E. Hallyn" , "Theodore Y. Ts'o" , Jaegeuk Kim , Kees Cook , Eric Biggers , linux-integrity@vger.kernel.org, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, linux-fscrypt@vger.kernel.org Subject: [PATCH v3] fscrypt: add support for the encrypted key type Date: Thu, 18 Jan 2018 13:13:59 +0000 Message-Id: <20180118131359.8365-1-git@andred.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-integrity-owner@vger.kernel.org List-ID: fscrypt uses a master key for each directory policy from which all further keys for that policy are derived, and at the moment such a master key has to be inserted into a kernel keyring as a 'logon' key by user-space. While 'logon' keys have the nice property of not being readable by user-space (keyctl dump etc.), the fscrypt master key still needs to be generated initially, in a secure way, and it needs to be saved somewhere for subsequent reboots, and hence also needs securing itself. Usage of the 'logon' key means that it is up to user-space to do all that, opening up the possibility of creating cryptographically non-sound master keys, or not storing the master key securely across reboots. One approach for securing the master key would be to do that using a TPM and while one could manually do so e.g. using tpm-tools, that still leaves creation and actual correct usage of tpm-tools up to user-space, though. As an aside, tpm-tools needs the tcsd daemon running, which makes it awkward to use from within an initramfs, and while other libraries for interfacing with a TPM do exist, there appears to be a better way: The kernel already has a concept of trusted as well as encrypted keys. Trusted keys are TPM backed keys, which can be sealed to PCRs and also easily be re-sealed against new future PCRs, and encrypted keys are keys that are encrypted using another key, e.g. a trusted key. All are generated automatically by the kernel using the RNG and never leave kernel memory space (bar any kernel or hardware bugs). So it seems reasonable to allow the fscrypt subsystem to work with encrypted keys as well. This is what this change here does. We can utilise keys that never ever exist in user-space, not even at initial creation time, as well as simplifying usage / configuration. Something very very similar exists for eCrypts already. With these patches, we can kmk_id=$(keyctl add trusted kmk "new 128 [pcrinfo=...]" @u) fscrypt_id=$(keyctl add encrypted fscrypt:1234567890123456 "new default trusted:kmk 64" @u) fscryptctl set_policy 1234567890123456 /encrypted then we can save those keys for after reboot (optionally TPM-sealed as per the pcrinfo= argument above): keyctl pipe ${kmk_id} > /keys/kmk.blob keyctl pipe ${fscrypt_id} > /keys/fscrypt.blob and on subsequent boots we can simply insert them again (optionally benefitting from the TPM's capability to only unseal kmk.blob when the system is in the expected state, thereby also protecting fscrypt.blob): keyctl add trusted kmk "load $(cat /keys/kmk.blob)" @u keyctl add encrypted fscrypt:1234567890123456 "load $(cat /keys/fscrypt.blob)" @u Signed-off-by: Andre Draszik Cc: Mimi Zohar Cc: David Howells Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Theodore Y. Ts'o" Cc: Jaegeuk Kim Cc: Kees Cook Cc: Eric Biggers Cc: linux-integrity@vger.kernel.org Cc: keyrings@vger.kernel.org Cc: linux-security-module@vger.kernel.org Cc: linux-fscrypt@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- changes in v3: * merge documentation changes into this commit * update derive_key_aes() signature to not take a struct fscrypt_key and update all callers * try to use the 'encrypted' key as fallback only if the a 'logon' key isn't present (ENOKEY) * update fscrypt_get_encrypted_key() to take a 'description', not a 'sig' * update commit message * re-add keyrings mailing list and encrypted-keys maintainers to Cc changes in v2: * dropped the previously added 'fscrypt' encrypted-key, and just use the 'default' format --- Documentation/filesystems/fscrypt.rst | 56 +++++++++++++++++++-- fs/crypto/keyinfo.c | 92 ++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 38 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 776ddc655f79..852ac2900b66 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -368,11 +368,19 @@ Adding keys To provide a master key, userspace must add it to an appropriate keyring using the add_key() system call (see: ``Documentation/security/keys/core.rst``). The key type must be -"logon"; keys of this type are kept in kernel memory and cannot be -read back by userspace. The key description must be "fscrypt:" -followed by the 16-character lower case hex representation of the -``master_key_descriptor`` that was set in the encryption policy. The -key payload must conform to the following structure:: +either "logon" or "encrypted"; "logon" keys are kept in kernel +memory and cannot be read back by userspace while "encrypted" +keys can be rooted in a "trusted" key and thus are protected by +a TPM and cannot be read by userspace in unencrypted form. Note +that while an "encrypted" key can also be rooted in a "user" key, +any "encrypted" key rooted in a "user" key can effectively be +retrieved in the clear, hence only rooting the key in a "trusted" +key has any useful security properties! + +The key description must be "fscrypt:" followed by the 16-character +lower case hex representation of the ``master_key_descriptor`` that +was set in the encryption policy. For a "logon" key, key payload +must conform to the following structure:: #define FS_MAX_KEY_SIZE 64 @@ -386,6 +394,17 @@ key payload must conform to the following structure:: ``raw`` with ``size`` indicating its size in bytes. That is, the bytes ``raw[0..size-1]`` (inclusive) are the actual key. +When using an "encrypted" key, only the actual ``raw`` key from above +fscrypt_key structure is needed:: + + keyctl add encrypted "fscrypt:``master_key_descriptor``" "new default trusted:``master-key-name`` ``size``" ``ring`` + keyctl add encrypted "fscrypt:``master_key_descriptor``" "load ``hex_blob``" ``ring`` + +Where:: + + master-key-name:= name of the trusted key this fscrypt master key + shall be rooted in + The key description prefix "fscrypt:" may alternatively be replaced with a filesystem-specific prefix such as "ext4:". However, the filesystem-specific prefixes are deprecated and should not be used in @@ -412,6 +431,33 @@ evicted. In the future there probably should be a way to provide keys directly to the filesystem instead, which would make the intended semantics clearer. +Complete Examples +------------------ + +Set fscrypt policy on an (empty) encrypted directory, /encrypted:: + + $ fscryptctl set_policy 1234567890123456 /encrypted + +Create an encrypted key "1234567890123456" of length 64 bytes with format +'fscrypt' and root it in a previously loaded trusted "kmk":: + + $ keyctl add encrypted "fscrypt:1234567890123456" "new default trusted:kmk 64" @u + 839715473 + + $ keyctl print 839715473 + default trusted:kmk 64 e98a49dc11eb9312f46530879aac869300ee734035100f4ee + 5441279369a4c9d83d6e59b8158d0a3de01790c0bb99af82e9603cb6977c7d1229338cda + 80375aaf034678405a00c19806d6fb12490e39b1d7ca603c491b58a962345160e344ae51 + 83483e066692d05f5ab3d8b9ea39cab0e + + $ keyctl pipe 839715473 > fscrypt.blob + +The directory policy will remain across reboots, so after a reboot the key +generated earlier will simply have to be loaded into the kernel keyring +again:: + + $ keyctl add encrypted fscrypt:1234567890123456 "load $(cat fscrypt.blob)" @u + Access semantics ================ diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 5e6e846f5a24..3d20addadcd4 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -20,14 +21,16 @@ static struct crypto_shash *essiv_hash_tfm; /** * derive_key_aes() - Derive a key using AES-128-ECB - * @deriving_key: Encryption key used for derivation. - * @source_key: Source key to which to apply derivation. - * @derived_raw_key: Derived raw key. + * @deriving_key: Encryption key used for derivation. + * @source_key: Raw source key to which to apply derivation. + * @source_key_len: Length of the source key. + * @derived_raw_key: Derived raw key. * * Return: Zero on success; non-zero otherwise. */ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], - const struct fscrypt_key *source_key, + const u8 source_key[FS_MAX_KEY_SIZE], + u32 source_key_len, u8 derived_raw_key[FS_MAX_KEY_SIZE]) { int res = 0; @@ -55,9 +58,9 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], if (res < 0) goto out; - sg_init_one(&src_sg, source_key->raw, source_key->size); - sg_init_one(&dst_sg, derived_raw_key, source_key->size); - skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size, + sg_init_one(&src_sg, source_key, source_key_len); + sg_init_one(&dst_sg, derived_raw_key, source_key_len); + skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key_len, NULL); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); out: @@ -66,14 +69,21 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], return res; } -static int validate_user_key(struct fscrypt_info *crypt_info, +static inline struct key *fscrypt_get_encrypted_key(const char *description) +{ + if (IS_ENABLED(CONFIG_ENCRYPTED_KEYS)) + return request_key(&key_type_encrypted, description, NULL); + return ERR_PTR(-ENOKEY); +} + +static int validate_keyring_key(struct fscrypt_info *crypt_info, struct fscrypt_context *ctx, u8 *raw_key, const char *prefix, int min_keysize) { char *description; struct key *keyring_key; - struct fscrypt_key *master_key; - const struct user_key_payload *ukp; + const u8 *master_key; + u32 master_key_len; int res; description = kasprintf(GFP_NOFS, "%s%*phN", prefix, @@ -83,39 +93,55 @@ static int validate_user_key(struct fscrypt_info *crypt_info, return -ENOMEM; keyring_key = request_key(&key_type_logon, description, NULL); + if (keyring_key == ERR_PTR(-ENOKEY)) + keyring_key = fscrypt_get_encrypted_key(description); kfree(description); if (IS_ERR(keyring_key)) return PTR_ERR(keyring_key); down_read(&keyring_key->sem); - if (keyring_key->type != &key_type_logon) { + if (keyring_key->type == &key_type_logon) { + const struct user_key_payload *ukp; + const struct fscrypt_key *fk; + + ukp = user_key_payload_locked(keyring_key); + if (!ukp) { + /* key was revoked before we acquired its semaphore */ + res = -EKEYREVOKED; + goto out; + } + if (ukp->datalen != sizeof(struct fscrypt_key)) { + res = -EINVAL; + goto out; + } + fk = (struct fscrypt_key *)ukp->data; + master_key = fk->raw; + master_key_len = fk->size; + } else if (keyring_key->type == &key_type_encrypted) { + const struct encrypted_key_payload *ekp; + + ekp = keyring_key->payload.data[0]; + master_key = ekp->decrypted_data; + master_key_len = ekp->decrypted_datalen; + } else { printk_once(KERN_WARNING - "%s: key type must be logon\n", __func__); + "%s: key type must be logon or encrypted\n", + __func__); res = -ENOKEY; goto out; } - ukp = user_key_payload_locked(keyring_key); - if (!ukp) { - /* key was revoked before we acquired its semaphore */ - res = -EKEYREVOKED; - goto out; - } - if (ukp->datalen != sizeof(struct fscrypt_key)) { - res = -EINVAL; - goto out; - } - master_key = (struct fscrypt_key *)ukp->data; BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE); - if (master_key->size < min_keysize || master_key->size > FS_MAX_KEY_SIZE - || master_key->size % AES_BLOCK_SIZE != 0) { + if (master_key_len < min_keysize || master_key_len > FS_MAX_KEY_SIZE + || master_key_len % AES_BLOCK_SIZE != 0) { printk_once(KERN_WARNING - "%s: key size incorrect: %d\n", - __func__, master_key->size); + "%s: key size incorrect: %u\n", + __func__, master_key_len); res = -ENOKEY; goto out; } - res = derive_key_aes(ctx->nonce, master_key, raw_key); + res = derive_key_aes(ctx->nonce, master_key, master_key_len, raw_key); + out: up_read(&keyring_key->sem); key_put(keyring_key); @@ -302,12 +328,12 @@ int fscrypt_get_encryption_info(struct inode *inode) if (!raw_key) goto out; - res = validate_user_key(crypt_info, &ctx, raw_key, FS_KEY_DESC_PREFIX, - keysize); + res = validate_keyring_key(crypt_info, &ctx, raw_key, + FS_KEY_DESC_PREFIX, keysize); if (res && inode->i_sb->s_cop->key_prefix) { - int res2 = validate_user_key(crypt_info, &ctx, raw_key, - inode->i_sb->s_cop->key_prefix, - keysize); + int res2 = validate_keyring_key(crypt_info, &ctx, raw_key, + inode->i_sb->s_cop->key_prefix, + keysize); if (res2) { if (res2 == -ENOKEY) res = -ENOKEY; -- 2.15.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: git@andred.net (=?UTF-8?q?Andr=C3=A9=20Draszik?=) Date: Thu, 18 Jan 2018 13:13:59 +0000 Subject: [PATCH v3] fscrypt: add support for the encrypted key type Message-ID: <20180118131359.8365-1-git@andred.net> To: linux-security-module@vger.kernel.org List-Id: linux-security-module.vger.kernel.org fscrypt uses a master key for each directory policy from which all further keys for that policy are derived, and at the moment such a master key has to be inserted into a kernel keyring as a 'logon' key by user-space. While 'logon' keys have the nice property of not being readable by user-space (keyctl dump etc.), the fscrypt master key still needs to be generated initially, in a secure way, and it needs to be saved somewhere for subsequent reboots, and hence also needs securing itself. Usage of the 'logon' key means that it is up to user-space to do all that, opening up the possibility of creating cryptographically non-sound master keys, or not storing the master key securely across reboots. One approach for securing the master key would be to do that using a TPM and while one could manually do so e.g. using tpm-tools, that still leaves creation and actual correct usage of tpm-tools up to user-space, though. As an aside, tpm-tools needs the tcsd daemon running, which makes it awkward to use from within an initramfs, and while other libraries for interfacing with a TPM do exist, there appears to be a better way: The kernel already has a concept of trusted as well as encrypted keys. Trusted keys are TPM backed keys, which can be sealed to PCRs and also easily be re-sealed against new future PCRs, and encrypted keys are keys that are encrypted using another key, e.g. a trusted key. All are generated automatically by the kernel using the RNG and never leave kernel memory space (bar any kernel or hardware bugs). So it seems reasonable to allow the fscrypt subsystem to work with encrypted keys as well. This is what this change here does. We can utilise keys that never ever exist in user-space, not even at initial creation time, as well as simplifying usage / configuration. Something very very similar exists for eCrypts already. With these patches, we can kmk_id=$(keyctl add trusted kmk "new 128 [pcrinfo=...]" @u) fscrypt_id=$(keyctl add encrypted fscrypt:1234567890123456 "new default trusted:kmk 64" @u) fscryptctl set_policy 1234567890123456 /encrypted then we can save those keys for after reboot (optionally TPM-sealed as per the pcrinfo= argument above): keyctl pipe ${kmk_id} > /keys/kmk.blob keyctl pipe ${fscrypt_id} > /keys/fscrypt.blob and on subsequent boots we can simply insert them again (optionally benefitting from the TPM's capability to only unseal kmk.blob when the system is in the expected state, thereby also protecting fscrypt.blob): keyctl add trusted kmk "load $(cat /keys/kmk.blob)" @u keyctl add encrypted fscrypt:1234567890123456 "load $(cat /keys/fscrypt.blob)" @u Signed-off-by: Andr? Draszik Cc: Mimi Zohar Cc: David Howells Cc: James Morris Cc: "Serge E. Hallyn" Cc: "Theodore Y. Ts'o" Cc: Jaegeuk Kim Cc: Kees Cook Cc: Eric Biggers Cc: linux-integrity at vger.kernel.org Cc: keyrings at vger.kernel.org Cc: linux-security-module at vger.kernel.org Cc: linux-fscrypt at vger.kernel.org Cc: linux-kernel at vger.kernel.org --- changes in v3: * merge documentation changes into this commit * update derive_key_aes() signature to not take a struct fscrypt_key and update all callers * try to use the 'encrypted' key as fallback only if the a 'logon' key isn't present (ENOKEY) * update fscrypt_get_encrypted_key() to take a 'description', not a 'sig' * update commit message * re-add keyrings mailing list and encrypted-keys maintainers to Cc changes in v2: * dropped the previously added 'fscrypt' encrypted-key, and just use the 'default' format --- Documentation/filesystems/fscrypt.rst | 56 +++++++++++++++++++-- fs/crypto/keyinfo.c | 92 ++++++++++++++++++++++------------- 2 files changed, 110 insertions(+), 38 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 776ddc655f79..852ac2900b66 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -368,11 +368,19 @@ Adding keys To provide a master key, userspace must add it to an appropriate keyring using the add_key() system call (see: ``Documentation/security/keys/core.rst``). The key type must be -"logon"; keys of this type are kept in kernel memory and cannot be -read back by userspace. The key description must be "fscrypt:" -followed by the 16-character lower case hex representation of the -``master_key_descriptor`` that was set in the encryption policy. The -key payload must conform to the following structure:: +either "logon" or "encrypted"; "logon" keys are kept in kernel +memory and cannot be read back by userspace while "encrypted" +keys can be rooted in a "trusted" key and thus are protected by +a TPM and cannot be read by userspace in unencrypted form. Note +that while an "encrypted" key can also be rooted in a "user" key, +any "encrypted" key rooted in a "user" key can effectively be +retrieved in the clear, hence only rooting the key in a "trusted" +key has any useful security properties! + +The key description must be "fscrypt:" followed by the 16-character +lower case hex representation of the ``master_key_descriptor`` that +was set in the encryption policy. For a "logon" key, key payload +must conform to the following structure:: #define FS_MAX_KEY_SIZE 64 @@ -386,6 +394,17 @@ key payload must conform to the following structure:: ``raw`` with ``size`` indicating its size in bytes. That is, the bytes ``raw[0..size-1]`` (inclusive) are the actual key. +When using an "encrypted" key, only the actual ``raw`` key from above +fscrypt_key structure is needed:: + + keyctl add encrypted "fscrypt:``master_key_descriptor``" "new default trusted:``master-key-name`` ``size``" ``ring`` + keyctl add encrypted "fscrypt:``master_key_descriptor``" "load ``hex_blob``" ``ring`` + +Where:: + + master-key-name:= name of the trusted key this fscrypt master key + shall be rooted in + The key description prefix "fscrypt:" may alternatively be replaced with a filesystem-specific prefix such as "ext4:". However, the filesystem-specific prefixes are deprecated and should not be used in @@ -412,6 +431,33 @@ evicted. In the future there probably should be a way to provide keys directly to the filesystem instead, which would make the intended semantics clearer. +Complete Examples +------------------ + +Set fscrypt policy on an (empty) encrypted directory, /encrypted:: + + $ fscryptctl set_policy 1234567890123456 /encrypted + +Create an encrypted key "1234567890123456" of length 64 bytes with format +'fscrypt' and root it in a previously loaded trusted "kmk":: + + $ keyctl add encrypted "fscrypt:1234567890123456" "new default trusted:kmk 64" @u + 839715473 + + $ keyctl print 839715473 + default trusted:kmk 64 e98a49dc11eb9312f46530879aac869300ee734035100f4ee + 5441279369a4c9d83d6e59b8158d0a3de01790c0bb99af82e9603cb6977c7d1229338cda + 80375aaf034678405a00c19806d6fb12490e39b1d7ca603c491b58a962345160e344ae51 + 83483e066692d05f5ab3d8b9ea39cab0e + + $ keyctl pipe 839715473 > fscrypt.blob + +The directory policy will remain across reboots, so after a reboot the key +generated earlier will simply have to be loaded into the kernel keyring +again:: + + $ keyctl add encrypted fscrypt:1234567890123456 "load $(cat fscrypt.blob)" @u + Access semantics ================ diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c index 5e6e846f5a24..3d20addadcd4 100644 --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -20,14 +21,16 @@ static struct crypto_shash *essiv_hash_tfm; /** * derive_key_aes() - Derive a key using AES-128-ECB - * @deriving_key: Encryption key used for derivation. - * @source_key: Source key to which to apply derivation. - * @derived_raw_key: Derived raw key. + * @deriving_key: Encryption key used for derivation. + * @source_key: Raw source key to which to apply derivation. + * @source_key_len: Length of the source key. + * @derived_raw_key: Derived raw key. * * Return: Zero on success; non-zero otherwise. */ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], - const struct fscrypt_key *source_key, + const u8 source_key[FS_MAX_KEY_SIZE], + u32 source_key_len, u8 derived_raw_key[FS_MAX_KEY_SIZE]) { int res = 0; @@ -55,9 +58,9 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], if (res < 0) goto out; - sg_init_one(&src_sg, source_key->raw, source_key->size); - sg_init_one(&dst_sg, derived_raw_key, source_key->size); - skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key->size, + sg_init_one(&src_sg, source_key, source_key_len); + sg_init_one(&dst_sg, derived_raw_key, source_key_len); + skcipher_request_set_crypt(req, &src_sg, &dst_sg, source_key_len, NULL); res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); out: @@ -66,14 +69,21 @@ static int derive_key_aes(u8 deriving_key[FS_AES_128_ECB_KEY_SIZE], return res; } -static int validate_user_key(struct fscrypt_info *crypt_info, +static inline struct key *fscrypt_get_encrypted_key(const char *description) +{ + if (IS_ENABLED(CONFIG_ENCRYPTED_KEYS)) + return request_key(&key_type_encrypted, description, NULL); + return ERR_PTR(-ENOKEY); +} + +static int validate_keyring_key(struct fscrypt_info *crypt_info, struct fscrypt_context *ctx, u8 *raw_key, const char *prefix, int min_keysize) { char *description; struct key *keyring_key; - struct fscrypt_key *master_key; - const struct user_key_payload *ukp; + const u8 *master_key; + u32 master_key_len; int res; description = kasprintf(GFP_NOFS, "%s%*phN", prefix, @@ -83,39 +93,55 @@ static int validate_user_key(struct fscrypt_info *crypt_info, return -ENOMEM; keyring_key = request_key(&key_type_logon, description, NULL); + if (keyring_key == ERR_PTR(-ENOKEY)) + keyring_key = fscrypt_get_encrypted_key(description); kfree(description); if (IS_ERR(keyring_key)) return PTR_ERR(keyring_key); down_read(&keyring_key->sem); - if (keyring_key->type != &key_type_logon) { + if (keyring_key->type == &key_type_logon) { + const struct user_key_payload *ukp; + const struct fscrypt_key *fk; + + ukp = user_key_payload_locked(keyring_key); + if (!ukp) { + /* key was revoked before we acquired its semaphore */ + res = -EKEYREVOKED; + goto out; + } + if (ukp->datalen != sizeof(struct fscrypt_key)) { + res = -EINVAL; + goto out; + } + fk = (struct fscrypt_key *)ukp->data; + master_key = fk->raw; + master_key_len = fk->size; + } else if (keyring_key->type == &key_type_encrypted) { + const struct encrypted_key_payload *ekp; + + ekp = keyring_key->payload.data[0]; + master_key = ekp->decrypted_data; + master_key_len = ekp->decrypted_datalen; + } else { printk_once(KERN_WARNING - "%s: key type must be logon\n", __func__); + "%s: key type must be logon or encrypted\n", + __func__); res = -ENOKEY; goto out; } - ukp = user_key_payload_locked(keyring_key); - if (!ukp) { - /* key was revoked before we acquired its semaphore */ - res = -EKEYREVOKED; - goto out; - } - if (ukp->datalen != sizeof(struct fscrypt_key)) { - res = -EINVAL; - goto out; - } - master_key = (struct fscrypt_key *)ukp->data; BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE); - if (master_key->size < min_keysize || master_key->size > FS_MAX_KEY_SIZE - || master_key->size % AES_BLOCK_SIZE != 0) { + if (master_key_len < min_keysize || master_key_len > FS_MAX_KEY_SIZE + || master_key_len % AES_BLOCK_SIZE != 0) { printk_once(KERN_WARNING - "%s: key size incorrect: %d\n", - __func__, master_key->size); + "%s: key size incorrect: %u\n", + __func__, master_key_len); res = -ENOKEY; goto out; } - res = derive_key_aes(ctx->nonce, master_key, raw_key); + res = derive_key_aes(ctx->nonce, master_key, master_key_len, raw_key); + out: up_read(&keyring_key->sem); key_put(keyring_key); @@ -302,12 +328,12 @@ int fscrypt_get_encryption_info(struct inode *inode) if (!raw_key) goto out; - res = validate_user_key(crypt_info, &ctx, raw_key, FS_KEY_DESC_PREFIX, - keysize); + res = validate_keyring_key(crypt_info, &ctx, raw_key, + FS_KEY_DESC_PREFIX, keysize); if (res && inode->i_sb->s_cop->key_prefix) { - int res2 = validate_user_key(crypt_info, &ctx, raw_key, - inode->i_sb->s_cop->key_prefix, - keysize); + int res2 = validate_keyring_key(crypt_info, &ctx, raw_key, + inode->i_sb->s_cop->key_prefix, + keysize); if (res2) { if (res2 == -ENOKEY) res = -ENOKEY; -- 2.15.1 -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html