diff options
author | Lei YU <mine260309@gmail.com> | 2019-03-18 15:22:56 +0800 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2019-04-04 20:13:55 +0000 |
commit | 2b2d2298f5c6e9e596ed3ae84326a6ae804c46a4 (patch) | |
tree | 29dbffbb025678743a19d2fac3ca0f4cf64be017 | |
parent | 799eb1972c141271068cd4ea1010753e0347d8ab (diff) | |
download | openpower-pnor-code-mgmt-2b2d2298f5c6e9e596ed3ae84326a6ae804c46a4.tar.gz openpower-pnor-code-mgmt-2b2d2298f5c6e9e596ed3ae84326a6ae804c46a4.zip |
Static layout: support image verification
Add support of image verification for static layout PNOR code update.
Tested: Verify the PNOR code update succeeds with valid-signed PNOR;
and fails with invalid-signed PNOR or a PNOR tarball without
signature.
Change-Id: I1aafeb4e8e07eaa16c170f33f4f21940f7c9c146
Signed-off-by: Lei YU <mine260309@gmail.com>
-rw-r--r-- | activation.cpp | 5 | ||||
-rw-r--r-- | activation.hpp | 4 | ||||
-rw-r--r-- | image_verify.cpp | 7 | ||||
-rw-r--r-- | image_verify.hpp | 10 | ||||
-rw-r--r-- | static/activation_static.cpp | 56 | ||||
-rw-r--r-- | static/activation_static.hpp | 6 | ||||
-rw-r--r-- | test/test_signature.cpp | 3 | ||||
-rw-r--r-- | ubi/activation_ubi.cpp | 2 | ||||
-rw-r--r-- | ubi/activation_ubi.hpp | 2 | ||||
-rw-r--r-- | ubi/item_updater_ubi.cpp | 2 |
10 files changed, 60 insertions, 37 deletions
diff --git a/activation.cpp b/activation.cpp index 2c05ea745..b9cd5ba7d 100644 --- a/activation.cpp +++ b/activation.cpp @@ -176,12 +176,13 @@ uint8_t RedundancyPriority::priority(uint8_t value) } #ifdef WANT_SIGNATURE_VERIFY -bool Activation::validateSignature() +bool Activation::validateSignature(const std::string& pnorFileName) { using Signature = openpower::software::image::Signature; fs::path imageDir(IMG_DIR); - Signature signature(imageDir / versionId, PNOR_SIGNED_IMAGE_CONF_PATH); + Signature signature(imageDir / versionId, pnorFileName, + PNOR_SIGNED_IMAGE_CONF_PATH); // Validate the signed image. if (signature.verify()) diff --git a/activation.hpp b/activation.hpp index 1fcae61c5..a9fb34712 100644 --- a/activation.hpp +++ b/activation.hpp @@ -299,12 +299,14 @@ class Activation : public ActivationInherit * update process in lab environment by checking the * fieldModeEnabled property. * + * @param[in] pnorFileName - The PNOR filename in image dir + * * @return true if successful signature validation or field * mode is disabled. * false for unsuccessful signature validation or * any internal failure during the mapper call. */ - bool validateSignature(); + bool validateSignature(const std::string& pnorFileName); /** * @brief Gets the fieldModeEnabled property value. diff --git a/image_verify.cpp b/image_verify.cpp index 4ad22d177..4fb2d9c35 100644 --- a/image_verify.cpp +++ b/image_verify.cpp @@ -31,9 +31,10 @@ constexpr auto keyTypeTag = "KeyType"; constexpr auto hashFunctionTag = "HashType"; Signature::Signature(const fs::path& imageDirPath, + const std::string& pnorFileName, const fs::path& signedConfPath) : imageDirPath(imageDirPath), - signedConfPath(signedConfPath) + pnorFileName(pnorFileName), signedConfPath(signedConfPath) { fs::path file(imageDirPath / MANIFEST_FILE); @@ -103,7 +104,7 @@ bool Signature::verify() // Validate the PNOR image file. // Build Image File name fs::path file(imageDirPath); - file /= squashFSImage; + file /= pnorFileName; // Build Signature File name std::string fileName = file.filename(); @@ -115,7 +116,7 @@ bool Signature::verify() if (valid == false) { log<level::ERR>("Image file Signature Validation failed", - entry("IMAGE=%s", squashFSImage)); + entry("IMAGE=%s", pnorFileName.c_str())); return false; } diff --git a/image_verify.hpp b/image_verify.hpp index 31b5742c2..0aff4b84e 100644 --- a/image_verify.hpp +++ b/image_verify.hpp @@ -31,9 +31,6 @@ using EVP_PKEY_Ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>; using EVP_MD_CTX_Ptr = std::unique_ptr<EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>; -// PNOR flash image file name. -constexpr auto squashFSImage = "pnor.xz.squashfs"; - /** @struct CustomFd * * RAII wrapper for file descriptor. @@ -133,7 +130,9 @@ class Signature * @param[in] signedConfPath - Path of public key * hash function files */ - Signature(const fs::path& imageDirPath, const fs::path& signedConfPath); + explicit Signature(const fs::path& imageDirPath, + const std::string& pnorFileName, + const fs::path& signedConfPath); /** * @brief Image signature verification function. @@ -205,6 +204,9 @@ class Signature /** @brief Directory where software images are placed*/ fs::path imageDirPath; + /** @brief The PNOR file name in imageDirPath */ + std::string pnorFileName; + /** @brief Path of public key and hash function files */ fs::path signedConfPath; diff --git a/static/activation_static.cpp b/static/activation_static.cpp index 193d6b32a..19bb19e28 100644 --- a/static/activation_static.cpp +++ b/static/activation_static.cpp @@ -2,7 +2,6 @@ #include "item_updater.hpp" -#include <filesystem> #include <phosphor-logging/log.hpp> namespace openpower @@ -11,7 +10,6 @@ namespace software { namespace updater { -namespace fs = std::filesystem; namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server; using namespace phosphor::logging; @@ -27,6 +25,36 @@ auto ActivationStatic::activation(Activations value) -> Activations if (value == softwareServer::Activation::Activations::Activating) { + fs::path imagePath(IMG_DIR); + imagePath /= versionId; + + for (const auto& entry : fs::directory_iterator(imagePath)) + { + if (entry.path().extension() == ".pnor") + { + pnorFilePath = entry; + break; + } + } + if (pnorFilePath.empty()) + { + log<level::ERR>("Unable to find pnor file", + entry("DIR=%s", imagePath.c_str())); + ret = softwareServer::Activation::Activations::Failed; + goto out; + } +#ifdef WANT_SIGNATURE_VERIFY + // Validate the signed image. + if (!validateSignature(pnorFilePath.filename())) + { + // Cleanup + activationBlocksTransition.reset(nullptr); + activationProgress.reset(nullptr); + + ret = softwareServer::Activation::Activations::Failed; + goto out; + } +#endif if (parent.freeSpace()) { startActivation(); @@ -42,30 +70,12 @@ auto ActivationStatic::activation(Activations value) -> Activations activationProgress.reset(nullptr); } +out: return softwareServer::Activation::activation(ret); } void ActivationStatic::startActivation() { - fs::path pnorFile; - fs::path imagePath(IMG_DIR); - imagePath /= versionId; - - for (const auto& entry : fs::directory_iterator(imagePath)) - { - if (entry.path().extension() == ".pnor") - { - pnorFile = entry; - break; - } - } - if (pnorFile.empty()) - { - log<level::ERR>("Unable to find pnor file", - entry("DIR=%s", imagePath.c_str())); - return; - } - if (!activationProgress) { activationProgress = std::make_unique<ActivationProgress>(bus, path); @@ -82,9 +92,9 @@ void ActivationStatic::startActivation() subscribeToSystemdSignals(); log<level::INFO>("Start programming...", - entry("PNOR=%s", pnorFile.c_str())); + entry("PNOR=%s", pnorFilePath.c_str())); - std::string pnorFileEscaped = pnorFile.string(); + std::string pnorFileEscaped = pnorFilePath.string(); // Escape all '/' to '-' std::replace(pnorFileEscaped.begin(), pnorFileEscaped.end(), '/', '-'); diff --git a/static/activation_static.hpp b/static/activation_static.hpp index 6fe713899..258a6126d 100644 --- a/static/activation_static.hpp +++ b/static/activation_static.hpp @@ -2,6 +2,8 @@ #include "activation.hpp" +#include <filesystem> + namespace openpower { namespace software @@ -9,6 +11,8 @@ namespace software namespace updater { +namespace fs = std::filesystem; + /** @class ActivationStatic * @brief Implementation for static PNOR layout */ @@ -25,6 +29,8 @@ class ActivationStatic : public Activation void finishActivation() override; std::string pnorUpdateUnit; + + fs::path pnorFilePath; }; } // namespace updater diff --git a/test/test_signature.cpp b/test/test_signature.cpp index b199c7467..9e8de4bcc 100644 --- a/test/test_signature.cpp +++ b/test/test_signature.cpp @@ -82,7 +82,8 @@ class SignatureTest : public testing::Test command(opensslCmd + pkeyFile + " -out " + pubkeyFile + ".sig " + pubkeyFile); - signature = std::make_unique<Signature>(extractPath, signedConfPath); + signature = std::make_unique<Signature>(extractPath, "pnor.xz.squashfs", + signedConfPath); } virtual void TearDown() { diff --git a/ubi/activation_ubi.cpp b/ubi/activation_ubi.cpp index 9ce7085b8..5c57c4b56 100644 --- a/ubi/activation_ubi.cpp +++ b/ubi/activation_ubi.cpp @@ -40,7 +40,7 @@ auto ActivationUbi::activation(Activations value) -> Activations #ifdef WANT_SIGNATURE_VERIFY // Validate the signed image. - if (!validateSignature()) + if (!validateSignature(squashFSImage)) { // Cleanup activationBlocksTransition.reset(nullptr); diff --git a/ubi/activation_ubi.hpp b/ubi/activation_ubi.hpp index c0ffa012d..a6ef436c1 100644 --- a/ubi/activation_ubi.hpp +++ b/ubi/activation_ubi.hpp @@ -9,6 +9,8 @@ namespace software namespace updater { +constexpr auto squashFSImage = "pnor.xz.squashfs"; + class RedundancyPriorityUbi : public RedundancyPriority { public: diff --git a/ubi/item_updater_ubi.cpp b/ubi/item_updater_ubi.cpp index 188b0bffd..227bc1a69 100644 --- a/ubi/item_updater_ubi.cpp +++ b/ubi/item_updater_ubi.cpp @@ -30,8 +30,6 @@ namespace fs = std::experimental::filesystem; using namespace sdbusplus::xyz::openbmc_project::Common::Error; using namespace phosphor::logging; -constexpr auto squashFSImage = "pnor.xz.squashfs"; - std::unique_ptr<Activation> ItemUpdaterUbi::createActivationObject( const std::string& path, const std::string& versionId, const std::string& extVersion, |