update_engine: Store and test kern/fw versions as 4 values

- Refactors the handling of _firmware_version and _kernel_version
  attributes to split as 4x 16 bit values.
- Based on discussion, we are trying to avoid using the client
  specific version format in the network protocol.
- Each of firmware and kernel versions will be stored separately
  as uint16_t rather than combined as a uint32_t.
- In the Omaha response the two fields of each version type will
  be encoded as key_version.version
- Adds tests for the actual parsing of the response.

BUG=chromium:840432
TEST=cros_run_unit_tests --board=samus --packages update_engine

Change-Id: I4da02e3f4715a132db7e96e55c30139fff6fe6ea
Reviewed-on: https://chromium-review.googlesource.com/1123106
Commit-Ready: Marton Hunyady <hunyadym@chromium.org>
Tested-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/omaha_response_handler_action.cc b/omaha_response_handler_action.cc
index 775c0a8..3a8439d 100644
--- a/omaha_response_handler_action.cc
+++ b/omaha_response_handler_action.cc
@@ -16,6 +16,7 @@
 
 #include "update_engine/omaha_response_handler_action.h"
 
+#include <limits>
 #include <string>
 
 #include <base/logging.h>
@@ -36,6 +37,7 @@
 
 using chromeos_update_manager::Policy;
 using chromeos_update_manager::UpdateManager;
+using std::numeric_limits;
 using std::string;
 
 namespace chromeos_update_engine {
@@ -149,8 +151,20 @@
         system_state_->hardware()->GetMinKernelKeyVersion());
     auto min_firmware_key_version = static_cast<uint32_t>(
         system_state_->hardware()->GetMinFirmwareKeyVersion());
-    if (response.kernel_version < min_kernel_key_version ||
-        response.firmware_version < min_firmware_key_version) {
+    uint32_t kernel_key_version =
+        static_cast<uint32_t>(response.rollback_key_version.kernel_key) << 16 |
+        static_cast<uint32_t>(response.rollback_key_version.kernel);
+    uint32_t firmware_key_version =
+        static_cast<uint32_t>(response.rollback_key_version.firmware_key)
+            << 16 |
+        static_cast<uint32_t>(response.rollback_key_version.firmware);
+
+    // Don't attempt a rollback if the versions are incompatible or the
+    // target image does not specify the version information.
+    if (kernel_key_version == numeric_limits<uint32_t>::max() ||
+        firmware_key_version == numeric_limits<uint32_t>::max() ||
+        kernel_key_version < min_kernel_key_version ||
+        firmware_key_version < min_firmware_key_version) {
       LOG(ERROR) << "Device won't be able to boot up the rollback image.";
       completer.set_code(ErrorCode::kRollbackNotPossible);
       return;