Parrot: Add registration code sanity check

registration_codes.py was cherry-picked from
https://gerrit.chromium.org/gerrit/28683 of ToT.

BUG=chrome-os-partner:15553
TEST=To be verified by the partner

Change-Id: Idedf623c758f36a3161560fe97b8c4e052ea5296
Reviewed-on: https://gerrit.chromium.org/gerrit/36376
Reviewed-by: Jon Salz <jsalz@chromium.org>
Tested-by: Jay Kim <yongjaek@chromium.org>
diff --git a/client/site_tests/factory_VPD/factory_VPD.py b/client/site_tests/factory_VPD/factory_VPD.py
index 8d587ca..fbe9486 100644
--- a/client/site_tests/factory_VPD/factory_VPD.py
+++ b/client/site_tests/factory_VPD/factory_VPD.py
@@ -5,6 +5,7 @@
 import os
 import serial_task
 import region_task
+import registration_codes
 
 from autotest_lib.client.bin import test
 from autotest_lib.client.common_lib import error, utils
@@ -27,7 +28,7 @@
         mask_keys = ['ubind_attribute', 'gbind_attribute']
         disp_dict = {'ro':{}, 'rw':{}}
 
-        for vpd_type in disp_dict:
+        for vpd_type in ('ro', 'rw'):
             for key in self.vpd[vpd_type]:
                 if key in mask_keys:
                     disp_dict[vpd_type][key] = '********'
@@ -67,8 +68,11 @@
         vpd = self.vpd
         vpd_list = []
         for vpd_type in ('ro', 'rw'):
-            vpd_list += ['%s: %s = %s' % (vpd_type, key, vpd[vpd_type][key])
-                         for key in sorted(vpd[vpd_type])]
+            for key in sorted(vpd[vpd_type]):
+                vpd_list += ['%s: %s = %s' %
+                             (vpd_type, key, vpd[vpd_type][key])]
+                if key in ['ubind_attribute', 'gbind_attribute']:
+                    registration_codes.CheckRegistrationCode(vpd[vpd_type][key])
 
         self.add_widget(ui.make_label("%s\n%s" % (_MESSAGE_WRITING,
                                                   '\n'.join(vpd_list))))
diff --git a/client/site_tests/factory_VPD/registration_codes.py b/client/site_tests/factory_VPD/registration_codes.py
new file mode 100644
index 0000000..4d48d70
--- /dev/null
+++ b/client/site_tests/factory_VPD/registration_codes.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import binascii
+import re
+import struct
+
+
+def CheckRegistrationCode(code):
+  '''Checks that a registration code is valid, raising a ValueError if not.'''
+  if len(code) != 72:
+    raise ValueError('Registration code %r is not 72 characters long' % code)
+  if re.search('[^0-9a-f]', code):
+    raise ValueError('Registration code %r has invalid characters' % code)
+
+  # Parse payload and CRC as byte strings.
+  payload = binascii.unhexlify(code[0:64])
+  crc = binascii.unhexlify(code[64:72])
+  expected_crc = struct.pack('!I', binascii.crc32(payload) & 0xFFFFFFFF)
+  if expected_crc != crc:
+    raise ValueError('CRC of %r is invalid (should be %s)' %
+                     (code, binascii.hexlify(expected_crc)))
+