use ipmiblob library from ipmi-blob-tool

Drop all code that is now handled by the ipmiblob library provided by
the new ipmi-blob-tool.  This is a library that can be included on the
BMC if necessary, but relies on nothing that is strictly meant for the
BMC.

Change-Id: I2b02ae0d432e84c08e598d27eef85b57c06a70fc
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/Makefile.am b/Makefile.am
index a5d2779..d777c20 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,6 @@
 	ipmi.cpp \
 	manager.cpp \
 	process.cpp \
-	crc.cpp \
 	utils.cpp \
 	internal/sys.cpp \
 	fs.cpp
@@ -45,6 +44,7 @@
 	$(PHOSPHOR_LOGGING_LIBS) \
 	$(LIBIPMID_LIBS) \
 	$(CODE_COVERAGE_LIBS) \
+	$(IPMIBLOB_LIBS) \
 	-lstdc++fs \
 	-export-dynamic \
 	-version-info 0:0:0 -shared
@@ -54,6 +54,7 @@
 	$(PHOSPHOR_LOGGING_CFLAGS) \
 	$(LIBIPMID_CFLAGS) \
 	$(CODE_COVERAGE_CXXFLAGS) \
+	$(IPMIBLOB_CFLAGS) \
 	-flto
 
 nobase_include_HEADERS = \
diff --git a/crc.cpp b/crc.cpp
deleted file mode 100644
index 5fc4558..0000000
--- a/crc.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "crc.hpp"
-
-namespace blobs
-{
-
-void Crc16::clear()
-{
-    value = crc16Initial;
-}
-
-// Origin: security/crypta/ipmi/portable/ipmi_utils.c
-void Crc16::compute(const uint8_t* bytes, uint32_t length)
-{
-    if (!bytes)
-    {
-        return;
-    }
-
-    const int kExtraRounds = 2;
-    const uint16_t kLeftBit = 0x8000;
-    uint16_t crc = value;
-    size_t i, j;
-
-    for (i = 0; i < length + kExtraRounds; ++i)
-    {
-        for (j = 0; j < 8; ++j)
-        {
-            bool xor_flag = crc & kLeftBit;
-            crc <<= 1;
-            // If this isn't an extra round and the current byte's j'th bit
-            // from the left is set, increment the CRC.
-            if (i < length && bytes[i] & (1 << (7 - j)))
-            {
-                crc++;
-            }
-            if (xor_flag)
-            {
-                crc ^= crc16Ccitt;
-            }
-        }
-    }
-
-    value = crc;
-}
-
-uint16_t Crc16::get() const
-{
-    return value;
-}
-} // namespace blobs
diff --git a/crc.hpp b/crc.hpp
deleted file mode 100644
index 3793d9a..0000000
--- a/crc.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include <cstdint>
-
-namespace blobs
-{
-
-using std::size_t;
-using std::uint16_t;
-using std::uint32_t;
-using std::uint8_t;
-
-constexpr uint16_t crc16Ccitt = 0x1021;
-/* Value from: http://srecord.sourceforge.net/crc16-ccitt.html for
- * implementation without explicit bit adding.
- */
-constexpr uint16_t crc16Initial = 0xFFFF;
-
-class CrcInterface
-{
-  public:
-    virtual ~CrcInterface() = default;
-
-    /**
-     * Reset the crc.
-     */
-    virtual void clear() = 0;
-
-    /**
-     * Provide bytes against which to compute the crc.  This method is
-     * meant to be only called once between clear() and get().
-     *
-     * @param[in] bytes - the data against which to compute.
-     * @param[in] length - the number of bytes.
-     */
-    virtual void compute(const uint8_t* bytes, uint32_t length) = 0;
-
-    /**
-     * Read back the current crc value.
-     *
-     * @return the crc16 value.
-     */
-    virtual uint16_t get() const = 0;
-};
-
-class Crc16 : public CrcInterface
-{
-  public:
-    Crc16() : poly(crc16Ccitt), value(crc16Initial){};
-    ~Crc16() = default;
-
-    void clear() override;
-    void compute(const uint8_t* bytes, uint32_t length) override;
-    uint16_t get() const override;
-
-  private:
-    uint16_t poly;
-    uint16_t value;
-};
-} // namespace blobs
diff --git a/main.cpp b/main.cpp
index 6115302..bd071ae 100644
--- a/main.cpp
+++ b/main.cpp
@@ -48,17 +48,16 @@
 
     /* on failure rc is set to the corresponding IPMI error. */
     ipmi_ret_t rc = IPMI_CC_OK;
