Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp726070imm; Wed, 18 Jul 2018 09:35:48 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdPWOfGaGsK6w3l56GycKNr9jZ75c+OrxgDyNL57gKXKLPeWDXxrLYTLuNpBUx51UfRxG1L X-Received: by 2002:a17:902:b944:: with SMTP id h4-v6mr6433805pls.157.1531931748322; Wed, 18 Jul 2018 09:35:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531931748; cv=none; d=google.com; s=arc-20160816; b=xTi554k9pbtHDrqVw0lARlpuuVxdGTMBDqpm9MpY/N9UblUyppvxkuZmGx3OGiVkPL Q/shzZZYwkJ/+CnWDudYD85FWt3vvB9Ft3WX5TMvErT6rBGfV+F/lQKRIoRGyIK1CFpc YXRdeyl9o1wsWa+7SfXCs5ZnIWEudKC1YvIi1vhsxlb51c/0LFVkGpZhvxR7+B22Cyg3 FcEySD6p47lyJU3dRIwKcbiNMxpdFOSWE7PsuJJOf6r9/6K+HKfbj0jRWstKpnID73Zw BT1YpJdiY6H0HhBYDSctvMx0FkoOD5AGvl3BF6Xk+JXyAQMxbc2KBefc3Mp1V8rt+3Io JSUw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=v6pIBIsv8h4km1ida8UTaKjLyXmNYAJH1iYg+wepAH0=; b=qyAKD52DyPjs/XRrCKxQYFLVgLgAaAjpzB9S4s3+TtxpsBT1GAFPjxYiBaw04iVPlB 3EFQtfsAPuyFdBqQZORg2WSvr/UbbSJEX4m31PchJTUdLnS5hLlEhDBnYC4/ELSBTv8/ KqXgJwqg/Ju9rd9MhGtrvcGw2L8GfSEiQGsP4gNHq638m9F5Ryphs+SbpI/iSgb6DYbI 9LkVl8YS55aGObW9rV6tIaFL0yNS84w3zZyj/xyP3fj4pxzqnwFhJj9D95tif0ajEKRS W4DUzX/OWinLsdixrHSgcPl+tjmnO6/k5NCcFxxGSHTXfS5ZLgopuaEeN5aqGio0cjNF bnxw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c13-v6si3590689pfi.256.2018.07.18.09.35.33; Wed, 18 Jul 2018 09:35:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731644AbeGRRNC (ORCPT + 99 others); Wed, 18 Jul 2018 13:13:02 -0400 Received: from mga04.intel.com ([192.55.52.120]:51996 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731570AbeGRRNC (ORCPT ); Wed, 18 Jul 2018 13:13:02 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Jul 2018 09:34:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,371,1526367600"; d="scan'208";a="57520063" Received: from sandybridge-desktop.sh.intel.com ([10.239.160.116]) by orsmga007.jf.intel.com with ESMTP; 18 Jul 2018 09:34:09 -0700 From: Chen Yu To: linux-pm@vger.kernel.org Cc: Rui Zhang , "Gu, Kookoo" , Chen Yu , "Rafael J . Wysocki" , Pavel Machek , Len Brown , "Lee, Chun-Yi" , Eric Biggers , "Theodore Ts'o" , Stephan Mueller , Denis Kenzior , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4][RFC v2] PM / hibernate: Install crypto hooks for hibernation encryption Date: Thu, 19 Jul 2018 00:39:54 +0800 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The encryption helper functions are installed into hibernation framework for later use. Suggested-by: Rafael J. Wysocki Cc: Rafael J. Wysocki Cc: Pavel Machek Cc: Len Brown Cc: "Lee, Chun-Yi" Cc: Eric Biggers Cc: "Theodore Ts'o" Cc: Stephan Mueller Cc: Denis Kenzior Cc: linux-pm@vger.kernel.org Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Chen Yu --- include/linux/suspend.h | 40 +++++++++++++++++++++++ kernel/power/crypto_hibernation.c | 10 ++++++ kernel/power/hibernate.c | 67 +++++++++++++++++++++++++++++++++++++++ kernel/power/power.h | 2 ++ 4 files changed, 119 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 440b62f..b45a857 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -391,6 +391,46 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); extern bool hibernation_available(void); +#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION) +struct hibernation_crypto_ops { + int (*crypto_data)( + const char *inbuf, int inlen, + char *outbuf, int outlen, + unsigned int cmd, + int page_idx); + void (*save)(void *buf); + void (*restore)(void *buf); + int (*init)(bool suspend); +}; + +extern void hibernation_set_crypto_ops( + const struct hibernation_crypto_ops *ops); +extern int hibernation_crypto_data( + const char *inbuf, + int inlen, + char *outbuf, + int outlen, + unsigned int cmd, + int page_idx); +extern void hibernation_crypto_save(void *outbuf); +extern void hibernation_crypto_restore(void *inbuf); +extern int hibernation_crypto_init(bool suspend); +extern int hibernation_crypto_mode; +#else +static inline int hibernation_crypto_data( + const char *inbuf, + int inlen, + char *outbuf, + int outlen, + unsigned int cmd, + int page_idx) { return 0; } +static inline void hibernation_crypto_save(void *outbuf) {} +static inline void hibernation_crypto_restore(void *inbuf) {} +static inline int hibernation_crypto_init(bool suspend) +{ + return 0; +} +#endif asmlinkage int swsusp_save(void); extern struct pbe *restore_pblist; #else /* CONFIG_HIBERNATION */ diff --git a/kernel/power/crypto_hibernation.c b/kernel/power/crypto_hibernation.c index 406bb0c..845eb54 100644 --- a/kernel/power/crypto_hibernation.c +++ b/kernel/power/crypto_hibernation.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -288,6 +289,13 @@ static int crypto_init(bool suspend) return 0; } +static const struct hibernation_crypto_ops crypto_ops = { + .crypto_data = crypto_data, + .save = crypto_save, + .restore = crypto_restore, + .init = crypto_init, +}; + /* key/salt probing via ioctl. */ dev_t crypto_dev; static struct class *crypto_dev_class; @@ -384,6 +392,8 @@ static int crypto_hibernate_init(void) /* generate the random salt */ get_random_bytes(get_salt_ptr(), HIBERNATE_MAX_SALT_BYTES); + hibernation_set_crypto_ops(&crypto_ops); + return 0; r_device: diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 9c85c78..a9e82f8 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -59,6 +59,16 @@ enum { /* keep last */ __HIBERNATION_AFTER_LAST }; + +#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION) +enum { + HIBERNATION_ENCRYPT, + HIBERNATION_SIGNATURE, + HIBERNATION_ENCRYPT_SIGNATURE, +}; +int hibernation_crypto_mode = HIBERNATION_ENCRYPT; +#endif + #define HIBERNATION_MAX (__HIBERNATION_AFTER_LAST-1) #define HIBERNATION_FIRST (HIBERNATION_INVALID + 1) @@ -96,6 +106,63 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops) } EXPORT_SYMBOL_GPL(hibernation_set_ops); +#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION) +/* Install encryption/decryption/signature hooks. */ +static const struct hibernation_crypto_ops *hibernation_crypto_ops; + +void hibernation_set_crypto_ops(const struct hibernation_crypto_ops *ops) +{ + hibernation_crypto_ops = ops; +} +EXPORT_SYMBOL_GPL(hibernation_set_crypto_ops); + +int hibernation_crypto_data( + const char *inbuf, + int inlen, + char *outbuf, + int outlen, + unsigned int mode, + int page_idx) +{ + if (hibernation_crypto_ops && + hibernation_crypto_ops->crypto_data) + return hibernation_crypto_ops->crypto_data(inbuf, + inlen, outbuf, outlen, mode, page_idx); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(hibernation_crypto_data); + +/* Invoked before hibernate. */ +void hibernation_crypto_save(void *outbuf) +{ + if (hibernation_crypto_ops && + hibernation_crypto_ops->save) + hibernation_crypto_ops->save(outbuf); +} +EXPORT_SYMBOL_GPL(hibernation_crypto_save); + +/* Invoked before resumed. */ +void hibernation_crypto_restore(void *inbuf) +{ + if (hibernation_crypto_ops && + hibernation_crypto_ops->restore) + hibernation_crypto_ops->restore(inbuf); +} +EXPORT_SYMBOL_GPL(hibernation_crypto_restore); + +/* Initialization for crypto helper facilities. */ +int hibernation_crypto_init(bool suspend) +{ + if (hibernation_crypto_ops && + hibernation_crypto_ops->init) + return hibernation_crypto_ops->init(suspend); + else + return -EINVAL; +} +EXPORT_SYMBOL_GPL(hibernation_crypto_init); + +#endif static bool entering_platform_hibernation; bool system_entering_hibernation(void) diff --git a/kernel/power/power.h b/kernel/power/power.h index a539bdb..ba3b24c 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -107,6 +107,8 @@ struct hibernation_crypto { struct hibernation_crypto_keys keys; }; +extern void hibernation_set_crypto_ops( + const struct hibernation_crypto_ops *ops); #else #define HIBERNATE_MAX_SALT_BYTES 0 #endif -- 2.7.4