Attest: Get option flags from challenge object

Special option flags (for test purpose) can be passed in for
attestation service. These flags are encoded in the challenge object.
Previously a 36 bytes long challenge object was used to carry these
4 extra bytes, but attestation API requires the challenge object to be
only 32, 48 or 64 bytes long.

With this change the option flags are packed in a 64 bytes long
challenge object which has a predefined value. If the challenge object
is 64 byte long and the bytes from 4 to 63 have 0 value in this case
the first 4 bytes are handled as the option flags.

Change-Id: I2a4d0bf417905d74cca0fbdb5070cdef085fe308
Signed-off-by: Laurence Lundblade <lgl@securitytheory.com>
Co-authored-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/lib/ext/qcbor/inc/UsefulBuf.h b/lib/ext/qcbor/inc/UsefulBuf.h
index 0aaa9b6..682646e 100644
--- a/lib/ext/qcbor/inc/UsefulBuf.h
+++ b/lib/ext/qcbor/inc/UsefulBuf.h
@@ -1,7 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018-2019, Laurence Lundblade.
- All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -42,6 +41,7 @@
 
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
+ 3/6/2019           llundblade      Add UsefulBuf_IsValue()
  12/17/2018         llundblade      Remove const from UsefulBuf and UsefulBufC .len
  12/13/2018         llundblade      Documentation improvements
  09/18/2018         llundblade      Cleaner distinction between UsefulBuf and UsefulBufC
@@ -480,10 +480,10 @@
 
 
 /**
- @brief Compare two UsefulBufCs
+ @brief Compare two UsefulBufCs.
 
- @param[in] UB1 The destination buffer to copy into
- @param[in] UB2  The source to copy from
+ @param[in] UB1  First UsefulBufC to compare.
+ @param[in] UB2  Second UsefulBufC to compare.
 
  @return 0 if equal...
 
@@ -504,6 +504,27 @@
 
 
 /**
+ @brief Find first byte that is not a particular byte value.
+
+ @param[in] UB     The destination buffer for byte comparison.
+ @param[in] uValue The byte value to compare to.
+
+ @return  Offset of first byte that isn't \c uValue or
+          SIZE_MAX if all bytes are \c uValue.
+
+ Note that unlike most comparison functions, 0
+ does not indicate a successful comparison,  so the
+ test for match is:
+
+      UsefulBuf_IsValue(...) == SIZE_MAX
+
+ If \c UB is NULL or empty, there is no match
+ and 0 is returned.
+ */
+size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue);
+
+
+/**
  @brief Find one UsefulBuf in another
 
  @param[in] BytesToSearch  UsefulBuf to search through
diff --git a/lib/ext/qcbor/inc/q_useful_buf.h b/lib/ext/qcbor/inc/q_useful_buf.h
index d7e38d4..4621fad 100644
--- a/lib/ext/qcbor/inc/q_useful_buf.h
+++ b/lib/ext/qcbor/inc/q_useful_buf.h
@@ -136,6 +136,12 @@
     return UsefulBuf_Compare(buf1, buf2);
 }
 
+static inline size_t q_useful_buf_is_value(const struct q_useful_buf_c buf,
+                                           uint8_t uValue)
+{
+    return UsefulBuf_IsValue(buf, uValue);
+}
+
 static inline size_t
 useful_buf_find_bytes(const struct q_useful_buf_c bytes_to_search,
                       const struct q_useful_buf_c bytes_to_find)
diff --git a/lib/ext/qcbor/src/UsefulBuf.c b/lib/ext/qcbor/src/UsefulBuf.c
index 5a7d37b..d27c146 100644
--- a/lib/ext/qcbor/src/UsefulBuf.c
+++ b/lib/ext/qcbor/src/UsefulBuf.c
@@ -1,7 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
  Copyright (c) 2018-2019, Laurence Lundblade.
- All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -42,6 +41,7 @@
 
  when               who             what, where, why
  --------           ----            ---------------------------------------------------
+ 3/6/2019           llundblade      Add UsefulBuf_IsValue()
  09/07/17           llundbla        Fix critical bug in UsefulBuf_Find() -- a read off
                                     the end of memory when the bytes to find is longer
                                     than the bytes to search.
@@ -91,6 +91,28 @@
 }
 
 
+/*
+ Public function -- see UsefulBuf.h
+ */
+size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
+{
+   if(UsefulBuf_IsNULLOrEmptyC(UB)) {
+      /* Not a match */
+      return 0;
+   }
+
+   const uint8_t * const pEnd = (uint8_t *)UB.ptr + UB.len;
+   for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
+      if(*p != uValue) {
+         /* Byte didn't match */
+         return p - (uint8_t *)UB.ptr;
+      }
+   }
+
+   /* Success. All bytes matched */
+   return SIZE_MAX;
+}
+
 
 /*
  Public function -- see UsefulBuf.h
diff --git a/lib/ext/qcbor/test/UsefulBuf_Tests.c b/lib/ext/qcbor/test/UsefulBuf_Tests.c
index cfa1262..388f8cf 100644
--- a/lib/ext/qcbor/test/UsefulBuf_Tests.c
+++ b/lib/ext/qcbor/test/UsefulBuf_Tests.c
@@ -544,6 +544,30 @@
       return "Copy null/empty failed";
    }
 
+   if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) {
+      return "IsValue failed to match all";
+   }
+
+   if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) {
+      return "IsValue should have failed right away";
+   }
+
+   if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) {
+      return "IsValue failed on NULLUsefulBufC";
+   }
+
+   if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) {
+      return "IsValue failed finding 0 in one byte of 0";
+   }
+
+   if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) {
+      return "IsValue failed not finding 1 in one byte of 0";
+   }
+
+   if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) {
+      return "IsValue failed to find final *";
+   }
+
    // Look for +++++... in +++++... and find it at the beginning
    if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){
       return "Failed to find";