-    Crc16 crc;
     IpmiBlobHandler command =
-        validateBlobCommand(&crc, reqBuf, replyCmdBuf, dataLen, &rc);
+        validateBlobCommand(reqBuf, replyCmdBuf, dataLen, &rc);
     if (command == nullptr)
     {
         (*dataLen) = 0;
         return rc;
     }
 
-    return processBlobCommand(command, getBlobManager(), &crc, reqBuf,
-                              replyCmdBuf, dataLen);
+    return processBlobCommand(command, getBlobManager(), reqBuf, replyCmdBuf,
+                              dataLen);
 }
 
 void setupBlobGlobalHandler() __attribute__((constructor));
diff --git a/process.cpp b/process.cpp
index a73f70e..661f59d 100644
--- a/process.cpp
+++ b/process.cpp
@@ -19,6 +19,7 @@
 #include "ipmi.hpp"
 
 #include <cstring>
+#include <ipmiblob/crc.hpp>
 #include <unordered_map>
 #include <vector>
 
@@ -47,9 +48,8 @@
     {BlobOEMCommands::bmcBlobWriteMeta, writeMeta},
 };
 
-IpmiBlobHandler validateBlobCommand(CrcInterface* crc, const uint8_t* reqBuf,
-                                    uint8_t* replyCmdBuf, size_t* dataLen,
-                                    ipmi_ret_t* code)
+IpmiBlobHandler validateBlobCommand(const uint8_t* reqBuf, uint8_t* replyCmdBuf,
+                                    size_t* dataLen, ipmi_ret_t* code)
 {
     size_t requestLength = (*dataLen);
     /* We know dataLen is at least 1 already */
@@ -88,11 +88,8 @@
         /* Set the in-place CRC to zero. */
         std::memcpy(bytes.data(), &reqBuf[3], requestBodyLen);
 
-        crc->clear();
-        crc->compute(bytes.data(), bytes.size());
-
         /* Crc expected but didn't match. */
-        if (crcValue != crc->get())
+        if (crcValue != ipmiblob::generateCrc(bytes))
         {
             *code = IPMI_CC_UNSPECIFIED_ERROR;
             return nullptr;
@@ -111,8 +108,8 @@
 }
 
 ipmi_ret_t processBlobCommand(IpmiBlobHandler cmd, ManagerInterface* mgr,
-                              CrcInterface* crc, const uint8_t* reqBuf,
-                              uint8_t* replyCmdBuf, size_t* dataLen)
+                              const uint8_t* reqBuf, uint8_t* replyCmdBuf,
+                              size_t* dataLen)
 {
     ipmi_ret_t result = cmd(mgr, reqBuf, replyCmdBuf, dataLen);
     if (result != IPMI_CC_OK)
@@ -137,12 +134,10 @@
     }
 
     /* The command, whatever it was, replied, so let's set the CRC. */
-    crc->clear();
-    crc->compute(replyCmdBuf + sizeof(uint16_t),
-                 replyLength - sizeof(uint16_t));
-
+    std::vector<std::uint8_t> crcBuffer(replyCmdBuf + sizeof(uint16_t),
+                                        replyCmdBuf + replyLength);
     /* Copy the CRC into place. */
-    uint16_t crcValue = crc->get();
+    uint16_t crcValue = ipmiblob::generateCrc(crcBuffer);
     std::memcpy(replyCmdBuf, &crcValue, sizeof(crcValue));
 
     return result;
diff --git a/process.hpp b/process.hpp
index 390bc1a..cdd7f72 100644
--- a/process.hpp
+++ b/process.hpp
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "crc.hpp"
 #include "manager.hpp"
 
 #include <ipmid/api.h>
@@ -17,7 +16,6 @@
 /**
  * Validate the IPMI request and determine routing.
  *
- * @param[in] crc - a pointer to the crc interface.
  * @param[in] reqBuf - a pointer to the ipmi request packet buffer.
  * @param[in,out] replyCmdBuf - a pointer to the ipmi reply packet buffer.
  * @param[in,out] dataLen - initially the request length, set to reply length
@@ -25,9 +23,8 @@
  * @param[out] code - set to the IPMI error on failure, otherwise unset.
  * @return the ipmi command handler, or nullptr on failure.
  */
-IpmiBlobHandler validateBlobCommand(CrcInterface* crc, const uint8_t* reqBuf,
-                                    uint8_t* replyCmdBuf, size_t* dataLen,
-                                    ipmi_ret_t* code);
+IpmiBlobHandler validateBlobCommand(const uint8_t* reqBuf, uint8_t* replyCmdBuf,
+                                    size_t* dataLen, ipmi_ret_t* code);
 
 /**
  * Call the IPMI command and process the result, including running the CRC
@@ -35,7 +32,6 @@
  *
  * @param[in] cmd - a funtion pointer to the ipmi command to process.
  * @param[in] mgr - a pointer to the manager interface.
- * @param[in] crc - a pointer to the crc interface.
  * @param[in] reqBuf - a pointer to the ipmi request packet buffer.
  * @param[in,out] replyCmdBuf - a pointer to the ipmi reply packet buffer.
  * @param[in,out] dataLen - initially the request length, set to reply length
@@ -43,6 +39,6 @@
  * @return the ipmi command result.
  */
 ipmi_ret_t processBlobCommand(IpmiBlobHandler cmd, ManagerInterface* mgr,
-                              CrcInterface* crc, const uint8_t* reqBuf,
-                              uint8_t* replyCmdBuf, size_t* dataLen);
+                              const uint8_t* reqBuf, uint8_t* replyCmdBuf,
+                              size_t* dataLen);
 } // namespace blobs
diff --git a/test/Makefile.am b/test/Makefile.am
index 86cfad1..de6bea5 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -44,7 +44,6 @@
 	manager_read_unittest \
 	manager_writemeta_unittest \
 	process_unittest \
-	crc_unittest \
 	utils_unittest
 
 TESTS = $(check_PROGRAMS)
@@ -122,11 +121,7 @@
 manager_writemeta_unittest_LDADD = $(top_builddir)/manager.o
 
 process_unittest_SOURCES = process_unittest.cpp
-process_unittest_LDADD = $(top_builddir)/process.o $(top_builddir)/ipmi.o \
-	$(top_builddir)/crc.o
-
-crc_unittest_SOURCES = crc_unittest.cpp
-crc_unittest_LDADD = $(top_builddir)/crc.o
+process_unittest_LDADD = $(top_builddir)/process.o $(top_builddir)/ipmi.o
 
 utils_unittest_SOURCES = utils_unittest.cpp
 utils_unittest_LDADD =  $(top_builddir)/utils.o $(PHOSPHOR_LOGGING_LIBS)
diff --git a/test/crc_mock.hpp b/test/crc_mock.hpp
deleted file mode 100644
index 1562200..0000000
--- a/test/crc_mock.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include "crc.hpp"
-
-#include <gmock/gmock.h>
-
-namespace blobs
-{
-
-class CrcMock : public CrcInterface
-{
-  public:
-    virtual ~CrcMock() = default;
-
-    MOCK_METHOD0(clear, void());
-    MOCK_METHOD2(compute, void(const uint8_t*, uint32_t));
-    MOCK_CONST_METHOD0(get, uint16_t());
-};
-} // namespace blobs
diff --git a/test/crc_unittest.cpp b/test/crc_unittest.cpp
deleted file mode 100644
index fb69cb4..0000000
--- a/test/crc_unittest.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "crc.hpp"
-
-#include <string>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-namespace blobs
-{
-
-TEST(Crc16Test, VerifyCrcValue)
-{
-    // Verify the crc16 is producing the value we expect.
-
-    // Origin: security/crypta/ipmi/portable/ipmi_utils_test.cc
-    struct CrcTestVector
-    {
-        std::string input;
-        uint16_t output;
-    };
-
-    std::string longString =
-        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-        "AAAAAAAAAAAAAAAA";
-
-    std::vector<CrcTestVector> vectors({{"", 0x1D0F},
-                                        {"A", 0x9479},
-                                        {"123456789", 0xE5CC},
-                                        {longString, 0xE938}});
-
-    Crc16 crc;
-
-    for (const CrcTestVector& testVector : vectors)
-    {
-        crc.clear();
-        auto data = reinterpret_cast<const uint8_t*>(testVector.input.data());
-        crc.compute(data, testVector.input.size());
-        EXPECT_EQ(crc.get(), testVector.output);
-    }
-}
-} // namespace blobs
diff --git a/test/process_unittest.cpp b/test/process_unittest.cpp
index bd1f886..d99bd21 100644
--- a/test/process_unittest.cpp
+++ b/test/process_unittest.cpp
@@ -1,25 +1,34 @@
-#include "crc.hpp"
-#include "crc_mock.hpp"
 #include "ipmi.hpp"
 #include "manager_mock.hpp"
 #include "process.hpp"
 
 #include <cstring>
+#include <ipmiblob/test/crc_mock.hpp>
 
 #include <gtest/gtest.h>
 
-namespace blobs
-{
-
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::Return;
-using ::testing::StrictMock;
-
 // ipmid.hpp isn't installed where we can grab it and this value is per BMC
 // SoC.
 #define MAX_IPMI_BUFFER 64
 
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::StrictMock;
+
+namespace ipmiblob
+{
+CrcInterface* crcIntf = nullptr;
+
+std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
+{
+    return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
+}
+} // namespace ipmiblob
+
+namespace blobs
+{
 namespace
 {
 
@@ -46,11 +55,21 @@
 
 } // namespace
 
-TEST(ValidateBlobCommandTest, InvalidCommandReturnsFailure)
+class ValidateBlobCommandTest : public ::testing::Test
+{
+  protected:
+    void SetUp() override
+    {
+        ipmiblob::crcIntf = &crcMock;
+    }
+
+    ipmiblob::CrcMock crcMock;
+};
+
+TEST_F(ValidateBlobCommandTest, InvalidCommandReturnsFailure)
 {
     // Verify we handle an invalid command.
 
-    StrictMock<CrcMock> crc;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
     uint8_t reply[MAX_IPMI_BUFFER] = {0};
@@ -59,16 +78,14 @@
     dataLen = sizeof(uint8_t); // There is no payload for CRC.
     ipmi_ret_t rc;
 
-    EXPECT_EQ(nullptr,
-              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
+    EXPECT_EQ(nullptr, validateBlobCommand(request, reply, &dataLen, &rc));
     EXPECT_EQ(IPMI_CC_INVALID_FIELD_REQUEST, rc);
 }
 
-TEST(ValidateBlobCommandTest, ValidCommandWithoutPayload)
+TEST_F(ValidateBlobCommandTest, ValidCommandWithoutPayload)
 {
     // Verify we handle a valid command that doesn't have a payload.
 
-    StrictMock<CrcMock> crc;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
     uint8_t reply[MAX_IPMI_BUFFER] = {0};
@@ -77,18 +94,16 @@
     dataLen = sizeof(uint8_t); // There is no payload for CRC.
     ipmi_ret_t rc;
 
-    IpmiBlobHandler res =
-        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
+    IpmiBlobHandler res = validateBlobCommand(request, reply, &dataLen, &rc);
     EXPECT_FALSE(res == nullptr);
     EqualFunctions(getBlobCount, res);
 }
 
-TEST(ValidateBlobCommandTest, WithPayloadMinimumLengthIs3VerifyChecks)
+TEST_F(ValidateBlobCommandTest, WithPayloadMinimumLengthIs3VerifyChecks)
 {
     // Verify that if there's a payload, it's at least one command byte and
     // two bytes for the crc16 and then one data byte.
 
-    StrictMock<CrcMock> crc;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
     uint8_t reply[MAX_IPMI_BUFFER] = {0};
@@ -98,16 +113,14 @@
     // There is a payload, but there are insufficient bytes.
     ipmi_ret_t rc;
 
-    EXPECT_EQ(nullptr,
-              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
+    EXPECT_EQ(nullptr, validateBlobCommand(request, reply, &dataLen, &rc));
     EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID, rc);
 }
 
-TEST(ValidateBlobCommandTest, WithPayloadAndInvalidCrc)
+TEST_F(ValidateBlobCommandTest, WithPayloadAndInvalidCrc)
 {
     // Verify that the CRC is checked, and failure is reported.
 
-    StrictMock<CrcMock> crc;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
     uint8_t reply[MAX_IPMI_BUFFER] = {0};
@@ -124,27 +137,19 @@
     dataLen = sizeof(struct BmcBlobWriteTx) + sizeof(expectedBytes);
 
     // skip over cmd and crc.
-    size_t expectedLen = dataLen - 3;
-
-    EXPECT_CALL(crc, clear());
-    EXPECT_CALL(crc, compute(_, expectedLen))
-        .WillOnce(Invoke([&](const uint8_t* bytes, uint32_t length) {
-            EXPECT_EQ(0, std::memcmp(&request[3], bytes, length));
-        }));
-    EXPECT_CALL(crc, get()).WillOnce(Return(0x1234));
+    std::vector<std::uint8_t> bytes(&request[3], request + dataLen);
+    EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x1234));
 
     ipmi_ret_t rc;
 
-    EXPECT_EQ(nullptr,
-              validateBlobCommand(&crc, request, reply, &dataLen, &rc));
+    EXPECT_EQ(nullptr, validateBlobCommand(request, reply, &dataLen, &rc));
     EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR, rc);
 }
 
-TEST(ValidateBlobCommandTest, WithPayloadAndValidCrc)
+TEST_F(ValidateBlobCommandTest, WithPayloadAndValidCrc)
 {
     // Verify the CRC is checked and if it matches, return the handler.
 
-    StrictMock<CrcMock> crc;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
     uint8_t reply[MAX_IPMI_BUFFER] = {0};
@@ -161,55 +166,32 @@
     dataLen = sizeof(struct BmcBlobWriteTx) + sizeof(expectedBytes);
 
     // skip over cmd and crc.
-    size_t expectedLen = dataLen - 3;
-
-    EXPECT_CALL(crc, clear());
-    EXPECT_CALL(crc, compute(_, expectedLen))
-        .WillOnce(Invoke([&](const uint8_t* bytes, uint32_t length) {
-            EXPECT_EQ(0, std::memcmp(&request[3], bytes, length));
-        }));
-    EXPECT_CALL(crc, get()).WillOnce(Return(0x3412));
+    std::vector<std::uint8_t> bytes(&request[3], request + dataLen);
+    EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x3412));
 
     ipmi_ret_t rc;
 
-    IpmiBlobHandler res =
-        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
+    IpmiBlobHandler res = validateBlobCommand(request, reply, &dataLen, &rc);
     EXPECT_FALSE(res == nullptr);
     EqualFunctions(writeBlob, res);
 }
 
-TEST(ValidateBlobCommandTest, InputIntegrationTest)
+class ProcessBlobCommandTest : public ::testing::Test
 {
-    // Given a request buffer generated by the host-side utility, verify it is
-    // properly routed.
+  protected:
+    void SetUp() override
+    {
+        ipmiblob::crcIntf = &crcMock;
+    }
 
-    Crc16 crc;
-    size_t dataLen;
-    uint8_t request[] = {0x02, 0x88, 0x21, 0x03, 0x00, 0x2f, 0x64, 0x65, 0x76,
-                         0x2f, 0x68, 0x61, 0x76, 0x65, 0x6e, 0x2f, 0x63, 0x6f,
-                         0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x61, 0x73,
-                         0x73, 0x74, 0x68, 0x72, 0x75, 0x00};
+    ipmiblob::CrcMock crcMock;
+};
 
-    // The above request to open a file for reading & writing named:
-    // "/dev/haven/command_passthru"
-
-    uint8_t reply[MAX_IPMI_BUFFER] = {0};
-
-    dataLen = sizeof(request);
-    ipmi_ret_t rc;
-
-    IpmiBlobHandler res =
-        validateBlobCommand(&crc, request, reply, &dataLen, &rc);
-    EXPECT_FALSE(res == nullptr);
-    EqualFunctions(openBlob, res);
-}
-
-TEST(ProcessBlobCommandTest, CommandReturnsNotOk)
+TEST_F(ProcessBlobCommandTest, CommandReturnsNotOk)
 {
     // Verify that if the IPMI command handler returns not OK that this is
     // noticed and returned.
 
-    StrictMock<CrcMock> crc;
     StrictMock<ManagerMock> manager;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
@@ -222,15 +204,14 @@
     dataLen = sizeof(request);
 
     EXPECT_EQ(IPMI_CC_INVALID,
-              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
+              processBlobCommand(h, &manager, request, reply, &dataLen));
 }
 
-TEST(ProcessBlobCommandTest, CommandReturnsOkWithNoPayload)
+TEST_F(ProcessBlobCommandTest, CommandReturnsOkWithNoPayload)
 {
     // Verify that if the IPMI command handler returns OK but without a payload
     // it doesn't try to compute a CRC.
 
-    StrictMock<CrcMock> crc;
     StrictMock<ManagerMock> manager;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
@@ -245,15 +226,14 @@
     dataLen = sizeof(request);
 
     EXPECT_EQ(IPMI_CC_OK,
-              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
+              processBlobCommand(h, &manager, request, reply, &dataLen));
 }
 
-TEST(ProcessBlobCommandTest, CommandReturnsOkWithInvalidPayloadLength)
+TEST_F(ProcessBlobCommandTest, CommandReturnsOkWithInvalidPayloadLength)
 {
     // There is a minimum payload length of 2 bytes (the CRC only, no data, for
     // read), this returns 1.
 
-    StrictMock<CrcMock> crc;
     StrictMock<ManagerMock> manager;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
@@ -268,15 +248,14 @@
     dataLen = sizeof(request);
 
     EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR,
-              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
+              processBlobCommand(h, &manager, request, reply, &dataLen));
 }
 
-TEST(ProcessBlobCommandTest, CommandReturnsOkWithValidPayloadLength)
+TEST_F(ProcessBlobCommandTest, CommandReturnsOkWithValidPayloadLength)
 {
     // There is a minimum payload length of 3 bytes, this command returns a
     // payload of 3 bytes and the crc code is called to process the payload.
 
-    StrictMock<CrcMock> crc;
     StrictMock<ManagerMock> manager;
     size_t dataLen;
     uint8_t request[MAX_IPMI_BUFFER] = {0};
@@ -293,12 +272,10 @@
 
     dataLen = sizeof(request);
 
-    EXPECT_CALL(crc, clear());
-    EXPECT_CALL(crc, compute(_, payloadLen - sizeof(uint16_t)));
-    EXPECT_CALL(crc, get()).WillOnce(Return(0x3412));
+    EXPECT_CALL(crcMock, generateCrc(_)).WillOnce(Return(0x3412));
 
     EXPECT_EQ(IPMI_CC_OK,
-              processBlobCommand(h, &manager, &crc, request, reply, &dataLen));
+              processBlobCommand(h, &manager, request, reply, &dataLen));
     EXPECT_EQ(dataLen, payloadLen);
 
     uint8_t expectedBytes[3] = {0x12, 0x34, 0x56};