Add CounterSignature support to the code base (#97)

Add support for full Counter Signatures to all of the base objects.
Add back parens to most of the code
diff --git a/.appveyor.yml b/.appveyor.yml
index 19e4816..90e8665 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,7 +1,7 @@
 platform:
   - x64
 
-image: Visual Studio 2017
+image: Visual Studio 2019
   
 configuration:
   - Release
@@ -27,8 +27,12 @@
   - git clone --depth 1 git://github.com/cose-wg/Examples Examples
 
 before_build:
+  - set PATH=c:\OpenSSL-v111-Win64\bin;%PATH%
+  - set OPENSSL_ROOT_DIR=c:\OpenSSL-v111-Win64
   - cmake --version
-  - cmake -DCOSE_C_USE_CONTEXT=%USE_CONTEXT% -DCOSE_C_USE_MBEDTLS=%USE_EMBEDTLS% -DBUILD_SHARED_LIBS=OFF  -G "Visual Studio 15 2017 Win64" .
+  - mkdir build
+  - cd build
+  - cmake -DCOSE_C_USE_CONTEXT=%USE_CONTEXT% -DCOSE_C_USE_MBEDTLS=%USE_EMBEDTLS% -DBUILD_SHARED_LIBS=OFF -G "Visual Studio 16 2019" ..
 
 build_script:
   - msbuild cose-c.sln
diff --git a/.clang-format b/.clang-format
index 955f6ad..4ec66ca 100644
--- a/.clang-format
+++ b/.clang-format
@@ -8,6 +8,6 @@
 BraceWrapping:
   AfterFunction: true
   BeforeCatch: false
-  BeforeElse: false
+  BeforeElse: true
 AlignAfterOpenBracket: false
 SortIncludes: false
\ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 6ea987b..e384343 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,12 +14,19 @@
         USE_CONTEXT: ["ON", "OFF"]

         CMAKE_OPTIONS:

           [

-            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_OPTIMIZE=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON"

           ]

 

     steps:

@@ -71,12 +78,18 @@
         USE_CONTEXT: ["ON", "OFF"]

         CMAKE_OPTIONS:

           [

-            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF",

-            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON -DCOSE_C_INCLUDE_COUNTERSIGN=OFF",

+            "-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=ON -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=ON -DCOSE_C_INCLUDE_SIGN1=OFF -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

+            "-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON",

           ]

 

     steps:

diff --git a/.gitignore b/.gitignore
index bec05a8..e5b428b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@
 *.x86_64
 *.hex
 a.bat
+clang-format.bat
 
 # Debug files
 *.dSYM/
@@ -59,6 +60,7 @@
 *.VC.opendb
 .vs
 .vscode
+CMakeSettings.json
 
 # CMake and CTest directories
 project_cn-cbor-prefix
diff --git a/.travis.yml b/.travis.yml
index ae3e636..588ee63 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,11 +9,11 @@
       OPENSSL_INSTALL_DIR="${HOME}/opt"
   jobs:
     - USE_CONTEXT=ON
-      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON"
+      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON"
     - USE_CONTEXT=OFF
-      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON"
+      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON"
     - USE_CONTEXT=OFF USE_EMBEDTLS=ON
-      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON"
+      COVERALLS="-DCOSE_C_COVERALLS_SEND=ON -DCOSE_C_INCLUDE_COUNTERSIGN=ON"
     - CMAKE_OPTIONS="-DCOSE_C_INCLUDE_ENCRYPT=ON -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF"
     - CMAKE_OPTIONS="-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=ON -DCOSE_C_INCLUDE_MAC0=OFF -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF"
     - CMAKE_OPTIONS="-DCOSE_C_INCLUDE_ENCRYPT=OFF -DCOSE_C_INCLUDE_ENCRYPT0=OFF -DCOSE_C_INCLUDE_MAC0=ON -DCOSE_C_INCLUDE_MAC=OFF -DCOSE_C_INCLUDE_SIGN=OFF -DCOSE_C_INCLUDE_SIGN1=OFF"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e39b91c..24c920f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,6 +37,7 @@
 option(COSE_C_INCLUDE_MAC0 "Include COSE_MAC0" ON)
 option(COSE_C_INCLUDE_SIGN "Include COSE_SIGN" ON)
 option(COSE_C_INCLUDE_SIGN1 "Include COSE_SIGN1" ON)
+option(COSE_C_INCLUDE_COUNTERSIGN "Include COSE_COUNTERSIGN" OFF)
 
 # Set the output of the libraries and executables.
 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
@@ -82,6 +83,9 @@
 if(NOT COSE_C_INCLUDE_SIGN1)
   add_definitions(-DINCLUDE_SIGN1=0)
 endif()
+if (NOT COSE_C_INCLUDE_COUNTERSIGN)
+  add_definitions(-DINCLUDE_COUNTERSIGN=0)
+endif()
 if(COSE_C_USE_CONTEXT)
   add_definitions(-DUSE_CBOR_CONTEXT)
 endif()
@@ -93,6 +97,10 @@
   set(CMAKE_VERBOSE_MAKEFILE ON)
 endif()
 
+# Control the order of packages - get the latest not the first
+SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
+SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+
 ###############################################################################
 # DOCS
 ###############################################################################
@@ -247,6 +255,7 @@
 message(STATUS "COSE_C_INCLUDE_MAC0:.............${COSE_C_INCLUDE_MAC0}")
 message(STATUS "COSE_C_INCLUDE_SIGN:.............${COSE_C_INCLUDE_SIGN}")
 message(STATUS "COSE_C_INCLUDE_SIGN1:............${COSE_C_INCLUDE_SIGN1}")
+message(STATUS "COSE_C_INCLUDE_COUNTERSIGN:......${COSE_C_INCLUDE_COUNTERSIGN}")
 message(STATUS "COSE_C_USE_CONTEXT:..............${COSE_C_USE_CONTEXT}")
 message(STATUS "COSE_C_FATAL_WARNINGS:...........${COSE_C_FATAL_WARNINGS}")
 message(STATUS "COSE_C_BUILD_TESTS:..............${COSE_C_BUILD_TESTS}")
diff --git a/dumper/dumper.c b/dumper/dumper.c
index ab45b2f..23feca1 100644
--- a/dumper/dumper.c
+++ b/dumper/dumper.c
@@ -31,9 +31,7 @@
 extern FOO Signer[];
 
 #ifdef USE_CBOR_CONTEXT
-#define CBOR_CONTEXT_PARAM , NULL
-#else
-#define CBOR_CONTEXT_PARAM
+void* context = NULL;
 #endif
 
 FOO AlgorithmMap[38] = {
diff --git a/include/cose/cose.h b/include/cose/cose.h
index 471a102..bb35c24 100644
--- a/include/cose/cose.h
+++ b/include/cose/cose.h
@@ -20,6 +20,7 @@
 typedef struct _cose_mac* HCOSE_MAC;
 typedef struct _cose_mac0* HCOSE_MAC0;
 typedef struct _cose_counterSignature* HCOSE_COUNTERSIGN;
+typedef struct _cose_counterSignature1* HCOSE_COUNTERSIGN1;
 
 /**
  * All of the different kinds of errors
@@ -70,19 +71,20 @@
 	COSE_encrypt_object = 16,
 	COSE_mac_object = 97,
 	COSE_mac0_object = 17,
-	COSE_recipient_object = -1
+	COSE_recipient_object = -1,
+	COSE_countersign_object = -2,
 } COSE_object_type;
 
 //  Generic functions for the COSE library
 
 HCOSE COSE_Decode(const byte* rgbData,
 	size_t cbData,
-	int* type,
+	int* ptype,
 	COSE_object_type struct_type,
 	CBOR_CONTEXT_COMMA cose_errback* perr);	 //  Decode the object
 size_t COSE_Encode(HCOSE msg, byte* rgb, size_t ib, size_t cb);
 
-cn_cbor* COSE_get_cbor(HCOSE hmsg);
+cn_cbor* COSE_get_cbor(HCOSE h);
 
 //  Functions for the signing object
 
@@ -538,7 +540,7 @@
  * Counter Signature Routines
  */
 
-HCOSE_COUNTERSIGN COSE_CounterSign_Init(COSE_INIT_FLAGS flags,
+HCOSE_COUNTERSIGN COSE_CounterSign_Init(
 	CBOR_CONTEXT_COMMA cose_errback* perr);
 bool COSE_CounterSign_Free(HCOSE_COUNTERSIGN cose);
 
@@ -552,7 +554,91 @@
 	int flags,
 	cose_errback* errp);
 
-/*
+bool COSE_CounterSign_SetExternal(HCOSE_COUNTERSIGN cose, const byte* pbExternalData, size_t cbExternalData, cose_errback* perr);
+bool COSE_CounterSign_SetKey(HCOSE_COUNTERSIGN,
+	const cn_cbor* pkey,
+	cose_errback* perr);
+
+	
+HCOSE_COUNTERSIGN COSE_Signer_add_countersignature(HCOSE_SIGNER hSigner, HCOSE_COUNTERSIGN hCountersignature, cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Signer_get_countersignature(HCOSE_SIGNER hSigner,
+	int index,
+	cose_errback* perr);
+bool COSE_Signer_CounterSign_validate(HCOSE_SIGNER hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Sign_add_countersignature(HCOSE_SIGN hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Sign_get_countersignature(HCOSE_SIGN hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Sign_CounterSign_validate(HCOSE_SIGN hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Sign1_add_countersignature(HCOSE_SIGN1 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Sign1_get_countersignature(HCOSE_SIGN1 hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Sign1_CounterSign_validate(HCOSE_SIGN1 hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Encrypt0_add_countersignature(HCOSE_ENCRYPT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Encrypt0_get_countersignature(HCOSE_ENCRYPT hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Encrypt0_CounterSign_validate(HCOSE_ENCRYPT hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Enveloped_add_countersignature(HCOSE_ENVELOPED hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Enveloped_get_countersignature(HCOSE_ENVELOPED hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Enveloped_CounterSign_validate(HCOSE_ENVELOPED hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Recipient_add_countersignature(HCOSE_RECIPIENT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Recipient_get_countersignature(HCOSE_RECIPIENT hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Recipient_CounterSign_validate(HCOSE_RECIPIENT hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Mac0_add_countersignature(HCOSE_MAC0 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Mac0_get_countersignature(HCOSE_MAC0 hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Mac0_CounterSign_validate(HCOSE_MAC0 hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+
+HCOSE_COUNTERSIGN COSE_Mac_add_countersignature(HCOSE_MAC hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+HCOSE_COUNTERSIGN COSE_Mac_get_countersignature(HCOSE_MAC hSignMsg,
+	int index,
+	cose_errback* perr);
+bool COSE_Mac_CounterSign_validate(HCOSE_MAC hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr);
+	
+	/*
  */
 
 cn_cbor* cn_cbor_clone(const cn_cbor* pIn,
diff --git a/include/cose/cose_configure.h b/include/cose/cose_configure.h
index 7a1ce44..5250faa 100644
--- a/include/cose/cose_configure.h
+++ b/include/cose/cose_configure.h
@@ -143,13 +143,12 @@
 // Requires OPEN SSL 1.1.1 to build
 #define USE_EDDSA
 #else
-#pragma message("OPENSSL VERSION IS ")
-#pragma message(OPENSSL_VERISON_NUMBER)
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+#pragma message("OPENSSL VERSION IS " OPENSSL_VERSION_TEXT)
 #endif
 #endif	// !defined (USE_MBED_TLS)
 
-//#define USE_COUNTER_SIGNATURES
-
 //
 //   Define which COSE objects are included
 //
@@ -172,3 +171,9 @@
 #ifndef INCLUDE_SIGN1
 #define INCLUDE_SIGN1 1
 #endif
+#ifndef INCLUDE_COUNTERSIGNATURE
+#define INCLUDE_COUNTERSIGNATURE 1
+#endif
+#ifndef INCLUDE_COUNTERSIGNATURE1
+#define INCLUDE_COUNTERSIGNATURE1 0
+#endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c41e555..1314e10 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,13 +6,16 @@
   endif()
   if(COSE_C_OPTIMIZE)
     add_definitions(-Os)
+    add_definitions(-DNDEBUG)
   endif()
-  add_definitions(-DNDEBUG)
 elseif(MSVC)
   add_definitions(/W4)
   if(COSE_C_FATAL_WARNINGS)
     add_definitions(/WX)
   endif()
+  if(COSE_C_OPTIMIZE)
+    add_definitions(-DNDEBUG)
+  endif()
 else()
   message(FATAL_ERROR "unhandled compiler id: ${CMAKE_C_COMPILER_ID}")
 endif()
@@ -32,6 +35,8 @@
     cose_int.h
     crypto.h
     Cose.c
+    CounterSign.c
+    CounterSign0.c
     MacMessage.c
     MacMessage0.c
     Sign.c
diff --git a/src/Cose.c b/src/Cose.c
index 28e0469..e5214eb 100644
--- a/src/Cose.c
+++ b/src/Cose.c
@@ -4,20 +4,21 @@
 #endif
 
 #include "cose/cose.h"
-#include "cose_int.h"
 #include "cose/cose_configure.h"
+#include "cose_int.h"
 #include "crypto.h"
 
 bool IsValidCOSEHandle(HCOSE h)
 {
 	COSE_Encrypt *p = (COSE_Encrypt *)h;
-	if (p == NULL)
+	if (p == NULL) {
 		return false;
+	}
 	return true;
 }
 
 bool _COSE_Init(COSE_INIT_FLAGS flags,
-	COSE *pobj,
+	COSE *pcose,
 	int msgType,
 	CBOR_CONTEXT_COMMA cose_errback *perr)
 {
@@ -25,49 +26,50 @@
 	;
 
 #ifdef USE_CBOR_CONTEXT
-	if (context != NULL)
-		pobj->m_allocContext = *context;
+	if (context != NULL) {
+		pcose->m_allocContext = *context;
+	}
 #endif
 
 	CHECK_CONDITION((flags & ~(COSE_INIT_FLAGS_DETACHED_CONTENT |
 								 COSE_INIT_FLAGS_NO_CBOR_TAG)) == 0,
 		COSE_ERR_INVALID_PARAMETER);
 
-	pobj->m_flags = flags;
+	pcose->m_flags = flags;
 
-	pobj->m_protectedMap =
+	pcose->m_protectedMap =
 		cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA & errState);
-	CHECK_CONDITION_CBOR(pobj->m_protectedMap != NULL, errState);
+	CHECK_CONDITION_CBOR(pcose->m_protectedMap != NULL, errState);
 
-	pobj->m_dontSendMap =
+	pcose->m_dontSendMap =
 		cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA & errState);
-	CHECK_CONDITION_CBOR(pobj->m_dontSendMap != NULL, errState);
+	CHECK_CONDITION_CBOR(pcose->m_dontSendMap != NULL, errState);
 
-	pobj->m_cborRoot = pobj->m_cbor =
+	pcose->m_cborRoot = pcose->m_cbor =
 		cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & errState);
-	CHECK_CONDITION_CBOR(pobj->m_cbor != NULL, errState);
-	pobj->m_ownMsg = 1;
+	CHECK_CONDITION_CBOR(pcose->m_cbor != NULL, errState);
+	pcose->m_ownMsg = 1;
 
-	pobj->m_msgType = msgType;
+	pcose->m_msgType = msgType;
 
-	pobj->m_unprotectMap =
+	pcose->m_unprotectMap =
 		cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA & errState);
-	CHECK_CONDITION_CBOR(pobj->m_unprotectMap != NULL, errState);
+	CHECK_CONDITION_CBOR(pcose->m_unprotectMap != NULL, errState);
 	CHECK_CONDITION_CBOR(
-		_COSE_array_replace(pobj, pobj->m_unprotectMap, INDEX_UNPROTECTED,
+		_COSE_array_replace(pcose, pcose->m_unprotectMap, INDEX_UNPROTECTED,
 			CBOR_CONTEXT_PARAM_COMMA & errState),
 		errState);
-	pobj->m_ownUnprotectedMap = false;
+	pcose->m_ownUnprotectedMap = false;
 
 	if (!(flags & COSE_INIT_FLAGS_NO_CBOR_TAG)) {
 		cn_cbor_errback cbor_error;
 		cn_cbor *cn = cn_cbor_tag_create(
-			msgType, pobj->m_cborRoot, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+			msgType, pcose->m_cborRoot, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 		CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
-		pobj->m_cborRoot = cn;
+		pcose->m_cborRoot = cn;
 	}
 
-	pobj->m_refCount = 1;
+	pcose->m_refCount = 1;
 
 	return true;
 
@@ -84,15 +86,16 @@
 	cn_cbor_errback cbor_error;
 
 #ifdef USE_CBOR_CONTEXT
-	if (context != NULL)
+	if (context != NULL) {
 		pobj->m_allocContext = *context;
+	}
 #endif
 	pobj->m_cborRoot = pcbor;
 	pobj->m_cbor = pcbor;
 
 	//  Check if we have a tag
 	if (pcbor->type == CN_CBOR_TAG) {
-		pcbor = pobj->m_cbor = pcbor->first_child;
+		pobj->m_cbor = pcbor->first_child;
 	}
 
 	pmap = _COSE_arrayget_int(pobj, INDEX_PROTECTED);
@@ -106,7 +109,8 @@
 			pobj->m_protectedMap =
 				cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA NULL);
 			CHECK_CONDITION(pobj->m_protectedMap, COSE_ERR_OUT_OF_MEMORY);
-		} else {
+		}
+		else {
 			pobj->m_protectedMap = cn_cbor_decode((const byte *)pmap->v.str,
 				pmap->length, CBOR_CONTEXT_PARAM_COMMA & errState);
 			CHECK_CONDITION(
@@ -124,6 +128,31 @@
 		cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 	CHECK_CONDITION_CBOR(pobj->m_dontSendMap != NULL, cbor_error);
 
+#if INCLUDE_COUNTERSIGNATURE
+	cn_cbor *pCounter =
+		cn_cbor_mapget_int(pobj->m_unprotectMap, COSE_Header_CounterSign);
+	if (pCounter != NULL) {
+		int i;
+		CHECK_CONDITION(
+			pCounter->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
+		CHECK_CONDITION(pCounter->length > 0, COSE_ERR_INVALID_PARAMETER);
+		if (pCounter->first_child->type == CN_CBOR_ARRAY) {
+			cn_cbor *pSig = pCounter->first_child;
+			for (i = 0; i < pCounter->length; i++, pSig = pSig->next) {
+				COSE_CounterSign *cs = _COSE_CounterSign_Init_From_Object(
+					pSig, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
+				cs->m_next = pobj->m_counterSigners;
+				pobj->m_counterSigners = cs;
+			}
+		}
+		else {
+			COSE_CounterSign *cs = _COSE_CounterSign_Init_From_Object(
+				pCounter, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
+			pobj->m_counterSigners = cs;
+		}
+	}
+#endif
+
 	pobj->m_ownMsg = true;
 	pobj->m_refCount = 1;
 
@@ -133,21 +162,38 @@
 	return false;
 }
 
-void _COSE_Release(COSE *pobj)
+void _COSE_Release(COSE *pcose)
 {
 #ifdef USE_CBOR_CONTEXT
-	cn_cbor_context *context = &pobj->m_allocContext;
+	cn_cbor_context *context = &pcose->m_allocContext;
 #endif
 
-	if (pobj->m_protectedMap != NULL)
-		CN_CBOR_FREE(pobj->m_protectedMap, context);
-	if (pobj->m_ownUnprotectedMap && (pobj->m_unprotectMap != NULL))
-		CN_CBOR_FREE(pobj->m_unprotectMap, context);
-	if (pobj->m_dontSendMap != NULL)
-		CN_CBOR_FREE(pobj->m_dontSendMap, context);
-	if (pobj->m_ownMsg && (pobj->m_cborRoot != NULL) &&
-		(pobj->m_cborRoot->parent == NULL))
-		CN_CBOR_FREE(pobj->m_cborRoot, context);
+	if (pcose->m_protectedMap != NULL) {
+		CN_CBOR_FREE(pcose->m_protectedMap, context);
+	}
+	if (pcose->m_ownUnprotectedMap && (pcose->m_unprotectMap != NULL)) {
+		CN_CBOR_FREE(pcose->m_unprotectMap, context);
+	}
+	if (pcose->m_dontSendMap != NULL) {
+		CN_CBOR_FREE(pcose->m_dontSendMap, context);
+	}
+	if (pcose->m_ownMsg && (pcose->m_cborRoot != NULL) &&
+		(pcose->m_cborRoot->parent == NULL)) {
+		CN_CBOR_FREE(pcose->m_cborRoot, context);
+	}
+
+#if INCLUDE_COUNTERSIGNATURE
+	if (pcose->m_counterSigners != NULL) {
+		COSE_CounterSign *p = pcose->m_counterSigners;
+		COSE_CounterSign *p2 = NULL;
+
+		while (p != NULL) {
+			p2 = p->m_next;
+			COSE_CounterSign_Free((HCOSE_COUNTERSIGN)p);
+			p = p2;
+		}
+	}
+#endif
 }
 
 HCOSE COSE_Decode(const byte *rgbData,
@@ -172,13 +218,16 @@
 		if (struct_type != 0) {
 			CHECK_CONDITION(struct_type == (COSE_object_type)cbor->v.sint,
 				COSE_ERR_INVALID_PARAMETER);
-		} else
+		}
+		else {
 			struct_type = cbor->v.uint;
+		}
 
 		*ptype = struct_type;
 
 		cbor = cbor->first_child;
-	} else {
+	}
+	else {
 		*ptype = struct_type;
 	}
 
@@ -270,8 +319,9 @@
 
 size_t COSE_Encode(HCOSE msg, byte *rgb, size_t ib, size_t cb)
 {
-	if (rgb == NULL)
+	if (rgb == NULL) {
 		return cn_cbor_encode_size(((COSE *)msg)->m_cbor) + ib;
+	}
 	ssize_t size = cn_cbor_encoder_write(rgb, ib, cb, ((COSE *)msg)->m_cbor);
 	return size >= 0 ? size : 0;
 }
@@ -279,8 +329,9 @@
 cn_cbor *COSE_get_cbor(HCOSE h)
 {
 	COSE *msg = (COSE *)h;
-	if (!IsValidCOSEHandle(h))
+	if (!IsValidCOSEHandle(h)) {
 		return NULL;
+	}
 
 	return msg->m_cbor;
 }
@@ -297,35 +348,36 @@
 	return true;
 }
 
-cn_cbor *_COSE_map_get_int(COSE *pcose,
-	int key,
-	int flags,
-	cose_errback *perror)
+cn_cbor *_COSE_map_get_int(COSE *cose, int key, int flags, cose_errback *perr)
 {
 	cn_cbor *p = NULL;
 
-	if (perror != NULL)
-		perror->err = COSE_ERR_NONE;
-
-	if ((pcose->m_protectedMap != NULL) && ((flags & COSE_PROTECT_ONLY) != 0)) {
-		p = cn_cbor_mapget_int(pcose->m_protectedMap, key);
-		if (p != NULL)
-			return p;
+	if (perr != NULL) {
+		perr->err = COSE_ERR_NONE;
 	}
 
-	if ((pcose->m_unprotectMap != NULL) &&
+	if ((cose->m_protectedMap != NULL) && ((flags & COSE_PROTECT_ONLY) != 0)) {
+		p = cn_cbor_mapget_int(cose->m_protectedMap, key);
+		if (p != NULL) {
+			return p;
+		}
+	}
+
+	if ((cose->m_unprotectMap != NULL) &&
 		((flags & COSE_UNPROTECT_ONLY) != 0)) {
-		p = cn_cbor_mapget_int(pcose->m_unprotectMap, key);
-		if (p != NULL)
+		p = cn_cbor_mapget_int(cose->m_unprotectMap, key);
+		if (p != NULL) {
 			return p;
+		}
 	}
 
-	if ((pcose->m_dontSendMap != NULL) && ((flags & COSE_DONT_SEND) != 0)) {
-		p = cn_cbor_mapget_int(pcose->m_dontSendMap, key);
+	if ((cose->m_dontSendMap != NULL) && ((flags & COSE_DONT_SEND) != 0)) {
+		p = cn_cbor_mapget_int(cose->m_dontSendMap, key);
 	}
 
-	if ((p == NULL) && (perror != NULL))
-		perror->err = COSE_ERR_INVALID_PARAMETER;
+	if ((p == NULL) && (perr != NULL)) {
+		perr->err = COSE_ERR_INVALID_PARAMETER;
+	}
 
 	return p;
 }
@@ -337,13 +389,15 @@
 {
 	cn_cbor *p = NULL;
 
-	if (perror != NULL)
+	if (perror != NULL) {
 		perror->err = COSE_ERR_NONE;
+	}
 
 	if ((pcose->m_protectedMap != NULL) && ((flags & COSE_PROTECT_ONLY) != 0)) {
 		p = cn_cbor_mapget_string(pcose->m_protectedMap, key);
-		if (p != NULL)
+		if (p != NULL) {
 			return p;
+		}
 	}
 
 	if ((pcose->m_unprotectMap != NULL) &&
@@ -358,39 +412,39 @@
 	return p;
 }
 
-bool _COSE_map_put(COSE *pCose,
+bool _COSE_map_put(COSE *cose,
 	int key,
 	cn_cbor *value,
 	int flags,
 	cose_errback *perr)
 {
 #ifdef USE_CBOR_CONTEXT
-	cn_cbor_context *context = &pCose->m_allocContext;
+	cn_cbor_context *context = &cose->m_allocContext;
 #endif
 	cn_cbor_errback error;
 	bool f = false;
 	CHECK_CONDITION(value != NULL, COSE_ERR_INVALID_PARAMETER);
 
-	CHECK_CONDITION(cn_cbor_mapget_int(pCose->m_protectedMap, key) == NULL,
+	CHECK_CONDITION(cn_cbor_mapget_int(cose->m_protectedMap, key) == NULL,
 		COSE_ERR_INVALID_PARAMETER);
-	CHECK_CONDITION(cn_cbor_mapget_int(pCose->m_unprotectMap, key) == NULL,
+	CHECK_CONDITION(cn_cbor_mapget_int(cose->m_unprotectMap, key) == NULL,
 		COSE_ERR_INVALID_PARAMETER);
-	CHECK_CONDITION(cn_cbor_mapget_int(pCose->m_dontSendMap, key) == NULL,
+	CHECK_CONDITION(cn_cbor_mapget_int(cose->m_dontSendMap, key) == NULL,
 		COSE_ERR_INVALID_PARAMETER);
 
 	switch (flags) {
 		case COSE_PROTECT_ONLY:
-			f = cn_cbor_mapput_int(pCose->m_protectedMap, key, value,
+			f = cn_cbor_mapput_int(cose->m_protectedMap, key, value,
 				CBOR_CONTEXT_PARAM_COMMA & error);
 			break;
 
 		case COSE_UNPROTECT_ONLY:
-			f = cn_cbor_mapput_int(pCose->m_unprotectMap, key, value,
+			f = cn_cbor_mapput_int(cose->m_unprotectMap, key, value,
 				CBOR_CONTEXT_PARAM_COMMA & error);
 			break;
 
 		case COSE_DONT_SEND:
-			f = cn_cbor_mapput_int(pCose->m_dontSendMap, key, value,
+			f = cn_cbor_mapput_int(cose->m_dontSendMap, key, value,
 				CBOR_CONTEXT_PARAM_COMMA & error);
 			break;
 
@@ -417,8 +471,9 @@
 	pProtected = cn_cbor_index(pMessage->m_cbor, INDEX_PROTECTED);
 	if ((pProtected != NULL) && (pProtected->type != CN_CBOR_INVALID)) {
 	errorReturn:
-		if (pbProtected != NULL)
+		if (pbProtected != NULL) {
 			COSE_FREE(pbProtected, context);
+		}
 		return pProtected;
 	}
 
@@ -430,7 +485,8 @@
 		CHECK_CONDITION(cn_cbor_encoder_write(pbProtected, 0, cbProtected,
 							pMessage->m_protectedMap) == cbProtected,
 			COSE_ERR_CBOR);
-	} else {
+	}
+	else {
 		cbProtected = 0;
 	}
 
@@ -446,109 +502,6 @@
 	return pProtected;
 }
 
-#ifdef USE_COUNTER_SIGNATURES
-bool _COSE_CounterSign_add(COSE *pMessage,
-	HCOSE_COUNTERSIGN hSigner,
-	cose_errback *perr)
-{
-	COSE_CounterSign *pSigner = (COSE_CounterSign *)hSigner;
-
-	CHECK_CONDITION(IsValidCounterSignHandle(hSigner), COSE_ERR_INVALID_HANDLE);
-	CHECK_CONDITION(
-		pSigner->m_signer.m_signerNext == NULL, COSE_ERR_INVALID_PARAMETER);
-
-	pSigner = pMessage->m_counterSigners;
-	pMessage->m_counterSigners = pSigner;
-	return true;
-
-errorReturn:
-	return false;
-}
-
-HCOSE_COUNTERSIGN _COSE_CounterSign_get(COSE *pMessage,
-	int iSigner,
-	cose_errback *perr)
-{
-	COSE_CounterSign *pSigner = pMessage->m_counterSigners;
-	int i;
-
-	for (i = 0; i < iSigner; i++, pSigner = pSigner->m_next) {
-		CHECK_CONDITION(pSigner != NULL, COSE_ERR_INVALID_PARAMETER);
-	}
-
-	return (HCOSE_COUNTERSIGN)pSigner;
-
-errorReturn:
-	return false;
-}
-
-bool _COSE_CountSign_create(COSE *pMessage,
-	cn_cbor *pcnBody,
-	CBOR_CONTEXT_COMMA cose_errback *perr)
-{
-	cn_cbor *pArray = NULL;
-	cn_cbor_errback cbor_err;
-	COSE_CounterSign *pSigner = NULL;
-	cn_cbor *pcnProtected = NULL;
-	cn_cbor *pcn = NULL;
-	cn_cbor *pcn2 = NULL;
-
-	if (pMessage->m_counterSigners == NULL)
-		return true;
-
-	//  One or more than one?
-	if (pMessage->m_counterSigners->m_signer.m_signerNext != NULL) {
-		pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_err);
-		CHECK_CONDITION_CBOR(pArray != NULL, cbor_err);
-	}
-
-	pcnProtected = _COSE_arrayget_int(pMessage, INDEX_PROTECTED);
-	CHECK_CONDITION(pcnProtected != NULL, COSE_ERR_INTERNAL);
-
-	for (pSigner = pMessage->m_counterSigners; pSigner != NULL;
-		 pSigner = pSigner->m_next) {
-		CHECK_CONDITION(
-			pSigner->m_signer.m_signerNext == NULL, COSE_ERR_INTERNAL);
-
-		pcn = cn_cbor_data_create(pcnProtected->v.bytes, pcnProtected->v.count,
-			CBOR_CONTEXT_PARAM_COMMA & cbor_err);
-		CHECK_CONDITION_CBOR(pcnProtected != NULL, cbor_err);
-
-		pcn2 = cn_cbor_clone(pcnBody, CBOR_CONTEXT_PARAM_COMMA & cbor_err);
-		CHECK_CONDITION_CBOR(pcnBody != NULL, cbor_err);
-
-		if (!_COSE_Signer_sign(&pSigner->m_signer, pcnBody, pcn2, perr))
-			goto errorReturn;
-		pcn = NULL;
-		pcn2 = NULL;
-
-		if (pArray != NULL) {
-			bool f = cn_cbor_array_append(
-				pArray, pSigner->m_signer.m_message.m_cborRoot, &cbor_err);
-			CHECK_CONDITION_CBOR(f, cbor_err);
-		} else {
-			pArray = pSigner->m_signer.m_message.m_cborRoot;
-		}
-	}
-
-	if (!_COSE_map_put(pMessage, COSE_Header_CounterSign, pArray,
-			COSE_UNPROTECT_ONLY, perr))
-		goto errorReturn;
-
-	return true;
-
-errorReturn:
-	if (pArray != NULL)
-		CN_CBOR_FREE(pArray, context);
-	if ((pcn != NULL) && (pcn->parent != NULL))
-		CN_CBOR_FREE(pcn, context);
-	if ((pcn2 != NULL) && (pcn2->parent != NULL))
-		CN_CBOR_FREE(pcn2, context);
-	return false;
-}
-
-#endif
-
 bool _COSE_array_replace(COSE *pMessage,
 	cn_cbor *cb_value,
 	int index,
@@ -577,28 +530,28 @@
 	}
 }
 
-void _COSE_InsertInList(COSE **root, COSE *newMsg)
+void _COSE_InsertInList(COSE **rootNode, COSE *newMsg)
 {
-	if (*root == NULL) {
-		*root = newMsg;
+	if (*rootNode == NULL) {
+		*rootNode = newMsg;
 		return;
 	}
 
-	newMsg->m_handleList = *root;
-	*root = newMsg;
+	newMsg->m_handleList = *rootNode;
+	*rootNode = newMsg;
 	return;
 }
 
-bool _COSE_IsInList(const COSE *const root, const COSE *const thisMsg)
+bool _COSE_IsInList(const COSE *const rootNode, const COSE *const thisMsg)
 {
-	if (root == NULL) {
+	if (rootNode == NULL) {
 		return false;
 	}
 	if (thisMsg == NULL) {
 		return false;
 	}
 
-	for (const COSE *walk = root; walk != NULL; walk = walk->m_handleList) {
+	for (const COSE *walk = rootNode; walk != NULL; walk = walk->m_handleList) {
 		if (walk == thisMsg) {
 			return true;
 		}
@@ -606,17 +559,16 @@
 	return false;
 }
 
-void _COSE_RemoveFromList(COSE **root, COSE *thisMsg)
+void _COSE_RemoveFromList(COSE **rootNode, COSE *thisMsg)
 {
-	COSE *walk;
-
-	if (*root == thisMsg) {
-		*root = thisMsg->m_handleList;
+	if (*rootNode == thisMsg) {
+		*rootNode = thisMsg->m_handleList;
 		thisMsg->m_handleList = NULL;
 		return;
 	}
 
-	for (walk = *root; walk->m_handleList != NULL; walk = walk->m_handleList) {
+	for (COSE *walk = *rootNode; walk->m_handleList != NULL;
+		 walk = walk->m_handleList) {
 		if (walk->m_handleList == thisMsg) {
 			walk->m_handleList = thisMsg->m_handleList;
 			thisMsg->m_handleList = NULL;
@@ -625,3 +577,62 @@
 	}
 	return;
 }
+
+#ifndef NDEBUG
+#if INCLUDE_COUNTERSIGNATURE
+extern COSE *CountersignRoot;
+#endif
+#if INCLUDE_SIGN
+extern COSE *SignerRoot;
+extern COSE *SignRoot;
+#endif
+#if INCLUDE_SIGN1
+extern COSE *Sign1Root;
+#endif
+#if INCLUDE_ENCRYPT0
+extern COSE *EncryptRoot;
+#endif
+#if INCLUDE_ENCRYPT
+extern COSE *EnvelopedRoot;
+#endif
+#if INCLUDE_ENCRYPT || INCLUDE_MAC
+extern COSE *RecipientRoot;
+#endif
+#if INCLUDE_MAC
+extern COSE *MacRoot;
+#endif
+#if INCLUDE_MAC0
+extern COSE *Mac0Root;
+#endif
+
+bool AreListsEmpty()
+{
+	bool fRet = true;
+#if INCLUDE_COUNTERSIGNATURE
+	fRet &= CountersignRoot == NULL;
+#endif
+#if INCLUDE_SIGN
+	fRet &= SignerRoot == NULL && SignRoot == NULL;
+#endif
+#if INCLUDE_SIGN1
+	fRet &= Sign1Root == NULL;
+#endif
+#if INCLUDE_ENCRYPT0
+	fRet &= EncryptRoot == NULL;
+#endif
+#if INCLUDE_ENCRYPT
+	fRet &= EnvelopedRoot == NULL;
+#endif
+#if INCLUDE_ENCRYPT || INCLUDE_MAC
+	fRet &= RecipientRoot == NULL;
+#endif
+#if INCLUDE_MAC
+	fRet &= MacRoot == NULL;
+#endif
+#if INCLUDE_MAC0
+	fRet &= Mac0Root == NULL;
+#endif
+	return fRet;
+}
+
+#endif
diff --git a/src/CounterSign.c b/src/CounterSign.c
new file mode 100644
index 0000000..7047aa0
--- /dev/null
+++ b/src/CounterSign.c
@@ -0,0 +1,964 @@
+#include <stdlib.h>
+#ifndef __MBED__
+#include <memory.h>
+#endif
+
+#include "cose/cose.h"
+#include "cose_int.h"
+#include "cose/cose_configure.h"
+#include "crypto.h"
+
+#if INCLUDE_COUNTERSIGNATURE
+
+COSE* CountersignRoot = NULL;
+
+bool IsValidCounterSignHandle(HCOSE_COUNTERSIGN h)
+{
+	COSE_CounterSign* p = (COSE_CounterSign*)h;
+	return _COSE_IsInList(CountersignRoot, &p->m_signer.m_message);
+}
+
+bool _COSE_CounterSign_Free(COSE_CounterSign* pSigner)
+{
+	if (pSigner->m_signer.m_message.m_refCount > 1) {
+		pSigner->m_signer.m_message.m_refCount--;
+		return true;
+	}
+
+	_COSE_RemoveFromList(&CountersignRoot, &pSigner->m_signer.m_message);
+
+	_COSE_SignerInfo_Release(&pSigner->m_signer);
+
+	COSE_FREE(pSigner, &pSigner->m_signer.m_message.m_allocContext);
+
+	return true;
+}
+
+COSE_CounterSign* _COSE_CounterSign_Init_From_Object(cn_cbor* cbor,
+	COSE_CounterSign* pIn,
+	CBOR_CONTEXT_COMMA cose_errback* perr)
+{
+	COSE_CounterSign* pobj = pIn;
+
+	cose_errback error = {0};
+	if (perr == NULL) {
+		perr = &error;
+	}
+
+	if (pobj == NULL) {
+		pobj = (COSE_CounterSign*)COSE_CALLOC(
+			1, sizeof(COSE_CounterSign), context);
+		CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
+	}
+
+	CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
+	if (!_COSE_SignerInfo_Init_From_Object(
+			cbor, &pobj->m_signer, CBOR_CONTEXT_PARAM_COMMA perr)) {
+		goto errorReturn;
+	}
+
+	if (pIn == NULL) {
+		_COSE_InsertInList(&CountersignRoot, &pobj->m_signer.m_message);
+	}
+
+	return pobj;
+
+errorReturn:
+	if (pobj != NULL) {
+		_COSE_CounterSign_Free(pobj);
+	}
+	return NULL;
+}
+
+bool _COSE_CounterSign_Init(COSE_CounterSign* pobject,
+	CBOR_CONTEXT_COMMA cose_errback* perror)
+{
+	return _COSE_SignerInfo_Init(COSE_INIT_FLAGS_NO_CBOR_TAG,
+		&pobject->m_signer, COSE_countersign_object,
+		CBOR_CONTEXT_PARAM_COMMA perror);
+}
+
+HCOSE_COUNTERSIGN COSE_CounterSign_Init(CBOR_CONTEXT_COMMA cose_errback* perror)
+{
+	COSE_CounterSign* pobject =
+		(COSE_CounterSign*)COSE_CALLOC(1, sizeof(COSE_CounterSign), context);
+	if (pobject == NULL) {
+		if (perror != NULL) {
+			perror->err = COSE_ERR_OUT_OF_MEMORY;
+		}
+		return NULL;
+	}
+
+	if (!_COSE_CounterSign_Init(pobject, CBOR_CONTEXT_PARAM_COMMA perror)) {
+		_COSE_CounterSign_Free(pobject);
+		return NULL;
+	}
+
+	_COSE_InsertInList(&CountersignRoot, &pobject->m_signer.m_message);
+	return (HCOSE_COUNTERSIGN)pobject;
+}
+
+bool COSE_CounterSign_Free(HCOSE_COUNTERSIGN h)
+{
+	COSE_CounterSign* p = (COSE_CounterSign*)h;
+	bool fRet = false;
+
+	if (!IsValidCounterSignHandle(h)) {
+		goto errorReturn;
+	}
+
+	if (p->m_signer.m_message.m_refCount > 1) {
+		p->m_signer.m_message.m_refCount--;
+		return true;
+	}
+
+	fRet = _COSE_CounterSign_Free(p);
+
+errorReturn:
+	return fRet;
+}
+
+///  Add a countersignature to the list used to create the attribute
+///
+bool _COSE_CounterSign_add(COSE* pMessage,
+	HCOSE_COUNTERSIGN hSigner,
+	cose_errback* perr)
+{
+	COSE_CounterSign* pSigner = (COSE_CounterSign*)hSigner;
+
+	CHECK_CONDITION(IsValidCounterSignHandle(hSigner), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(pSigner->m_signer.m_message.m_counterSigners == NULL,
+		COSE_ERR_INVALID_PARAMETER);
+
+	pSigner->m_next = pMessage->m_counterSigners;
+	pMessage->m_counterSigners = pSigner;
+	pSigner->m_signer.m_message.m_refCount += 1;
+	return true;
+
+errorReturn:
+	return false;
+}
+
+#if 0
+/// Get the n-th counter signature from the attribute.
+///
+HCOSE_COUNTERSIGN _COSE_CounterSign_get(COSE* pMessage,
+	int iSigner,
+	cose_errback* perr)
+{
+	COSE_CounterSign* pSigner = pMessage->m_counterSigners;
+
+	for (int i = 0; i < iSigner && pSigner != NULL; i++, pSigner = pSigner->m_next) {
+		CHECK_CONDITION(pSigner != NULL, COSE_ERR_INVALID_PARAMETER);
+	}
+
+	return (HCOSE_COUNTERSIGN)pSigner;
+
+errorReturn:
+	return false;
+}
+#endif
+
+/// _COSE_CounterSign_create
+///
+///	Create the CounterSign attribute based on the set of countersignatures added
+/// to the message.
+///
+
+bool _COSE_CounterSign_create(COSE* pMessage,
+	cn_cbor* pcnBody,
+	CBOR_CONTEXT_COMMA cose_errback* perr)
+{
+	cn_cbor* pArray = NULL;
+	cn_cbor_errback cbor_err;
+	COSE_CounterSign* pSigner = NULL;
+	cn_cbor* pcnProtected = NULL;
+	cn_cbor* pcn = NULL;
+	cn_cbor* pcn2 = NULL;
+
+	if (pMessage->m_counterSigners == NULL) {
+		return true;
+	}
+
+	//  One or more than one?
+	if (pMessage->m_counterSigners->m_signer.m_signerNext != NULL) {
+		pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pArray != NULL, cbor_err);
+	}
+
+	pcnProtected = _COSE_arrayget_int(pMessage, INDEX_PROTECTED);
+	CHECK_CONDITION(pcnProtected != NULL, COSE_ERR_INTERNAL);
+
+	for (pSigner = pMessage->m_counterSigners; pSigner != NULL;
+		 pSigner = pSigner->m_next) {
+		CHECK_CONDITION(
+			pSigner->m_signer.m_signerNext == NULL, COSE_ERR_INTERNAL);
+
+		pcn = cn_cbor_data_create(pcnProtected->v.bytes, pcnProtected->length,
+			CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pcnProtected != NULL, cbor_err);
+
+		pcn2 = cn_cbor_clone(pcnBody, CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pcnBody != NULL, cbor_err);
+
+		if (!_COSE_Signer_sign(
+				&pSigner->m_signer, pcnBody, pcn2, "CounterSignature", perr)) {
+			goto errorReturn;
+		}
+		pcn = NULL;
+		pcn2 = NULL;
+
+		if (pArray != NULL) {
+			bool f = cn_cbor_array_append(
+				pArray, pSigner->m_signer.m_message.m_cborRoot, &cbor_err);
+			CHECK_CONDITION_CBOR(f, cbor_err);
+		}
+		else {
+			pArray = pSigner->m_signer.m_message.m_cborRoot;
+		}
+	}
+
+	if (!_COSE_map_put(pMessage, COSE_Header_CounterSign, pArray,
+			COSE_UNPROTECT_ONLY, perr)) {
+		goto errorReturn;
+	}
+
+	return true;
+
+errorReturn:
+	if (pArray != NULL) {
+		CN_CBOR_FREE(pArray, context);
+	}
+	if ((pcn != NULL) && (pcn->parent != NULL)) {
+		CN_CBOR_FREE(pcn, context);
+	}
+	if ((pcn2 != NULL) && (pcn2->parent != NULL)) {
+		CN_CBOR_FREE(pcn2, context);
+	}
+	return false;
+}
+
+bool COSE_CounterSign_SetKey(HCOSE_COUNTERSIGN h,
+	const cn_cbor* pkey,
+	cose_errback* perr)
+{
+	bool fRet = false;
+	CHECK_CONDITION(IsValidCounterSignHandle(h), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(pkey != NULL, COSE_ERR_INVALID_PARAMETER);
+
+	COSE_CounterSign* p = (COSE_CounterSign*)h;
+	p->m_signer.m_pkey = pkey;
+
+	fRet = true;
+errorReturn:
+	return fRet;
+}
+
+COSE_CounterSign* _COSE_Message_get_countersignature(COSE* pMessage,
+	int index,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(
+		pMessage->m_counterSigners != NULL, COSE_ERR_INVALID_PARAMETER);
+
+	COSE_CounterSign* pCounterSign = pMessage->m_counterSigners;
+
+	for (int i = 0; i < index; i++) {
+		pCounterSign = pCounterSign->m_next;
+		CHECK_CONDITION(pCounterSign != NULL, COSE_ERR_INVALID_PARAMETER);
+	}
+
+	pCounterSign->m_signer.m_message.m_refCount += 1;
+
+	return pCounterSign;
+
+errorReturn:
+	return NULL;
+}
+
+bool COSE_CounterSign_map_put_int(HCOSE_COUNTERSIGN h,
+	int key,
+	cn_cbor* value,
+	int flags,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidCounterSignHandle(h), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(value != NULL, COSE_ERR_INVALID_PARAMETER);
+
+	return _COSE_map_put(
+		&((COSE_CounterSign*)h)->m_signer.m_message, key, value, flags, perr);
+
+errorReturn:
+	return false;
+}
+
+/*!
+ * @brief Set the application external data for authentication
+ *
+ * Signer data objects support the authentication of external application
+ * supplied data.  This function is provided to supply that data to the library.
+ *
+ * The external data is not copied, nor will be it freed when the handle is
+ * released.
+ *
+ * @param hcose  Handle for the COSE MAC data object
+ * @param pbEternalData  point to the external data
+ * @param cbExternalData size of the external data
+ * @param perr  location to return errors
+ * @return result of the operation.
+ */
+
+bool COSE_CounterSign_SetExternal(HCOSE_COUNTERSIGN hcose,
+	const byte* pbExternalData,
+	size_t cbExternalData,
+	cose_errback* perr)
+{
+	if (!IsValidCounterSignHandle(hcose)) {
+		if (perr != NULL) {
+			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
+		return false;
+	}
+
+	return _COSE_SetExternal(&((COSE_CounterSign*)hcose)->m_signer.m_message,
+		pbExternalData, cbExternalData, perr);
+}
+
+bool _COSE_CounterSign_Sign(COSE* baseMessage,
+	CBOR_CONTEXT_COMMA cose_errback* perr)
+{
+	bool fRet = false;
+	cn_cbor* pcborProtectedSign = NULL;
+
+	cn_cbor* pSignature = _COSE_arrayget_int(baseMessage, INDEX_SIGNATURE);
+	int count = 0;
+
+	COSE_CounterSign* pCountersign = baseMessage->m_counterSigners;
+	for (; pCountersign != NULL;
+		 pCountersign = pCountersign->m_next, count += 1) {
+		pcborProtectedSign = _COSE_encode_protected(baseMessage, perr);
+		if (pcborProtectedSign == NULL) {
+			goto errorReturn;
+		}
+		if (!_COSE_Signer_sign(&pCountersign->m_signer, pSignature,
+				pcborProtectedSign, "CounterSignature", perr)) {
+			goto errorReturn;
+		}
+	}
+
+	if (count == 1) {
+		cn_cbor* cn = COSE_get_cbor((HCOSE)baseMessage->m_counterSigners);
+		CHECK_CONDITION(_COSE_map_put(baseMessage, COSE_Header_CounterSign, cn,
+							COSE_UNPROTECT_ONLY, perr),
+			COSE_ERR_OUT_OF_MEMORY);
+	}
+	else {
+		cn_cbor_errback cn_error;
+		cn_cbor* cn_counterSign =
+			cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cn_error);
+		CHECK_CONDITION_CBOR(cn_counterSign, cn_error);
+
+		for (pCountersign = baseMessage->m_counterSigners; pCountersign != NULL;
+			 pCountersign = pCountersign->m_next) {
+			cn_cbor* cn = COSE_get_cbor((HCOSE)pCountersign);
+			CHECK_CONDITION_CBOR(
+				cn_cbor_array_append(cn_counterSign, cn, &cn_error), cn_error);
+		}
+		CHECK_CONDITION(_COSE_map_put(baseMessage, COSE_Header_CounterSign,
+							cn_counterSign, COSE_UNPROTECT_ONLY, perr),
+			COSE_ERR_OUT_OF_MEMORY);
+	}
+
+	fRet = true;
+errorReturn:
+	return fRet;
+}
+
+/*! brief Retrieve header parameter from an enveloped message structure
+ *
+ * Retrieve a header parameter from the message.
+ * Retrieved object is the same as the one in the message - do not delete it
+ *
+ * @param[in]	h	Handle of recipient object
+ * @param[in]    key	Key to look for
+ * @param[in]	flags	What buckets should we look for the message
+ * @param[out]	perror	Location to return error codes
+ * @return	Object which is found or NULL
+ */
+
+cn_cbor* COSE_CounterSign_map_get_int(HCOSE_COUNTERSIGN h,
+	int key,
+	int flags,
+	cose_errback* perror)
+{
+	if (!IsValidCounterSignHandle(h)) {
+		if (perror != NULL) {
+			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
+		return NULL;
+	}
+
+	return _COSE_map_get_int(
+		&((COSE_CounterSign*)h)->m_signer.m_message, key, flags, perror);
+}
+
+#if INCLUDE_SIGN
+/***************************************************************************************************
+ *
+ *   SIGNER
+ */
+HCOSE_COUNTERSIGN COSE_Signer_add_countersignature(HCOSE_SIGNER hSigner,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_SignerInfo*)hSigner)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Signer_get_countersignature(HCOSE_SIGNER hSigner,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_SignerInfo*)hSigner)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Signer_CounterSign_validate(HCOSE_SIGNER hSigner,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_SignerInfo* pSigner = (COSE_SignerInfo*)hSigner;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSigner->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSigner->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+
+/***************************************************************************************************
+ *
+ *   SIGN MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Sign_add_countersignature(HCOSE_SIGN hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Sign_get_countersignature(HCOSE_SIGN hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Sign_CounterSign_validate(HCOSE_SIGN hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_SignMessage* pSignMsg = (COSE_SignMessage*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_SIGN1
+/***************************************************************************************************
+ *
+ *   SIGN1 MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Sign1_add_countersignature(HCOSE_SIGN1 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Sign1_get_countersignature(HCOSE_SIGN1 hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Sign1_CounterSign_validate(HCOSE_SIGN1 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_Sign1Message* pSignMsg = (COSE_Sign1Message*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_ENCRYPT
+/***************************************************************************************************
+ *
+ *   ENVELOPED MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Enveloped_add_countersignature(HCOSE_ENVELOPED hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_Enveloped*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Enveloped_get_countersignature(HCOSE_ENVELOPED hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_Enveloped*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Enveloped_CounterSign_validate(HCOSE_ENVELOPED hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_Enveloped* pSignMsg = (COSE_Enveloped*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_ENCRYPT || INCLUDE_MAC
+/***************************************************************************************************
+ *
+ *   RECIPIENT MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Recipient_add_countersignature(HCOSE_RECIPIENT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_RecipientInfo*)hSignMsg)->m_encrypt.m_message, hCountersign,
+			perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Recipient_get_countersignature(HCOSE_RECIPIENT hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_RecipientInfo*)hSignMsg)->m_encrypt.m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Recipient_CounterSign_validate(HCOSE_RECIPIENT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_RecipientInfo* pSignMsg = (COSE_RecipientInfo*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_encrypt.m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_encrypt.m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_ENCRYPT0
+/***************************************************************************************************
+ *
+ *   ENCRYPT0 MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Encrypt0_add_countersignature(HCOSE_ENCRYPT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Encrypt0_get_countersignature(HCOSE_ENCRYPT hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Encrypt0_CounterSign_validate(HCOSE_ENCRYPT hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_Encrypt* pSignMsg = (COSE_Encrypt*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_MAC0
+/***************************************************************************************************
+ *
+ *   MAC0 MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Mac0_add_countersignature(HCOSE_MAC0 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Mac0_get_countersignature(HCOSE_MAC0 hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Mac0_CounterSign_validate(HCOSE_MAC0 hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_Mac0Message* pSignMsg = (COSE_Mac0Message*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#if INCLUDE_MAC
+/***************************************************************************************************
+ *
+ *   ENCRYPT0 MESSAGE
+ */
+HCOSE_COUNTERSIGN COSE_Mac_add_countersignature(HCOSE_MAC hSignMsg,
+	HCOSE_COUNTERSIGN hCountersign,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);
+
+	if (!_COSE_CounterSign_add(
+			&((COSE_MacMessage*)hSignMsg)->m_message, hCountersign, perr)) {
+		goto errorReturn;
+	}
+
+	return hCountersign;
+
+errorReturn:
+	return NULL;
+}
+
+HCOSE_COUNTERSIGN COSE_Mac_get_countersignature(HCOSE_MAC hSignMsg,
+	int index,
+	cose_errback* perr)
+{
+	COSE_CounterSign* p = NULL;
+
+	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+
+	p = _COSE_Message_get_countersignature(
+		&((COSE_MacMessage*)hSignMsg)->m_message, index, perr);
+
+errorReturn:
+	return (HCOSE_COUNTERSIGN)p;
+}
+
+bool COSE_Mac_CounterSign_validate(HCOSE_MAC hSignMsg,
+	HCOSE_COUNTERSIGN hCountersignature,
+	cose_errback* perr)
+{
+	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
+	CHECK_CONDITION(
+		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);
+
+	COSE_MacMessage* pSignMsg = (COSE_MacMessage*)hSignMsg;
+	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;
+
+	const cn_cbor* cnContent =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
+	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	const cn_cbor* cnProtected =
+		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
+	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
+		COSE_ERR_INVALID_PARAMETER);
+
+	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
+		cnProtected, "CounterSignature", perr);
+
+	return f;
+
+errorReturn:
+	return false;
+}
+#endif
+
+#endif
diff --git a/src/CounterSign0.c b/src/CounterSign0.c
new file mode 100644
index 0000000..dc9e4a2
--- /dev/null
+++ b/src/CounterSign0.c
@@ -0,0 +1,106 @@
+#include <stdlib.h>
+#ifndef __MBED__
+#include <memory.h>
+#endif
+
+#include "cose/cose.h"
+#include "cose_int.h"
+#include "cose/cose_configure.h"
+#include "crypto.h"
+
+#if USE_COUNTER_SIGNATURE1
+
+extern bool IsValidCounterSign1Handle(HCOSE_COUNTERSIGN1 h);
+
+bool _COSE_CounterSign1_add(COSE* pMessage,
+	HCOSE_COUNTERSIGN1 hSigner,
+	cose_errback* perr)
+{
+	COSE_CounterSign1* pSigner = (COSE_CounterSign1*)hSigner;
+
+	CHECK_CONDITION(
+		IsValidCounterSign1Handle(hSigner), COSE_ERR_INVALID_HANDLE);
+
+	pMessage->m_counterSign1 = pSigner;
+	return true;
+
+errorReturn:
+	return false;
+}
+
+HCOSE_COUNTERSIGN _COSE_CounterSign1_get(COSE* pMessage, cose_errback* perr)
+{
+	UNUSED(perr);
+
+	COSE_CounterSign1* pSigner = pMessage->m_counterSign1;
+
+	return (HCOSE_COUNTERSIGN)pSigner;
+}
+
+bool _COSE_CountSign_create(COSE* pMessage,
+	cn_cbor* pcnBody,
+	CBOR_CONTEXT_COMMA cose_errback* perr)
+{
+	cn_cbor* pArray = NULL;
+	cn_cbor_errback cbor_err;
+	COSE_CounterSign1* pSigner = NULL;
+	cn_cbor* pcnProtected = NULL;
+	cn_cbor* pcn = NULL;
+	cn_cbor* pcn2 = NULL;
+
+	if (pMessage->m_counterSigners == NULL)
+		return true;
+
+	//  One or more than one?
+	if (pMessage->m_counterSigners->m_signer.m_signerNext != NULL) {
+		pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pArray != NULL, cbor_err);
+	}
+
+	pcnProtected = _COSE_arrayget_int(pMessage, INDEX_PROTECTED);
+	CHECK_CONDITION(pcnProtected != NULL, COSE_ERR_INTERNAL);
+
+	for (pSigner = pMessage->m_counterSigners; pSigner != NULL;
+		 pSigner = pSigner->m_next) {
+		CHECK_CONDITION(
+			pSigner->m_signer.m_signerNext == NULL, COSE_ERR_INTERNAL);
+
+		pcn = cn_cbor_data_create(pcnProtected->v.bytes, pcnProtected->v.count,
+			CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pcnProtected != NULL, cbor_err);
+
+		pcn2 = cn_cbor_clone(pcnBody, CBOR_CONTEXT_PARAM_COMMA & cbor_err);
+		CHECK_CONDITION_CBOR(pcnBody != NULL, cbor_err);
+
+		if (!_COSE_Signer_sign(&pSigner->m_signer, pcnBody, pcn2, perr))
+			goto errorReturn;
+		pcn = NULL;
+		pcn2 = NULL;
+
+		if (pArray != NULL) {
+			bool f = cn_cbor_array_append(
+				pArray, pSigner->m_signer.m_message.m_cborRoot, &cbor_err);
+			CHECK_CONDITION_CBOR(f, cbor_err);
+		}
+		else {
+			pArray = pSigner->m_signer.m_message.m_cborRoot;
+		}
+	}
+
+	if (!_COSE_map_put(pMessage, COSE_Header_CounterSign, pArray,
+			COSE_UNPROTECT_ONLY, perr))
+		goto errorReturn;
+
+	return true;
+
+errorReturn:
+	if (pArray != NULL)
+		CN_CBOR_FREE(pArray, context);
+	if ((pcn != NULL) && (pcn->parent != NULL))
+		CN_CBOR_FREE(pcn, context);
+	if ((pcn2 != NULL) && (pcn2->parent != NULL))
+		CN_CBOR_FREE(pcn2, context);
+	return false;
+}
+
+#endif
diff --git a/src/Encrypt.c b/src/Encrypt.c
index 1d36a22..022fcc1 100644
--- a/src/Encrypt.c
+++ b/src/Encrypt.c
@@ -18,9 +18,7 @@
 #include "crypto.h"
 
 #if INCLUDE_ENCRYPT || INCLUDE_MAC
-void _COSE_Enveloped_Release(COSE_Enveloped *p);
-
-static COSE *EnvelopedRoot = NULL;
+COSE *EnvelopedRoot = NULL;
 #endif
 
 #if INCLUDE_ENCRYPT
@@ -93,19 +91,20 @@
 	COSE_Enveloped *pobj = pIn;
 	cn_cbor *pRecipients = NULL;
 	cose_errback error = {0};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj =
 			(COSE_Enveloped *)COSE_CALLOC(1, sizeof(COSE_Enveloped), context);
+	}
 	if (pobj == NULL) {
 		perr->err = COSE_ERR_OUT_OF_MEMORY;
 	errorReturn:
-		if (pobj != NULL) {
+		if (pIn == NULL && pobj != NULL) {
 			_COSE_Enveloped_Release(pobj);
-			if (pIn == NULL)
-				COSE_FREE(pobj, context);
+			COSE_FREE(pobj, context);
 		}
 		return NULL;
 	}
@@ -132,8 +131,9 @@
 		}
 	}
 
-	if (pIn == NULL)
+	if (pIn == NULL) {
 		_COSE_InsertInList(&EnvelopedRoot, &pobj->m_message);
+	}
 
 	return (HCOSE_ENVELOPED)pobj;
 }
@@ -147,8 +147,9 @@
 #endif
 	COSE_Enveloped *p = (COSE_Enveloped *)h;
 
-	if (!IsValidEnvelopedHandle(h))
+	if (!IsValidEnvelopedHandle(h)) {
 		return false;
+	}
 
 	if (p->m_message.m_refCount > 1) {
 		p->m_message.m_refCount--;
@@ -175,8 +176,9 @@
 	COSE_RecipientInfo *pRecipient1;
 	COSE_RecipientInfo *pRecipient2;
 
-	if (p->pbContent != NULL)
+	if (p->pbContent != NULL) {
 		COSE_FREE((void *)p->pbContent, &p->m_message.m_allocContext);
+	}
 	//	if (p->pbIV != NULL) COSE_FREE(p->pbIV, &p->m_message.m_allocContext);
 
 	for (pRecipient1 = p->m_recipientFirst; pRecipient1 != NULL;
@@ -241,8 +243,9 @@
 	if (cn == NULL) {
 	error:
 	errorReturn:
-		if (pbAuthData != NULL)
+		if (pbAuthData != NULL) {
 			COSE_FREE(pbAuthData, context);
+		}
 		if (pbKeyNew != NULL) {
 			memset(pbKeyNew, 0xff, cbitKey / 8);
 			COSE_FREE(pbKeyNew, context);
@@ -352,22 +355,27 @@
 				 pRecipX = pRecipX->m_recipientNext) {
 				if (pRecipX == pRecip) {
 					if (!_COSE_Recipient_decrypt(
-							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr))
+							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) {
 						goto errorReturn;
+					}
 					break;
-				} else if (pRecipX->m_encrypt.m_recipientFirst != NULL) {
+				}
+				else if (pRecipX->m_encrypt.m_recipientFirst != NULL) {
 					if (_COSE_Recipient_decrypt(
-							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr))
+							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) {
 						break;
+					}
 				}
 			}
 			CHECK_CONDITION(pRecipX != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
-		} else {
+		}
+		else {
 			for (pRecip = pcose->m_recipientFirst; pRecip != NULL;
 				 pRecip = pRecip->m_recipientNext) {
 				if (_COSE_Recipient_decrypt(
-						pRecip, NULL, alg, cbitKey, pbKeyNew, perr))
+						pRecip, NULL, alg, cbitKey, pbKeyNew, perr)) {
 					break;
+				}
 			}
 			CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
 		}
@@ -377,8 +385,9 @@
 	//  Build authenticated data
 
 	if (!_COSE_Encrypt_Build_AAD(
-			&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr))
+			&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) {
 		goto errorReturn;
+	}
 
 	cn = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
 	CHECK_CONDITION(cn != NULL, COSE_ERR_INVALID_PARAMETER);
@@ -387,88 +396,99 @@
 #ifdef USE_AES_CCM_16_64_128
 		case COSE_Algorithm_AES_CCM_16_64_128:
 			if (!AES_CCM_Decrypt(pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_64_256
 		case COSE_Algorithm_AES_CCM_16_64_256:
 			if (!AES_CCM_Decrypt(pcose, 64, 16, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_128_128
 		case COSE_Algorithm_AES_CCM_16_128_128:
 			if (!AES_CCM_Decrypt(pcose, 128, 16, pbKey, cbitKey / 8,
-					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr))
+					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_128_256
 		case COSE_Algorithm_AES_CCM_16_128_256:
 			if (!AES_CCM_Decrypt(pcose, 128, 16, pbKey, cbitKey / 8,
-					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr))
+					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_64_128
 		case COSE_Algorithm_AES_CCM_64_64_128:
 			if (!AES_CCM_Decrypt(pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_64_256
 		case COSE_Algorithm_AES_CCM_64_64_256:
 			if (!AES_CCM_Decrypt(pcose, 64, 64, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_128_128
 		case COSE_Algorithm_AES_CCM_64_128_128:
 			if (!AES_CCM_Decrypt(pcose, 128, 64, pbKey, cbitKey / 8,
-					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr))
+					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_128_256
 		case COSE_Algorithm_AES_CCM_64_128_256:
 			if (!AES_CCM_Decrypt(pcose, 128, 64, pbKey, cbitKey / 8,
-					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr))
+					cn->v.bytes, cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_128
 		case COSE_Algorithm_AES_GCM_128:
 			if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_192
 		case COSE_Algorithm_AES_GCM_192:
 			if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_256
 		case COSE_Algorithm_AES_GCM_256:
 			if (!AES_GCM_Decrypt(pcose, pbKey, cbitKey / 8, cn->v.bytes,
-					cn->length, pbAuthData, cbAuthData, perr))
+					cn->length, pbAuthData, cbAuthData, perr)) {
 				goto error;
+			}
 			break;
 #endif
 
@@ -477,12 +497,15 @@
 			break;
 	}
 
-	if (pbAuthData != NULL)
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
-	if (pbKeyNew != NULL)
+	}
+	if (pbKeyNew != NULL) {
 		COSE_FREE(pbKeyNew, context);
-	if (perr != NULL)
+	}
+	if (perr != NULL) {
 		perr->err = COSE_ERR_NONE;
+	}
 
 	return true;
 }
@@ -526,8 +549,9 @@
 
 	cn_Alg = _COSE_map_get_int(
 		&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn_Alg == NULL)
+	if (cn_Alg == NULL) {
 		goto errorReturn;
+	}
 
 	CHECK_CONDITION((cn_Alg->type != CN_CBOR_TEXT), COSE_ERR_UNKNOWN_ALGORITHM);
 	CHECK_CONDITION(
@@ -629,9 +653,11 @@
 				pbKeyNew =
 					_COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
 				cbKey = cbitKey / 8;
-				if (pbKeyNew == NULL)
+				if (pbKeyNew == NULL) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				t |= 2;
 			}
 		}
@@ -651,110 +677,115 @@
 
 	const cn_cbor *cbProtected =
 		_COSE_encode_protected(&pcose->m_message, perr);
-	if (cbProtected == NULL)
-		goto errorReturn;
-
-#ifdef USE_COUNTER_SIGNATURES
-	//  Setup Counter Signatures
-	if (!_COSE_CountSign_create(
-			&pcose->m_message, NULL, CBOR_CONTEXT_PARAM_COMMA perr)) {
+	if (cbProtected == NULL) {
 		goto errorReturn;
 	}
-#endif
 
 	//  Build authenticated data
 
 	size_t cbAuthData = 0;
 	if (!_COSE_Encrypt_Build_AAD(
-			&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr))
+			&pcose->m_message, &pbAuthData, &cbAuthData, szContext, perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_AES_CCM_16_64_128
 		case COSE_Algorithm_AES_CCM_16_64_128:
-			if (!AES_CCM_Encrypt(
-					pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 64, 16, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_64_256
 		case COSE_Algorithm_AES_CCM_16_64_256:
-			if (!AES_CCM_Encrypt(
-					pcose, 64, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 64, 16, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_128_128
 		case COSE_Algorithm_AES_CCM_16_128_128:
-			if (!AES_CCM_Encrypt(
-					pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 128, 16, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_16_128_256
 		case COSE_Algorithm_AES_CCM_16_128_256:
-			if (!AES_CCM_Encrypt(
-					pcose, 128, 16, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 128, 16, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_64_128
 		case COSE_Algorithm_AES_CCM_64_64_128:
-			if (!AES_CCM_Encrypt(
-					pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 64, 64, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_64_256
 		case COSE_Algorithm_AES_CCM_64_64_256:
-			if (!AES_CCM_Encrypt(
-					pcose, 64, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 64, 64, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_128_128
 		case COSE_Algorithm_AES_CCM_64_128_128:
-			if (!AES_CCM_Encrypt(
-					pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 128, 64, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CCM_64_128_256
 		case COSE_Algorithm_AES_CCM_64_128_256:
-			if (!AES_CCM_Encrypt(
-					pcose, 128, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!AES_CCM_Encrypt(pcose, 128, 64, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_128
 		case COSE_Algorithm_AES_GCM_128:
 			if (!AES_GCM_Encrypt(
-					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_192
 		case COSE_Algorithm_AES_GCM_192:
 			if (!AES_GCM_Encrypt(
-					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_GCM_256
 		case COSE_Algorithm_AES_GCM_256:
 			if (!AES_GCM_Encrypt(
-					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -762,21 +793,32 @@
 			FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
 	}
 
-#ifdef INCLUDE_ENCRYPT
+#if INCLUDE_ENCRYPT
 	for (pri = pcose->m_recipientFirst; pri != NULL;
 		 pri = pri->m_recipientNext) {
-		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr))
+		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr)) {
 			goto errorReturn;
+		}
 	}
 #endif	// INCLUDE_ENCRYPT
 
+#if INCLUDE_COUNTERSIGNATURE
+	if (pcose->m_message.m_counterSigners != NULL) {
+		if (!_COSE_CounterSign_Sign(
+				&pcose->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
+			goto errorReturn;
+		}
+	}
+#endif
+
 	//  Figure out the clean up
 
 	fRet = true;
 
 errorReturn:
-	if (pbAuthData != NULL)
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
+	}
 	if (pbKeyNew != NULL) {
 		memset(pbKeyNew, 0, cbKey);
 		COSE_FREE(pbKeyNew, context);
@@ -841,8 +883,9 @@
 	cose->pbContent = pb =
 		(byte *)COSE_CALLOC(cb, 1, &cose->m_message.m_allocContext);
 	if (cose->pbContent == NULL) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 	memcpy(pb, rgb, cb);
@@ -869,8 +912,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidEnvelopedHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
@@ -928,8 +972,9 @@
 		if (!_COSE_array_replace(&pEncrypt->m_message, pRecipients,
 				INDEX_RECIPIENTS, CBOR_CONTEXT_PARAM_COMMA & cbor_error)) {
 			CN_CBOR_FREE(pRecipients, context);
-			if (perr != NULL)
+			if (perr != NULL) {
 				perr->err = _MapFromCBOR(cbor_error);
+			}
 			goto errorReturn;
 		}
 	}
@@ -980,7 +1025,8 @@
 	if ((pItem->length == 1) && (pItem->v.bytes[0] == 0xa0)) {
 		ptmp =
 			cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else {
+	}
+	else {
 		ptmp = cn_cbor_data_create(pItem->v.bytes, (int)pItem->length,
 			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 	}
@@ -1020,12 +1066,15 @@
 	return true;
 
 errorReturn:
-	if (pbAuthData != NULL)
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
-	if (ptmp != NULL)
+	}
+	if (ptmp != NULL) {
 		CN_CBOR_FREE(ptmp, NULL);
-	if (pAuthData != NULL)
+	}
+	if (pAuthData != NULL) {
 		CN_CBOR_FREE(pAuthData, context);
+	}
 	return false;
 }
 #endif
@@ -1046,37 +1095,12 @@
 		CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
 		p = p->m_recipientNext;
 	}
-	if (p != NULL)
+	if (p != NULL) {
 		p->m_encrypt.m_message.m_refCount++;
+	}
 
 errorReturn:
 	return (HCOSE_RECIPIENT)p;
 }
 
-#ifdef USE_COUNTER_SIGNATURES
-bool COSE_Enveloped_AddCounterSigner(HCOSE_ENCRYPT hEnv,
-	HCOSE_COUNTERSIGN hSign,
-	cose_errback *perr)
-{
-	CHECK_CONDITION(IsValidEncryptHandle(hEnv), COSE_ERR_INVALID_HANDLE);
-	return _COSE_CounterSign_add(
-		&((COSE_Enveloped *)hEnv)->m_message, hSign, perr);
-
-errorReturn:
-	return false;
-}
-
-HCOSE_COUNTERSIGN COSE_Enveloped_GetCounterSigner(HCOSE_ENCRYPT h,
-	int iSigner,
-	cose_errback *perr)
-{
-	CHECK_CONDITION(IsValidEncryptHandle(h), COSE_ERR_INVALID_HANDLE);
-	return _COSE_CounterSign_get(
-		&((COSE_Enveloped *)h)->m_message, iSigner, perr);
-
-errorReturn:
-	return NULL;
-}
-#endif
-
 #endif
diff --git a/src/Encrypt0.c b/src/Encrypt0.c
index fa0885a..3d7227b 100644
--- a/src/Encrypt0.c
+++ b/src/Encrypt0.c
@@ -16,9 +16,8 @@
 #include "crypto.h"
 
 #if INCLUDE_ENCRYPT0 || INCLUDE_MAC0
-void _COSE_Encrypt_Release(COSE_Encrypt *p);
 
-static COSE *EncryptRoot = NULL;
+COSE *EncryptRoot = NULL;
 #endif
 
 #if INCLUDE_ENCRYPT0
@@ -75,8 +74,9 @@
 	COSE_Encrypt *pobj;
 
 	cose_errback error = {0};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
 	pobj = (COSE_Encrypt *)COSE_CALLOC(1, sizeof(COSE_Encrypt), context);
 	if (pobj == NULL) {
@@ -108,18 +108,21 @@
 	COSE_Encrypt *pobj = pIn;
 	cn_cbor *pRecipients = NULL;
 	cose_errback error = {0};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj = (COSE_Encrypt *)COSE_CALLOC(1, sizeof(COSE_Encrypt), context);
+	}
 	if (pobj == NULL) {
 		perr->err = COSE_ERR_OUT_OF_MEMORY;
 	errorReturn:
 		if (pobj != NULL) {
 			_COSE_Encrypt_Release(pobj);
-			if (pIn == NULL)
+			if (pIn == NULL) {
 				COSE_FREE(pobj, context);
+			}
 		}
 		return NULL;
 	}
@@ -144,8 +147,9 @@
 #endif
 	COSE_Encrypt *pEncrypt = (COSE_Encrypt *)h;
 
-	if (!IsValidEncryptHandle(h))
+	if (!IsValidEncryptHandle(h)) {
 		return false;
+	}
 
 #ifdef USE_CBOR_CONTEXT
 	context = &((COSE_Encrypt *)h)->m_message.m_allocContext;
@@ -164,8 +168,9 @@
 #if INCLUDE_ENCRYPT0 || INCLUDE_MAC0
 void _COSE_Encrypt_Release(COSE_Encrypt *p)
 {
-	if (p->pbContent != NULL)
+	if (p->pbContent != NULL) {
 		COSE_FREE((void *)p->pbContent, &p->m_message.m_allocContext);
+	}
 
 	_COSE_Release(&p->m_message);
 }
@@ -181,8 +186,9 @@
 	bool f;
 
 	if (!IsValidEncryptHandle(h)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -211,8 +217,9 @@
 {
 	COSE_Encrypt *cose = (COSE_Encrypt *)h;
 	if (!IsValidEncryptHandle(h) || (pcbContent == NULL)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -226,8 +233,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidEncryptHandle(h) || (rgb == NULL)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -243,8 +251,9 @@
 	cose->pbContent = pb =
 		(byte *)COSE_CALLOC(cb, 1, &cose->m_message.m_allocContext);
 	if (cose->pbContent == NULL) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 	memcpy(pb, rgb, cb);
@@ -275,8 +284,9 @@
 	cose_errback *perr)
 {
 	if (!IsValidEncryptHandle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -290,8 +300,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidEncryptHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return NULL;
 	}
 
@@ -306,8 +317,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidEncryptHandle(h) || (value == NULL)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
diff --git a/src/MacMessage.c b/src/MacMessage.c
index a051be5..96ef06a 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -17,7 +17,7 @@
 
 #if INCLUDE_MAC
 
-static COSE *MacRoot = NULL;
+COSE *MacRoot = NULL;
 
 /*! \private
  * @brief Test if a HCOSE_MAC handle is valid
@@ -74,12 +74,14 @@
 	cn_cbor *pRecipients = NULL;
 	// cn_cbor * tmp;
 	cose_errback error = {COSE_ERR_NONE};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj =
 			(COSE_MacMessage *)COSE_CALLOC(1, sizeof(COSE_MacMessage), context);
+	}
 	if (pobj == NULL) {
 		perr->err = COSE_ERR_OUT_OF_MEMORY;
 	errorReturn:
@@ -106,8 +108,9 @@
 		while (pRecipients != NULL) {
 			COSE_RecipientInfo *pInfo = _COSE_Recipient_Init_From_Object(
 				pRecipients, CBOR_CONTEXT_PARAM_COMMA perr);
-			if (pInfo == NULL)
+			if (pInfo == NULL) {
 				goto errorReturn;
+			}
 
 			pInfo->m_recipientNext = pobj->m_recipientFirst;
 			pobj->m_recipientFirst = pInfo;
@@ -127,8 +130,9 @@
 #endif
 	COSE_MacMessage *p = (COSE_MacMessage *)h;
 
-	if (!IsValidMacHandle(h))
+	if (!IsValidMacHandle(h)) {
 		return false;
+	}
 
 	if (p->m_message.m_refCount > 1) {
 		p->m_message.m_refCount--;
@@ -156,7 +160,7 @@
 	for (pRecipient = p->m_recipientFirst; pRecipient != NULL;
 		 pRecipient = pRecipient2) {
 		pRecipient2 = pRecipient->m_recipientNext;
-		_COSE_Recipient_Free(pRecipient);
+		COSE_Recipient_Free((HCOSE_RECIPIENT)pRecipient);
 	}
 
 	_COSE_Release(&p->m_message);
@@ -190,8 +194,9 @@
 	return true;
 
 errorReturn:
-	if (ptmp != NULL)
+	if (ptmp != NULL) {
 		CN_CBOR_FREE(ptmp, context);
+	}
 	return false;
 }
 
@@ -217,8 +222,9 @@
 	cose_errback *perr)
 {
 	if (!IsValidMacHandle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -232,8 +238,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidMacHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return NULL;
 	}
 
@@ -248,8 +255,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidMacHandle(h) || (value == NULL)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -298,7 +306,8 @@
 
 	if ((pcn->length == 1) && (pcn->v.bytes[0] == 0xa0)) {
 		ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	} else {
+	}
+	else {
 		ptmp = cn_cbor_data_create(
 			pcn->v.bytes, (int)pcn->length, CBOR_CONTEXT_PARAM_COMMA NULL);
 	}
@@ -340,12 +349,15 @@
 	fRet = true;
 
 errorReturn:
-	if (pbAuthData != NULL)
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
-	if (pAuthData != NULL)
+	}
+	if (pAuthData != NULL) {
 		CN_CBOR_FREE(pAuthData, context);
-	if (ptmp != NULL)
+	}
+	if (ptmp != NULL) {
 		CN_CBOR_FREE(ptmp, context);
+	}
 	return fRet;
 }
 #endif
@@ -390,8 +402,9 @@
 
 	cn_Alg = _COSE_map_get_int(
 		&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn_Alg == NULL)
+	if (cn_Alg == NULL) {
 		goto errorReturn;
+	}
 	CHECK_CONDITION(cn_Alg->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
 	CHECK_CONDITION(
 		((cn_Alg->type == CN_CBOR_UINT || cn_Alg->type == CN_CBOR_INT)),
@@ -460,7 +473,8 @@
 		CHECK_CONDITION(cbKeyIn == cbitKey / 8, COSE_ERR_INVALID_PARAMETER);
 		pbKey = pbKeyIn;
 		cbKey = cbKeyIn;
-	} else {
+	}
+	else {
 		t = 0;
 		for (pri = pcose->m_recipientFirst; pri != NULL;
 			 pri = pri->m_recipientNext) {
@@ -473,7 +487,8 @@
 				cbKey = cbitKey / 8;
 				CHECK_CONDITION(pbKeyNew != NULL, COSE_ERR_OUT_OF_MEMORY);
 				pbKey = pbKeyNew;
-			} else {
+			}
+			else {
 				t |= 2;
 			}
 		}
@@ -492,77 +507,87 @@
 
 	const cn_cbor *cbProtected =
 		_COSE_encode_protected(&pcose->m_message, perr);
-	if (cbProtected == NULL)
+	if (cbProtected == NULL) {
 		goto errorReturn;
+	}
 
 	//  Build authenticated data
 
 	if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData,
-			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr))
+			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_AES_CBC_MAC_128_64
 		case COSE_Algorithm_CBC_MAC_128_64:
 			if (!AES_CBC_MAC_Create(
-					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_256_64
 		case COSE_Algorithm_CBC_MAC_256_64:
 			if (!AES_CBC_MAC_Create(
-					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_128_128
 		case COSE_Algorithm_CBC_MAC_128_128:
 			if (!AES_CBC_MAC_Create(
-					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_256_128
 		case COSE_Algorithm_CBC_MAC_256_128:
 			if (!AES_CBC_MAC_Create(
-					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+					pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_256_64
 		case COSE_Algorithm_HMAC_256_64:
-			if (!HMAC_Create(
-					pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr))
+			if (!HMAC_Create(pcose, 256, 64, pbKey, cbKey, pbAuthData,
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_256_256
 		case COSE_Algorithm_HMAC_256_256:
 			if (!HMAC_Create(pcose, 256, 256, pbKey, cbKey, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_384_384
 		case COSE_Algorithm_HMAC_384_384:
 			if (!HMAC_Create(pcose, 384, 384, pbKey, cbKey, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_512_512
 		case COSE_Algorithm_HMAC_512_512:
 			if (!HMAC_Create(pcose, 512, 512, pbKey, cbKey, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -572,10 +597,20 @@
 
 	for (pri = pcose->m_recipientFirst; pri != NULL;
 		 pri = pri->m_recipientNext) {
-		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr))
+		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr)) {
 			goto errorReturn;
+		}
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	if (pcose->m_message.m_counterSigners != NULL) {
+		if (!_COSE_CounterSign_Sign(
+				&pcose->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
+			goto errorReturn;
+		}
+	}
+#endif
+
 	//  Figure out the clean up
 
 	fRet = true;
@@ -585,8 +620,9 @@
 		memset(pbKeyNew, 0, cbKey);
 		COSE_FREE(pbKeyNew, context);
 	}
-	if (pbAuthData != NULL)
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
+	}
 	return fRet;
 }
 #endif
@@ -633,12 +669,14 @@
 
 	cn = _COSE_map_get_int(
 		&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn == NULL)
+	if (cn == NULL) {
 		goto errorReturn;
+	}
 
 	if (cn->type == CN_CBOR_TEXT) {
 		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
-	} else {
+	}
+	else {
 		CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT),
 			COSE_ERR_INVALID_PARAMETER);
 
@@ -703,7 +741,8 @@
 	if (pbKeyIn != NULL) {
 		CHECK_CONDITION(cbitKey / 8 == cbKeyIn, COSE_ERR_INVALID_PARAMETER);
 		pbKey = pbKeyIn;
-	} else {
+	}
+	else {
 		if (pbKeyNew == NULL) {
 			pbKeyNew = COSE_CALLOC(cbitKey / 8, 1, context);
 			CHECK_CONDITION(pbKeyNew != NULL, COSE_ERR_OUT_OF_MEMORY);
@@ -719,22 +758,27 @@
 				 pRecipX = pRecipX->m_recipientNext) {
 				if (pRecip == pRecipX) {
 					if (!_COSE_Recipient_decrypt(
-							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr))
+							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) {
 						goto errorReturn;
+					}
 					break;
-				} else if (pRecipX->m_encrypt.m_recipientFirst != NULL) {
+				}
+				else if (pRecipX->m_encrypt.m_recipientFirst != NULL) {
 					if (_COSE_Recipient_decrypt(
-							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr))
+							pRecipX, pRecip, alg, cbitKey, pbKeyNew, perr)) {
 						break;
+					}
 				}
 			}
 			CHECK_CONDITION(pRecipX != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
-		} else {
+		}
+		else {
 			for (pRecip = pcose->m_recipientFirst; pRecip != NULL;
 				 pRecip = pRecip->m_recipientNext) {
 				if (_COSE_Recipient_decrypt(
-						pRecip, NULL, alg, cbitKey, pbKeyNew, perr))
+						pRecip, NULL, alg, cbitKey, pbKeyNew, perr)) {
 					break;
+				}
 			}
 			CHECK_CONDITION(pRecip != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
 		}
@@ -743,71 +787,80 @@
 	//  Build authenticated data
 
 	if (!_COSE_Mac_Build_AAD(&pcose->m_message, szContext, &pbAuthData,
-			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr))
+			&cbAuthData, CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_HMAC_256_256
 		case COSE_Algorithm_HMAC_256_256:
 			if (!HMAC_Validate(pcose, 256, 256, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_256_64
 		case COSE_Algorithm_HMAC_256_64:
 			if (!HMAC_Validate(pcose, 256, 64, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_384_384
 		case COSE_Algorithm_HMAC_384_384:
 			if (!HMAC_Validate(pcose, 384, 384, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_HMAC_512_512
 		case COSE_Algorithm_HMAC_512_512:
 			if (!HMAC_Validate(pcose, 512, 512, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_128_64
 		case COSE_Algorithm_CBC_MAC_128_64:
 			if (!AES_CBC_MAC_Validate(pcose, 64, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_256_64
 		case COSE_Algorithm_CBC_MAC_256_64:
 			if (!AES_CBC_MAC_Validate(pcose, 64, pbKey, cbitKey / 8, pbAuthData,
-					cbAuthData, perr))
+					cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_128_128
 		case COSE_Algorithm_CBC_MAC_128_128:
 			if (!AES_CBC_MAC_Validate(pcose, 128, pbKey, cbitKey / 8,
-					pbAuthData, cbAuthData, perr))
+					pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_AES_CBC_MAC_256_128
 		case COSE_Algorithm_CBC_MAC_256_128:
 			if (!AES_CBC_MAC_Validate(pcose, 128, pbKey, cbitKey / 8,
-					pbAuthData, cbAuthData, perr))
+					pbAuthData, cbAuthData, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -877,8 +930,9 @@
 	return true;
 
 errorReturn:
-	if (pRecipientsT == NULL)
+	if (pRecipientsT == NULL) {
 		CN_CBOR_FREE(pRecipientsT, context);
+	}
 	return false;
 }
 
@@ -896,8 +950,9 @@
 		CHECK_CONDITION(p != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
 		p = p->m_recipientNext;
 	}
-	if (p != NULL)
+	if (p != NULL) {
 		p->m_encrypt.m_message.m_refCount++;
+	}
 	return (HCOSE_RECIPIENT)p;
 
 errorReturn:
diff --git a/src/MacMessage0.c b/src/MacMessage0.c
index 1cc1293..ce6df54 100644
--- a/src/MacMessage0.c
+++ b/src/MacMessage0.c
@@ -18,7 +18,7 @@
 
 #if INCLUDE_MAC0
 
-static COSE *Mac0Root = NULL;
+COSE *Mac0Root = NULL;
 
 /*! \private
  * @brief Test if a HCOSE_MAC0 handle is valid
@@ -76,12 +76,14 @@
 	cn_cbor *pRecipients = NULL;
 	// cn_cbor * tmp;
 	cose_errback error = {COSE_ERR_NONE};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj = (COSE_Mac0Message *)COSE_CALLOC(
 			1, sizeof(COSE_Mac0Message), context);
+	}
 	if (pobj == NULL) {
 		perr->err = COSE_ERR_OUT_OF_MEMORY;
 	errorReturn:
@@ -114,8 +116,9 @@
 #endif
 	COSE_Mac0Message *p = (COSE_Mac0Message *)h;
 
-	if (!IsValidMac0Handle(h))
+	if (!IsValidMac0Handle(h)) {
 		return false;
+	}
 
 	if (p->m_message.m_refCount > 1) {
 		p->m_message.m_refCount--;
@@ -168,8 +171,9 @@
 	return true;
 
 errorReturn:
-	if (ptmp != NULL)
+	if (ptmp != NULL) {
 		CN_CBOR_FREE(ptmp, context);
+	}
 	return false;
 }
 
@@ -195,8 +199,9 @@
 	cose_errback *perr)
 {
 	if (!IsValidMac0Handle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -210,8 +215,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidMac0Handle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return NULL;
 	}
 
@@ -226,8 +232,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidMac0Handle(h) || (value == NULL)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
diff --git a/src/Recipient.c b/src/Recipient.c
index b597a57..ef48eaa 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -18,7 +18,7 @@
 #endif
 
 #if INCLUDE_ENCRYPT || INCLUDE_MAC
-static COSE *RecipientRoot = NULL;
+COSE *RecipientRoot = NULL;
 
 /*! \private
  * @brief Test if a HCOSE_RECIPIENT handle is valid
@@ -37,8 +37,9 @@
 {
 	COSE_RecipientInfo *p = (COSE_RecipientInfo *)h;
 
-	if (p == NULL)
+	if (p == NULL) {
 		return false;
+	}
 	return _COSE_IsInList(RecipientRoot, &p->m_encrypt.m_message);
 }
 
@@ -68,6 +69,12 @@
 {
 	if (IsValidRecipientHandle(hRecipient)) {
 		COSE_RecipientInfo *p = (COSE_RecipientInfo *)hRecipient;
+
+		if (p->m_encrypt.m_message.m_refCount > 1) {
+			p->m_encrypt.m_message.m_refCount--;
+			return true;
+		}
+
 		_COSE_RemoveFromList(&RecipientRoot, &p->m_encrypt.m_message);
 
 		_COSE_Recipient_Free(p);
@@ -86,18 +93,21 @@
 	HCOSE_RECIPIENT hRecipient = NULL;
 
 	hRecipient = COSE_Recipient_Init(0, CBOR_CONTEXT_PARAM_COMMA perr);
-	if (hRecipient == NULL)
+	if (hRecipient == NULL) {
 		goto errorReturn;
+	}
 
 	if (!COSE_Recipient_SetKey_secret(
-			hRecipient, rgbKey, cbKey, rgbKid, cbKid, perr))
+			hRecipient, rgbKey, cbKey, rgbKid, cbKid, perr)) {
 		goto errorReturn;
+	}
 
 	return hRecipient;
 
 errorReturn:
-	if (hRecipient != NULL)
+	if (hRecipient != NULL) {
 		COSE_Recipient_Free(hRecipient);
+	}
 	return NULL;
 }
 
@@ -122,8 +132,9 @@
 	return pRecipient;
 
 errorReturn:
-	if (pRecipient != NULL)
+	if (pRecipient != NULL) {
 		_COSE_Recipient_Free(pRecipient);
+	}
 	return NULL;
 }
 
@@ -134,6 +145,7 @@
 		return;
 	}
 
+	_COSE_Enveloped_Release(&pRecipient->m_encrypt);
 	COSE_FREE(pRecipient, &pRecipient->m_encrypt.m_message.m_allocContext);
 
 	return;
@@ -180,8 +192,9 @@
 	size_t cbSecret = 0;
 
 	if (!BuildContextBytes(pCose, algResult, cbitKey, &pbContext, &cbContext,
-			CBOR_CONTEXT_PARAM_COMMA perr))
+			CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
 	if (fECDH) {
 #ifdef USE_ECDH
@@ -208,14 +221,17 @@
 			pkeyMessage = (cn_cbor *)pKeyPrivate;
 
 			if (!ECDH_ComputeSecret(pCose, &pkeyMessage, pKeyPublic, &pbSecret,
-					&cbSecret, CBOR_CONTEXT_PARAM_COMMA perr))
+					&cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!fStatic && pkeyMessage->parent == NULL) {
 				if (!_COSE_map_put(pCose, COSE_Header_ECDH_EPHEMERAL,
-						pkeyMessage, COSE_UNPROTECT_ONLY, perr))
+						pkeyMessage, COSE_UNPROTECT_ONLY, perr)) {
 					goto errorReturn;
+				}
 			}
-		} else {
+		}
+		else {
 			pkeyMessage = _COSE_map_get_int(pCose,
 				fStatic ? COSE_Header_ECDH_STATIC : COSE_Header_ECDH_EPHEMERAL,
 				COSE_BOTH, perr);
@@ -225,13 +241,15 @@
 
 			if (!ECDH_ComputeSecret(pCose, (cn_cbor **)&pKeyPrivate,
 					pkeyMessage, &pbSecret, &cbSecret,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 		}
 #else
 		goto errorReturn;
 #endif
-	} else {
+	}
+	else {
 		CHECK_CONDITION(pKeyPrivate != NULL, COSE_ERR_INVALID_PARAMETER);
 		cn = cn_cbor_mapget_int(pKeyPrivate, COSE_Key_Type);
 		CHECK_CONDITION((cn != NULL) && (cn->type == CN_CBOR_UINT),
@@ -251,20 +269,24 @@
 	if (fHMAC) {
 #ifdef USE_HKDF_SHA2
 		if (!HKDF_Extract(pCose, pbSecret, cbSecret, cbitHash, rgbDigest,
-				&cbDigest, CBOR_CONTEXT_PARAM_COMMA perr))
+				&cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) {
 			goto errorReturn;
+		}
 
 		if (!HKDF_Expand(pCose, cbitHash, rgbDigest, cbDigest, pbContext,
-				cbContext, pbKey, cbitKey / 8, perr))
+				cbContext, pbKey, cbitKey / 8, perr)) {
 			goto errorReturn;
+		}
 #else
 		goto errorReturn;
 #endif
-	} else {
+	}
+	else {
 #ifdef USE_HKDF_AES
 		if (!HKDF_AES_Expand(pCose, cbitHash, pbSecret, cbSecret, pbContext,
-				cbContext, pbKey, cbitKey / 8, perr))
+				cbContext, pbKey, cbitKey / 8, perr)) {
 			goto errorReturn;
+		}
 #else
 		goto errorReturn;
 #endif
@@ -277,8 +299,9 @@
 		COSE_FREE(pbSecret, context);
 	}
 	memset(rgbDigest, 0, sizeof(rgbDigest));
-	if (pbContext != NULL)
+	if (pbContext != NULL) {
 		COSE_FREE(pbContext, context);
+	}
 	return fRet;
 }
 #endif	// defined(USE_HKDF_SHA2) || defined(USE_HKDF_AES)
@@ -318,14 +341,18 @@
 		&pRecip->m_encrypt.m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
 	if (cn == NULL) {
 	errorReturn:
-		if (pbContext != NULL)
+		if (pbContext != NULL) {
 			COSE_FREE(pbContext, context);
-		if (pbProtected != NULL)
+		}
+		if (pbProtected != NULL) {
 			COSE_FREE(pbProtected, context);
-		if (pbAuthData != NULL)
+		}
+		if (pbAuthData != NULL) {
 			COSE_FREE(pbAuthData, context);
-		if (pbSecret != NULL)
+		}
+		if (pbSecret != NULL) {
 			COSE_FREE(pbSecret, context);
+		}
 		return false;
 	}
 	CHECK_CONDITION(cn->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
@@ -449,8 +476,9 @@
 		for (pRecip2 = pcose->m_recipientFirst; pRecip2 != NULL;
 			 pRecip2 = pRecip->m_recipientNext) {
 			if (_COSE_Recipient_decrypt(
-					pRecip2, NULL, alg, cbitKeyX, pbKeyX, perr))
+					pRecip2, NULL, alg, cbitKeyX, pbKeyX, perr)) {
 				break;
+			}
 		}
 		CHECK_CONDITION(pRecip2 != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
 	}
@@ -464,9 +492,11 @@
 			if (pbKeyX != NULL) {
 				int x = cbitKeyOut / 8;
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, pbKeyX, cbitKeyX,
-						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr))
+						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				CHECK_CONDITION(
 					pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
 				int x = cbitKeyOut / 8;
@@ -476,8 +506,9 @@
 
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, cn->v.bytes,
 						cn->length * 8, cnBody->v.bytes, cnBody->length,
-						pbKeyOut, &x, perr))
+						pbKeyOut, &x, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -487,9 +518,11 @@
 			if (pbKeyX != NULL) {
 				int x = cbitKeyOut / 8;
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, pbKeyX, cbitKeyX,
-						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr))
+						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				CHECK_CONDITION(
 					pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
 				int x = cbitKeyOut / 8;
@@ -499,8 +532,9 @@
 
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, cn->v.bytes,
 						cn->length * 8, cnBody->v.bytes, cnBody->length,
-						pbKeyOut, &x, perr))
+						pbKeyOut, &x, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -510,9 +544,11 @@
 			if (pbKeyX != NULL) {
 				int x = cbitKeyOut / 8;
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, pbKeyX, cbitKeyX,
-						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr))
+						cnBody->v.bytes, cnBody->length, pbKeyOut, &x, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				CHECK_CONDITION(
 					pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
 				int x = cbitKeyOut / 8;
@@ -522,8 +558,9 @@
 
 				if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, cn->v.bytes,
 						cn->length * 8, cnBody->v.bytes, cnBody->length,
-						pbKeyOut, &x, perr))
+						pbKeyOut, &x, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -532,8 +569,9 @@
 		case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
 			if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -541,8 +579,9 @@
 		case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
 			if (!HKDF_X(&pcose->m_message, true, false, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 512,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -550,8 +589,9 @@
 		case COSE_Algorithm_Direct_HKDF_AES_128:
 			if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 128,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -559,8 +599,9 @@
 		case COSE_Algorithm_Direct_HKDF_AES_256:
 			if (!HKDF_X(&pcose->m_message, false, false, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -568,8 +609,9 @@
 		case COSE_Algorithm_ECDH_ES_HKDF_256:
 			if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -577,8 +619,9 @@
 		case COSE_Algorithm_ECDH_ES_HKDF_512:
 			if (!HKDF_X(&pcose->m_message, true, true, false, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 512,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -586,8 +629,9 @@
 		case COSE_Algorithm_ECDH_SS_HKDF_256:
 			if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -595,8 +639,9 @@
 		case COSE_Algorithm_ECDH_SS_HKDF_512:
 			if (!HKDF_X(&pcose->m_message, true, true, true, false, algIn,
 					pRecip->m_pkey, NULL, pbKeyOut, cbitKeyOut, 512,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -604,12 +649,14 @@
 		case COSE_Algorithm_ECDH_ES_A128KW:
 			if (!HKDF_X(&pcose->m_message, true, true, false, false,
 					COSE_Algorithm_AES_KW_128, pRecip->m_pkey, NULL, rgbKey,
-					128, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -618,12 +665,14 @@
 		case COSE_Algorithm_ECDH_ES_A192KW:
 			if (!HKDF_X(&pcose->m_message, true, true, false, false,
 					COSE_Algorithm_AES_KW_192, pRecip->m_pkey, NULL, rgbKey,
-					192, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -632,12 +681,14 @@
 		case COSE_Algorithm_ECDH_ES_A256KW:
 			if (!HKDF_X(&pcose->m_message, true, true, false, false,
 					COSE_Algorithm_AES_KW_256, pRecip->m_pkey, NULL, rgbKey,
-					256, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -646,12 +697,14 @@
 		case COSE_Algorithm_ECDH_SS_A128KW:
 			if (!HKDF_X(&pcose->m_message, true, true, true, false,
 					COSE_Algorithm_AES_KW_128, pRecip->m_pkey, NULL, rgbKey,
-					128, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 128,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -660,12 +713,14 @@
 		case COSE_Algorithm_ECDH_SS_A192KW:
 			if (!HKDF_X(&pcose->m_message, true, true, true, false,
 					COSE_Algorithm_AES_KW_192, pRecip->m_pkey, NULL, rgbKey,
-					192, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 192,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -674,12 +729,14 @@
 		case COSE_Algorithm_ECDH_SS_A256KW:
 			if (!HKDF_X(&pcose->m_message, true, true, true, false,
 					COSE_Algorithm_AES_KW_256, pRecip->m_pkey, NULL, rgbKey,
-					256, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 
 			if (!AES_KW_Decrypt((COSE_Enveloped *)pcose, rgbKey, 256,
-					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr))
+					cnBody->v.bytes, cnBody->length, pbKeyOut, &cbKey2, perr)) {
 				goto errorReturn;
+			}
 
 			break;
 #endif
@@ -721,8 +778,9 @@
 
 	cn_Alg = _COSE_map_get_int(&pRecipient->m_encrypt.m_message,
 		COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn_Alg == NULL)
+	if (cn_Alg == NULL) {
 		goto errorReturn;
+	}
 
 	CHECK_CONDITION(cn_Alg->type != CN_CBOR_TEXT, COSE_ERR_UNKNOWN_ALGORITHM);
 	CHECK_CONDITION(
@@ -833,10 +891,12 @@
 				t |= 1;
 				pbKey =
 					_COSE_RecipientInfo_generateKey(pri, alg, cbitKey, perr);
-				if (pbKey == NULL)
+				if (pbKey == NULL) {
 					goto errorReturn;
+				}
 				cbKey = cbitKey / 8;
-			} else {
+			}
+			else {
 				t |= 2;
 			}
 		}
@@ -858,14 +918,16 @@
 
 	const cn_cbor *cbProtected =
 		_COSE_encode_protected(&pRecipient->m_encrypt.m_message, perr);
-	if (cbProtected == NULL)
+	if (cbProtected == NULL) {
 		goto errorReturn;
+	}
 
 	//  Build authenticated data
 	size_t cbAuthData = 0;
 	if (!_COSE_Encrypt_Build_AAD(&pRecipient->m_encrypt.m_message, &pbAuthData,
-			&cbAuthData, "Recipient", perr))
+			&cbAuthData, "Recipient", perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 		case COSE_Algorithm_Direct:
@@ -910,12 +972,15 @@
 				cn_cbor *pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
 				CHECK_CONDITION(pK != NULL, COSE_ERR_INVALID_PARAMETER);
 				if (!AES_KW_Encrypt(pRecipient, pK->v.bytes,
-						(int)pK->length * 8, pbContent, (int)cbContent, perr))
+						(int)pK->length * 8, pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				if (!AES_KW_Encrypt(pRecipient, pbKey, (int)cbKey * 8,
-						pbContent, (int)cbContent, perr))
+						pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -926,12 +991,15 @@
 				cn_cbor *pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
 				CHECK_CONDITION(pK != NULL, COSE_ERR_INVALID_PARAMETER);
 				if (!AES_KW_Encrypt(pRecipient, pK->v.bytes,
-						(int)pK->length * 8, pbContent, (int)cbContent, perr))
+						(int)pK->length * 8, pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				if (!AES_KW_Encrypt(pRecipient, pbKey, (int)cbKey * 8,
-						pbContent, (int)cbContent, perr))
+						pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -942,12 +1010,15 @@
 				cn_cbor *pK = cn_cbor_mapget_int(pRecipient->m_pkey, -1);
 				CHECK_CONDITION(pK != NULL, COSE_ERR_INVALID_PARAMETER);
 				if (!AES_KW_Encrypt(pRecipient, pK->v.bytes,
-						(int)pK->length * 8, pbContent, (int)cbContent, perr))
+						(int)pK->length * 8, pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
-			} else {
+				}
+			}
+			else {
 				if (!AES_KW_Encrypt(pRecipient, pbKey, (int)cbKey * 8,
-						pbContent, (int)cbContent, perr))
+						pbContent, (int)cbContent, perr)) {
 					goto errorReturn;
+				}
 			}
 			break;
 #endif
@@ -956,11 +1027,13 @@
 		case COSE_Algorithm_ECDH_ES_A128KW:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false,
 					true, COSE_Algorithm_AES_KW_128, NULL, pRecipient->m_pkey,
-					rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					rgbKey, 128, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -968,11 +1041,13 @@
 		case COSE_Algorithm_ECDH_ES_A192KW:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false,
 					true, COSE_Algorithm_AES_KW_192, NULL, pRecipient->m_pkey,
-					rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					rgbKey, 192, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -980,11 +1055,13 @@
 		case COSE_Algorithm_ECDH_ES_A256KW:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false,
 					true, COSE_Algorithm_AES_KW_256, NULL, pRecipient->m_pkey,
-					rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					rgbKey, 256, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -993,11 +1070,13 @@
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true,
 					true, COSE_Algorithm_AES_KW_128, pRecipient->m_pkeyStatic,
 					pRecipient->m_pkey, rgbKey, 128, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 128, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1006,11 +1085,13 @@
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true,
 					true, COSE_Algorithm_AES_KW_192, pRecipient->m_pkeyStatic,
 					pRecipient->m_pkey, rgbKey, 192, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 192, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1019,11 +1100,13 @@
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true,
 					true, COSE_Algorithm_AES_KW_256, pRecipient->m_pkeyStatic,
 					pRecipient->m_pkey, rgbKey, 256, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			if (!AES_KW_Encrypt(
-					pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr))
+					pRecipient, rgbKey, 256, pbContent, (int)cbContent, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1033,8 +1116,9 @@
 
 	for (pri = pRecipient->m_encrypt.m_recipientFirst; pri != NULL;
 		 pri = pri->m_recipientNext) {
-		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr))
+		if (!_COSE_Recipient_encrypt(pri, pbKey, cbKey, perr)) {
 			goto errorReturn;
+		}
 	}
 
 	//  Figure out the clean up
@@ -1047,14 +1131,18 @@
 		memset(pbKey, 0, cbKey);
 		COSE_FREE(pbKey, context);
 	}
-	if (pbSecret != NULL)
+	if (pbSecret != NULL) {
 		COSE_FREE(pbSecret, context);
-	if (pbContext != NULL)
+	}
+	if (pbContext != NULL) {
 		COSE_FREE(pbContext, context);
-	if (pbAuthData != NULL)
+	}
+	if (pbAuthData != NULL) {
 		COSE_FREE(pbAuthData, context);
-	if (ptmp != NULL)
+	}
+	if (ptmp != NULL) {
 		cn_cbor_free(ptmp CBOR_CONTEXT_PARAM);
+	}
 	return fRet;
 }
 
@@ -1101,8 +1189,9 @@
 		case COSE_Algorithm_Direct_HKDF_HMAC_SHA_256:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false,
 					true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1110,8 +1199,9 @@
 		case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, false, false,
 					true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 512,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1119,8 +1209,9 @@
 		case COSE_Algorithm_Direct_HKDF_AES_128:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false,
 					true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 128,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1128,8 +1219,9 @@
 		case COSE_Algorithm_Direct_HKDF_AES_256:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, false, false, false,
 					true, algIn, pRecipient->m_pkey, NULL, pb, cbitKeySize, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1137,8 +1229,9 @@
 		case COSE_Algorithm_ECDH_ES_HKDF_256:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false,
 					true, algIn, NULL, pRecipient->m_pkey, pb, cbitKeySize, 256,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1146,8 +1239,9 @@
 		case COSE_Algorithm_ECDH_ES_HKDF_512:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, false,
 					true, algIn, NULL, pRecipient->m_pkey, pb, cbitKeySize, 512,
-					CBOR_CONTEXT_PARAM_COMMA perr))
+					CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1155,8 +1249,9 @@
 		case COSE_Algorithm_ECDH_SS_HKDF_256:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true,
 					true, algIn, pRecipient->m_pkeyStatic, pRecipient->m_pkey,
-					pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr))
+					pb, cbitKeySize, 256, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1164,8 +1259,9 @@
 		case COSE_Algorithm_ECDH_SS_HKDF_512:
 			if (!HKDF_X(&pRecipient->m_encrypt.m_message, true, true, true,
 					true, algIn, pRecipient->m_pkeyStatic, pRecipient->m_pkey,
-					pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr))
+					pb, cbitKeySize, 512, CBOR_CONTEXT_PARAM_COMMA perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -1173,20 +1269,25 @@
 			FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
 	}
 
-	if (pbSecret != NULL)
+	if (pbSecret != NULL) {
 		COSE_FREE(pbSecret, context);
-	if (pbContext != NULL)
+	}
+	if (pbContext != NULL) {
 		COSE_FREE(pbContext, context);
+	}
 	return pb;
 
 errorReturn:
 
-	if (pbSecret != NULL)
+	if (pbSecret != NULL) {
 		COSE_FREE(pbSecret, context);
-	if (pbContext != NULL)
+	}
+	if (pbContext != NULL) {
 		COSE_FREE(pbContext, context);
-	if (pb != NULL)
+	}
+	if (pb != NULL) {
 		COSE_FREE(pb, context);
+	}
 	return NULL;
 }
 #endif
@@ -1225,13 +1326,15 @@
 		CHECK_CONDITION(cnAlg->type == CN_CBOR_INT &&
 							cnAlg->v.sint == COSE_Algorithm_Direct,
 			COSE_ERR_INVALID_PARAMETER);
-	} else {
+	}
+	else {
 		cn_Temp = cn_cbor_int_create(
 			COSE_Algorithm_Direct, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 		CHECK_CONDITION_CBOR(cn_Temp != NULL, cbor_error);
 		if (!COSE_Recipient_map_put_int(hRecipient, COSE_Header_Algorithm,
-				cn_Temp, COSE_UNPROTECT_ONLY, perr))
+				cn_Temp, COSE_UNPROTECT_ONLY, perr)) {
 			goto errorReturn;
+		}
 		cn_Temp = NULL;
 	}
 
@@ -1245,9 +1348,10 @@
 		CHECK_CONDITION_CBOR(cnTemp != NULL, cbor_error);
 		pbTemp = NULL;
 
-		if (!COSE_Recipient_map_put_int(
-				hRecipient, COSE_Header_KID, cnTemp, COSE_UNPROTECT_ONLY, perr))
+		if (!COSE_Recipient_map_put_int(hRecipient, COSE_Header_KID, cnTemp,
+				COSE_UNPROTECT_ONLY, perr)) {
 			goto errorReturn;
+		}
 	}
 
 	pbKey = (byte *)COSE_CALLOC(cbKey, 1, context);
@@ -1274,21 +1378,26 @@
 		cbor_error);
 	cnTemp = NULL;
 
-	if (!COSE_Recipient_SetKey(hRecipient, cn_Temp, perr))
+	if (!COSE_Recipient_SetKey(hRecipient, cn_Temp, perr)) {
 		goto errorReturn;
+	}
 	cn_Temp = NULL;
 
 	return true;
 
 errorReturn:
-	if (cn_Temp != NULL)
+	if (cn_Temp != NULL) {
 		CN_CBOR_FREE(cn_Temp, context);
-	if (cnTemp != NULL)
+	}
+	if (cnTemp != NULL) {
 		CN_CBOR_FREE(cnTemp, context);
-	if (pbTemp != NULL)
+	}
+	if (pbTemp != NULL) {
 		COSE_FREE(pbTemp, context);
-	if (pbKey != NULL)
+	}
+	if (pbKey != NULL) {
 		COSE_FREE(pbKey, context);
+	}
 	return false;
 }
 
@@ -1413,10 +1522,12 @@
 
 	f = true;
 errorReturn:
-	if (cn2 != NULL)
+	if (cn2 != NULL) {
 		CN_CBOR_FREE(cn2, context);
-	if (cn3 != NULL)
+	}
+	if (cn3 != NULL) {
 		CN_CBOR_FREE(cn3, context);
+	}
 	return f;
 }
 
@@ -1442,8 +1553,9 @@
 	cose_errback *perr)
 {
 	if (!IsValidRecipientHandle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return false;
 	}
 
@@ -1462,8 +1574,9 @@
 	CHECK_CONDITION(value != NULL, COSE_ERR_INVALID_PARAMETER);
 
 	if (!_COSE_map_put(&((COSE_RecipientInfo *)h)->m_encrypt.m_message, key,
-			value, flags, perr))
+			value, flags, perr)) {
 		return false;
+	}
 
 	if (key == COSE_Header_Algorithm) {
 		if (value->type == CN_CBOR_INT) {
@@ -1501,7 +1614,8 @@
 						~1;
 					break;
 			}
-		} else {
+		}
+		else {
 			((COSE_RecipientInfo *)h)->m_encrypt.m_message.m_flags &= ~1;
 		}
 	}
@@ -1544,8 +1658,10 @@
 	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_U_name, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1556,8 +1672,10 @@
 		_COSE_map_get_int(pcose, COSE_Header_KDF_U_nonce, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1568,8 +1686,10 @@
 		_COSE_map_get_int(pcose, COSE_Header_KDF_U_other, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1586,8 +1706,10 @@
 	cnParam = _COSE_map_get_int(pcose, COSE_Header_KDF_V_name, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1598,8 +1720,10 @@
 		_COSE_map_get_int(pcose, COSE_Header_KDF_V_nonce, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1610,8 +1734,10 @@
 		_COSE_map_get_int(pcose, COSE_Header_KDF_V_other, COSE_BOTH, perr);
 	if (cnParam != NULL) {
 		cnT = cn_cbor_clone(cnParam, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	} else
+	}
+	else {
 		cnT = cn_cbor_null_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cnT != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(cnArrayT, cnT, &cbor_error), cbor_error);
@@ -1680,14 +1806,18 @@
 	fReturn = true;
 
 returnHere:
-	if (pbContext != NULL)
+	if (pbContext != NULL) {
 		COSE_FREE(pbContext, context);
-	if (pArray != NULL)
+	}
+	if (pArray != NULL) {
 		CN_CBOR_FREE(pArray, context);
-	if (cnArrayT != NULL)
+	}
+	if (cnArrayT != NULL) {
 		CN_CBOR_FREE(cnArrayT, context);
-	if (cnT != NULL)
+	}
+	if (cnT != NULL) {
 		CN_CBOR_FREE(cnT, context);
+	}
 	return fReturn;
 
 errorReturn:
@@ -1715,8 +1845,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidRecipientHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
@@ -1739,8 +1870,9 @@
 		CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
 		p = p->m_recipientNext;
 	}
-	if (p != NULL)
+	if (p != NULL) {
 		p->m_encrypt.m_message.m_refCount++;
+	}
 
 errorReturn:
 	return (HCOSE_RECIPIENT)p;
@@ -1780,8 +1912,9 @@
 		if (!_COSE_array_replace(&pEncrypt->m_message, pRecipients,
 				INDEX_RECIPIENTS, CBOR_CONTEXT_PARAM_COMMA & cbor_error)) {
 			CN_CBOR_FREE(pRecipients, context);
-			if (perr != NULL)
+			if (perr != NULL) {
 				perr->err = _MapFromCBOR(cbor_error);
+			}
 			goto errorReturn;
 		}
 	}
diff --git a/src/Sign.c b/src/Sign.c
index f4d3c23..0bfe185 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -11,7 +11,7 @@
 
 #if INCLUDE_SIGN
 
-static COSE *SignRoot = NULL;
+COSE *SignRoot = NULL;
 
 /*! \private
  * @brief Test if a HCOSE_SIGN handle is valid
@@ -27,12 +27,13 @@
  *  @returns result of check
  */
 
-static bool IsValidSignHandle(HCOSE_SIGN h)
+bool IsValidSignHandle(HCOSE_SIGN h)
 {
 	COSE_SignMessage *p = (COSE_SignMessage *)h;
 
-	if (p == NULL)
+	if (p == NULL) {
 		return false;
+	}
 	return _COSE_IsInList(SignRoot, (COSE *)p);
 }
 
@@ -74,12 +75,14 @@
 	cn_cbor *pSigners = NULL;
 	// cn_cbor * tmp;
 	cose_errback error = {0};
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj = (COSE_SignMessage *)COSE_CALLOC(
 			1, sizeof(COSE_SignMessage), context);
+	}
 	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
 
 	if (!_COSE_Init_From_Object(
@@ -98,24 +101,27 @@
 	do {
 		COSE_SignerInfo *pInfo = _COSE_SignerInfo_Init_From_Object(
 			pSigners, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
-		if (pInfo == NULL)
+		if (pInfo == NULL) {
 			goto errorReturn;
+		}
 
 		pInfo->m_signerNext = pobj->m_signerFirst;
 		pobj->m_signerFirst = pInfo;
 		pSigners = pSigners->next;
 	} while (pSigners != NULL);
 
-	if (pIn == NULL)
+	if (pIn == NULL) {
 		_COSE_InsertInList(&SignRoot, &pobj->m_message);
+	}
 
 	return (HCOSE_SIGN)pobj;
 
 errorReturn:
 	if (pobj != NULL) {
 		_COSE_Sign_Release(pobj);
-		if (pIn == NULL)
+		if (pIn == NULL) {
 			COSE_FREE(pobj, context);
+		}
 	}
 	return NULL;
 }
@@ -127,8 +133,9 @@
 #endif
 	COSE_SignMessage *pMessage = (COSE_SignMessage *)h;
 
-	if (!IsValidSignHandle(h))
+	if (!IsValidSignHandle(h)) {
 		return false;
+	}
 
 	//  Check reference counting
 	if (pMessage->m_message.m_refCount > 1) {
@@ -156,7 +163,7 @@
 
 	for (pSigner = p->m_signerFirst; pSigner != NULL; pSigner = pSigner2) {
 		pSigner2 = pSigner->m_signerNext;
-		_COSE_SignerInfo_Free(pSigner);
+		COSE_Signer_Free((HCOSE_SIGNER)pSigner);
 	}
 
 	_COSE_Release(&p->m_message);
@@ -191,8 +198,9 @@
 
 	f = true;
 errorReturn:
-	if (p != NULL)
+	if (p != NULL) {
 		CN_CBOR_FREE(p, context);
+	}
 
 	return f;
 }
@@ -219,14 +227,16 @@
 #endif
 
 	hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA perr);
-	if (hSigner == NULL)
+	if (hSigner == NULL) {
 		goto errorReturn;
+	}
 
 	cbor2 = cn_cbor_int_create(algId, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 	CHECK_CONDITION_CBOR(cbor2 != NULL, cbor_error);
 	if (!COSE_Signer_map_put_int(
-			hSigner, COSE_Header_Algorithm, cbor2, COSE_PROTECT_ONLY, perr))
+			hSigner, COSE_Header_Algorithm, cbor2, COSE_PROTECT_ONLY, perr)) {
 		goto errorReturn;
+	}
 	cbor2 = NULL;
 
 	cbor = cn_cbor_mapget_int(pkey, COSE_Key_ID);
@@ -237,31 +247,36 @@
 			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 		CHECK_CONDITION_CBOR(cbor2 != NULL, cbor_error);
 		if (!COSE_Signer_map_put_int(
-				hSigner, COSE_Header_KID, cbor2, COSE_UNPROTECT_ONLY, perr))
+				hSigner, COSE_Header_KID, cbor2, COSE_UNPROTECT_ONLY, perr)) {
 			goto errorReturn;
+		}
 		cbor2 = NULL;
 	}
 
-	if (!COSE_Signer_SetKey(hSigner, pkey, perr))
+	if (!COSE_Signer_SetKey(hSigner, pkey, perr)) {
 		goto errorReturn;
+	}
 
-	if (!COSE_Sign_AddSigner(hSign, hSigner, perr))
+	if (!COSE_Sign_AddSigner(hSign, hSigner, perr)) {
 		goto errorReturn;
+	}
 
 	return hSigner;
 
 errorReturn:
-	if (cbor2 != NULL)
+	if (cbor2 != NULL) {
 		CN_CBOR_FREE((void *)cbor2, context);
-	if (hSigner != NULL)
+	}
+	if (hSigner != NULL) {
 		COSE_Signer_Free(hSigner);
+	}
 	return NULL;
 }
 
 bool COSE_Sign_Sign(HCOSE_SIGN h, cose_errback *perr)
 {
 #ifdef USE_CBOR_CONTEXT
-	// cn_cbor_context * context = NULL;
+	cn_cbor_context *context = NULL;
 #endif
 	COSE_SignMessage *pMessage = (COSE_SignMessage *)h;
 	COSE_SignerInfo *pSigner;
@@ -274,7 +289,7 @@
 		return false;
 	}
 #ifdef USE_CBOR_CONTEXT
-	//	context = &pMessage->m_message.m_allocContext;
+	context = &pMessage->m_message.m_allocContext;
 #endif
 
 	pcborBody = _COSE_arrayget_int(&pMessage->m_message, INDEX_BODY);
@@ -282,15 +297,27 @@
 		COSE_ERR_INVALID_PARAMETER);
 
 	pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
-	if (pcborProtected == NULL)
+	if (pcborProtected == NULL) {
 		goto errorReturn;
+	}
 
 	for (pSigner = pMessage->m_signerFirst; pSigner != NULL;
 		 pSigner = pSigner->m_signerNext) {
-		if (!_COSE_Signer_sign(pSigner, pcborBody, pcborProtected, perr))
+		if (!_COSE_Signer_sign(
+				pSigner, pcborBody, pcborProtected, "Signature", perr)) {
 			goto errorReturn;
+		}
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	if (pMessage->m_message.m_counterSigners != NULL) {
+		if (!_COSE_CounterSign_Sign(
+				&pMessage->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
+			goto errorReturn;
+		}
+	}
+#endif
+
 	return true;
 }
 
@@ -318,7 +345,8 @@
 	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
 		COSE_ERR_INVALID_PARAMETER);
 
-	f = _COSE_Signer_validate(pSign, pSigner, cnContent, cnProtected, perr);
+	f = _COSE_Signer_validate(
+		pSigner, cnContent, cnProtected, "Signature", perr);
 
 	return f;
 
@@ -373,8 +401,9 @@
 	return true;
 
 errorReturn:
-	if (pSignersT == NULL)
+	if (pSignersT == NULL) {
 		CN_CBOR_FREE(pSignersT, context);
+	}
 	return false;
 }
 
@@ -384,8 +413,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidSignHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
@@ -400,8 +430,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidSignHandle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return false;
 	}
 
@@ -417,16 +448,18 @@
 	COSE_SignerInfo *p;
 
 	if (!IsValidSignHandle(cose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
 	p = ((COSE_SignMessage *)cose)->m_signerFirst;
 	for (i = 0; i < iSigner; i++) {
 		if (p == NULL) {
-			if (perr != NULL)
+			if (perr != NULL) {
 				perr->err = COSE_ERR_INVALID_PARAMETER;
+			}
 			return NULL;
 		}
 		p = p->m_signerNext;
diff --git a/src/Sign1.c b/src/Sign1.c
index cfc6c12..d9e0568 100644
--- a/src/Sign1.c
+++ b/src/Sign1.c
@@ -20,7 +20,7 @@
 	cose_errback *perr);
 void _COSE_Sign1_Release(COSE_Sign1Message *p);
 
-static COSE *Sign1Root = NULL;
+COSE *Sign1Root = NULL;
 
 /*! \private
  * @brief Test if a HCOSE_SIGN1 handle is valid
@@ -40,8 +40,9 @@
 {
 	COSE_Sign1Message *p = (COSE_Sign1Message *)h;
 
-	if (p == NULL)
+	if (p == NULL) {
 		return false;
+	}
 	return _COSE_IsInList(Sign1Root, (COSE *)p);
 }
 
@@ -52,8 +53,9 @@
 	COSE_Sign1Message *pobj =
 		(COSE_Sign1Message *)COSE_CALLOC(1, sizeof(COSE_Sign1Message), context);
 	if (pobj == NULL) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_OUT_OF_MEMORY;
+		}
 		return NULL;
 	}
 
@@ -79,12 +81,14 @@
 	COSE_Sign1Message *pobj = pIn;
 	cose_errback error = {0};
 
-	if (perr == NULL)
+	if (perr == NULL) {
 		perr = &error;
+	}
 
-	if (pobj == NULL)
+	if (pobj == NULL) {
 		pobj = (COSE_Sign1Message *)COSE_CALLOC(
 			1, sizeof(COSE_Sign1Message), context);
+	}
 	CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
 
 	if (!_COSE_Init_From_Object(
@@ -92,16 +96,18 @@
 		goto errorReturn;
 	}
 
-	if (pIn == NULL)
+	if (pIn == NULL) {
 		_COSE_InsertInList(&Sign1Root, &pobj->m_message);
+	}
 
 	return (HCOSE_SIGN1)pobj;
 
 errorReturn:
 	if (pobj != NULL) {
 		_COSE_Sign1_Release(pobj);
-		if (pIn == NULL)
+		if (pIn == NULL) {
 			COSE_FREE(pobj, context);
+		}
 	}
 	return NULL;
 }
@@ -113,8 +119,9 @@
 #endif
 	COSE_Sign1Message *pMessage = (COSE_Sign1Message *)h;
 
-	if (!IsValidSign1Handle(h))
+	if (!IsValidSign1Handle(h)) {
 		return false;
+	}
 
 	//  Check reference counting
 	if (pMessage->m_message.m_refCount > 1) {
@@ -170,8 +177,9 @@
 	fRet = true;
 
 errorReturn:
-	if (p != NULL)
+	if (p != NULL) {
 		CN_CBOR_FREE(p, context);
+	}
 	return fRet;
 }
 
@@ -197,8 +205,9 @@
 	cose_errback *perr)
 {
 	if (!IsValidSign1Handle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return false;
 	}
 
@@ -209,7 +218,7 @@
 bool COSE_Sign1_Sign(HCOSE_SIGN1 h, const cn_cbor *pKey, cose_errback *perr)
 {
 #ifdef USE_CBOR_CONTEXT
-	// cn_cbor_context * context = NULL;
+	cn_cbor_context *context = NULL;
 #endif
 	COSE_Sign1Message *pMessage = (COSE_Sign1Message *)h;
 	const cn_cbor *pcborProtected;
@@ -220,15 +229,26 @@
 		return false;
 	}
 #ifdef USE_CBOR_CONTEXT
-	//	context = &pMessage->m_message.m_allocContext;
+	context = &pMessage->m_message.m_allocContext;
 #endif
 
 	pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
-	if (pcborProtected == NULL)
+	if (pcborProtected == NULL) {
 		goto errorReturn;
+	}
 
-	if (!_COSE_Signer0_sign(pMessage, pKey, perr))
+	if (!_COSE_Signer0_sign(pMessage, pKey, perr)) {
 		goto errorReturn;
+	}
+
+#if INCLUDE_COUNTERSIGNATURE
+	if (pMessage->m_message.m_counterSigners != NULL) {
+		if (!_COSE_CounterSign_Sign(
+				&pMessage->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
+			goto errorReturn;
+		}
+	}
+#endif
 
 	return true;
 }
@@ -268,8 +288,9 @@
 	cose_errback *perror)
 {
 	if (!IsValidSign1Handle(h)) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
@@ -322,12 +343,14 @@
 	cn2 = _COSE_arrayget_int(&pMessage->m_message, INDEX_PROTECTED);
 	CHECK_CONDITION(cn2 != NULL, COSE_ERR_INVALID_PARAMETER);
 
-	if ((cn2->length == 1) && (cn2->v.bytes[0] == 0xa0))
+	if ((cn2->length == 1) && (cn2->v.bytes[0] == 0xa0)) {
 		cn =
 			cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	else
+	}
+	else {
 		cn = cn_cbor_data_create(cn2->v.bytes, (int)cn2->length,
 			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
@@ -361,19 +384,24 @@
 	*pcbToSign = cbToSign;
 	pbToSign = NULL;
 
-	if (cn != NULL)
+	if (cn != NULL) {
 		CN_CBOR_FREE(cn, context);
-	if (pArray != NULL)
+	}
+	if (pArray != NULL) {
 		COSE_FREE(pArray, context);
+	}
 	return true;
 
 errorReturn:
-	if (pbToSign != NULL)
+	if (pbToSign != NULL) {
 		COSE_FREE(pbToSign, context);
-	if (cn != NULL)
+	}
+	if (cn != NULL) {
 		CN_CBOR_FREE(cn, context);
-	if (pArray != NULL)
+	}
+	if (pArray != NULL) {
 		COSE_FREE(pArray, context);
+	}
 	return false;
 }
 
@@ -395,36 +423,44 @@
 
 	pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
 	if (pArray == NULL) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_OUT_OF_MEMORY;
+		}
 	errorReturn:
-		if (pcborBody2 != NULL)
+		if (pcborBody2 != NULL) {
 			CN_CBOR_FREE(pcborBody2, context);
-		if (pcborProtected2 != NULL)
+		}
+		if (pcborProtected2 != NULL) {
 			CN_CBOR_FREE(pcborProtected2, context);
-		if (pArray != NULL)
+		}
+		if (pArray != NULL) {
 			COSE_FREE(pArray, context);
-		if (pbToSign != NULL)
+		}
+		if (pbToSign != NULL) {
 			COSE_FREE(pbToSign, context);
+		}
 		return false;
 	}
 
 	cn = _COSE_map_get_int(
 		&pSigner->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn == NULL)
+	if (cn == NULL) {
 		goto errorReturn;
+	}
 
 	if (cn->type == CN_CBOR_TEXT) {
 		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
-	} else {
+	}
+	else {
 		CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT),
 			COSE_ERR_INVALID_PARAMETER);
 
 		alg = (int)cn->v.uint;
 	}
 
-	if (!CreateSign1AAD(pSigner, &pbToSign, &cbToSign, "Signature1", perr))
+	if (!CreateSign1AAD(pSigner, &pbToSign, &cbToSign, "Signature1", perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_ECDSA_SHA_256
@@ -484,12 +520,14 @@
 
 	cn = _COSE_map_get_int(
 		&pSign->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn == NULL)
+	if (cn == NULL) {
 		goto errorReturn;
+	}
 
 	if (cn->type == CN_CBOR_TEXT) {
 		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
-	} else {
+	}
+	else {
 		CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT),
 			COSE_ERR_INVALID_PARAMETER);
 
@@ -498,39 +536,44 @@
 
 	//  Build protected headers
 
-	if (!CreateSign1AAD(pSign, &pbToSign, &cbToSign, "Signature1", perr))
+	if (!CreateSign1AAD(pSign, &pbToSign, &cbToSign, "Signature1", perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_ECDSA_SHA_256
 		case COSE_Algorithm_ECDSA_SHA_256:
 			if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE + 1, pKey, 256,
-					pbToSign, cbToSign, perr))
+					pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_384
 		case COSE_Algorithm_ECDSA_SHA_384:
 			if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE + 1, pKey, 384,
-					pbToSign, cbToSign, perr))
+					pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_512
 		case COSE_Algorithm_ECDSA_SHA_512:
 			if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE + 1, pKey, 512,
-					pbToSign, cbToSign, perr))
+					pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_EDDSA
 		case COSE_Algorithm_EdDSA:
 			if (!EdDSA_Verify(&pSign->m_message, INDEX_SIGNATURE + 1, pKey,
-					pbToSign, cbToSign, perr))
+					pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -542,8 +585,9 @@
 	fRet = true;
 
 errorReturn:
-	if (pbToSign != NULL)
+	if (pbToSign != NULL) {
 		COSE_FREE(pbToSign, context);
+	}
 
 	return fRet;
 }
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index 824c796..8d117c5 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -13,17 +13,19 @@
 #include "cose/cose_configure.h"
 #include "crypto.h"
 
-#if INCLUDE_SIGN
+#if INCLUDE_SIGN || INCLUDE_COUNTERSIGNATURE
 
-static COSE *SignerRoot = NULL;
+#if INCLUDE_SIGN
+COSE *SignerRoot = NULL;
 
 bool IsValidSignerHandle(HCOSE_SIGNER h)
 {
 	COSE_SignerInfo *p = (COSE_SignerInfo *)h;
 	return _COSE_IsInList(SignerRoot, (COSE *)p);
 }
+#endif
 
-bool _COSE_SignerInfo_Free(COSE_SignerInfo *pSigner)
+bool _COSE_SignerInfo_Release(COSE_SignerInfo *pSigner)
 {
 	//  Check ref counting
 	if (pSigner->m_message.m_refCount > 1) {
@@ -36,20 +38,22 @@
 	return true;
 }
 
+#if INCLUDE_SIGN
 bool COSE_Signer_Free(HCOSE_SIGNER hSigner)
 {
 	COSE_SignerInfo *pSigner = (COSE_SignerInfo *)hSigner;
 	bool fRet = false;
 
-	if (!IsValidSignerHandle(hSigner))
+	if (!IsValidSignerHandle(hSigner)) {
 		goto errorReturn;
+	}
 
 	if (pSigner->m_message.m_refCount > 1) {
 		pSigner->m_message.m_refCount--;
 		return true;
 	}
 
-	_COSE_SignerInfo_Free(pSigner);
+	_COSE_SignerInfo_Release(pSigner);
 
 	_COSE_RemoveFromList(&SignerRoot, &pSigner->m_message);
 
@@ -65,14 +69,15 @@
 	COSE_SignerInfo *pobj =
 		(COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
 	if (pobj == NULL) {
-		if (perror != NULL)
+		if (perror != NULL) {
 			perror->err = COSE_ERR_OUT_OF_MEMORY;
+		}
 		return NULL;
 	}
 
 	if (!_COSE_SignerInfo_Init(COSE_INIT_FLAGS_NO_CBOR_TAG, pobj,
 			COSE_recipient_object, CBOR_CONTEXT_PARAM_COMMA perror)) {
-		_COSE_SignerInfo_Free(pobj);
+		_COSE_SignerInfo_Release(pobj);
 		COSE_FREE(pobj, context);
 		return NULL;
 	}
@@ -80,6 +85,7 @@
 	_COSE_InsertInList(&SignerRoot, &pobj->m_message);
 	return (HCOSE_SIGNER)pobj;
 }
+#endif
 
 bool _COSE_SignerInfo_Init(COSE_INIT_FLAGS flags,
 	COSE_SignerInfo *pobj,
@@ -105,17 +111,23 @@
 	CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
 
 	if (!_COSE_Init_From_Object(
-			&pSigner->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr))
+			&pSigner->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
-	_COSE_InsertInList(&SignerRoot, &pSigner->m_message);
+#if INCLUDE_SIGN
+	if (pIn == NULL) {
+		_COSE_InsertInList(&SignerRoot, &pSigner->m_message);
+	}
+#endif
 	return pSigner;
 
 errorReturn:
 	if (pSigner != NULL) {
-		_COSE_SignerInfo_Free(pSigner);
-		if (pIn == NULL)
+		_COSE_SignerInfo_Release(pSigner);
+		if (pIn == NULL) {
 			COSE_FREE(pSigner, context);
+		}
 	}
 	return NULL;
 }
@@ -127,6 +139,7 @@
 	const cn_cbor *pcborProtectedSign,
 	const byte *pbExternal,
 	size_t cbExternal,
+	const char *const contextString,
 	CBOR_CONTEXT_COMMA cose_errback *perr)
 {
 	cn_cbor *pArray = NULL;
@@ -140,31 +153,35 @@
 	CHECK_CONDITION_CBOR(pArray != NULL, cbor_error);
 
 	cn = cn_cbor_string_create(
-		"Signature", CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+		contextString, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 	CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
 	cn = NULL;
 
-	if (pcborProtected->length == 1 && (pcborProtected->v.bytes[0] == 0xa0))
+	if (pcborProtected->length == 1 && (pcborProtected->v.bytes[0] == 0xa0)) {
 		cn =
 			cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	else
+	}
+	else {
 		cn = cn_cbor_data_create(pcborProtected->v.bytes,
 			(int)pcborProtected->length, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
 	cn = NULL;
 
 	if ((pcborProtectedSign->length == 1) &&
-		(pcborProtectedSign->v.bytes[0] == 0xa0))
+		(pcborProtectedSign->v.bytes[0] == 0xa0)) {
 		cn =
 			cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
-	else
+	}
+	else {
 		cn = cn_cbor_data_create(pcborProtectedSign->v.bytes,
 			(int)pcborProtectedSign->length,
 			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
+	}
 	CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
 	CHECK_CONDITION_CBOR(
 		cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
@@ -199,18 +216,22 @@
 	f = true;
 
 errorReturn:
-	if (cn != NULL)
+	if (cn != NULL) {
 		CN_CBOR_FREE(cn, context);
-	if (pArray != NULL)
+	}
+	if (pArray != NULL) {
 		CN_CBOR_FREE(pArray, context);
-	if (pbToSign != NULL)
+	}
+	if (pbToSign != NULL) {
 		COSE_FREE(pbToSign, context);
+	}
 	return f;
 }
 
 bool _COSE_Signer_sign(COSE_SignerInfo *pSigner,
 	const cn_cbor *pcborBody,
 	const cn_cbor *pcborProtected,
+	const char *const contextString,
 	cose_errback *perr)
 {
 #ifdef USE_CBOR_CONTEXT
@@ -229,12 +250,14 @@
 
 	cnAlgorithm = _COSE_map_get_int(
 		&pSigner->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cnAlgorithm == NULL)
+	if (cnAlgorithm == NULL) {
 		goto errorReturn;
+	}
 
 	if (cnAlgorithm->type == CN_CBOR_TEXT) {
 		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
-	} else {
+	}
+	else {
 		CHECK_CONDITION((cnAlgorithm->type == CN_CBOR_UINT ||
 							cnAlgorithm->type == CN_CBOR_INT),
 			COSE_ERR_INVALID_PARAMETER);
@@ -243,44 +266,51 @@
 	}
 
 	pcborProtectedSign = _COSE_encode_protected(&pSigner->m_message, perr);
-	if (pcborProtectedSign == NULL)
+	if (pcborProtectedSign == NULL) {
 		goto errorReturn;
+	}
 
 	if (!BuildToBeSigned(&pbToSign, &cbToSign, pcborBody, pcborProtected,
 			pcborProtectedSign, pSigner->m_message.m_pbExternal,
-			pSigner->m_message.m_cbExternal, CBOR_CONTEXT_PARAM_COMMA perr))
+			pSigner->m_message.m_cbExternal, contextString,
+			CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
 	switch (alg) {
 #ifdef USE_ECDSA_SHA_256
 		case COSE_Algorithm_ECDSA_SHA_256:
 			if (!ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 256, pbToSign, cbToSign, perr))
+					pSigner->m_pkey, 256, pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_384
 		case COSE_Algorithm_ECDSA_SHA_384:
 			if (!ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 384, pbToSign, cbToSign, perr))
+					pSigner->m_pkey, 384, pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_512
 		case COSE_Algorithm_ECDSA_SHA_512:
 			if (!ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 512, pbToSign, cbToSign, perr))
+					pSigner->m_pkey, 512, pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_EDDSA
 		case COSE_Algorithm_EdDSA:
 			if (!EdDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, pbToSign, cbToSign, perr))
+					pSigner->m_pkey, pbToSign, cbToSign, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -288,16 +318,28 @@
 			FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	if (pSigner->m_message.m_counterSigners != NULL) {
+		if (!_COSE_CounterSign_Sign(
+				&pSigner->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
+			goto errorReturn;
+		}
+	}
+#endif
+
 	fRet = true;
 
 errorReturn:
-	if (pArray != NULL)
+	if (pArray != NULL) {
 		COSE_FREE(pArray, context);
-	if (pbToSign != NULL)
+	}
+	if (pbToSign != NULL) {
 		COSE_FREE(pbToSign, context);
+	}
 	return fRet;
 }
 
+#if INCLUDE_SIGN
 bool COSE_Signer_SetKey(HCOSE_SIGNER h, const cn_cbor *pKey, cose_errback *perr)
 {
 	COSE_SignerInfo *p;
@@ -336,39 +378,41 @@
 	cose_errback *perr)
 {
 	if (!IsValidSignerHandle(hcose)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return false;
 	}
 
 	return _COSE_SetExternal(&((COSE_SignerInfo *)hcose)->m_message,
 		pbExternalData, cbExternalData, perr);
 }
+#endif
 
-bool _COSE_Signer_validate(COSE_SignMessage *pSign,
-	COSE_SignerInfo *pSigner,
+bool _COSE_Signer_validate(COSE_SignerInfo *pSigner,
 	const cn_cbor *pcborBody,
 	const cn_cbor *pcborProtected,
+	const char *const contextString,
 	cose_errback *perr)
 {
 	byte *pbToBeSigned = NULL;
 	int alg = 0;
 #ifdef USE_CBOR_CONTEXT
-	cn_cbor_context *context = &pSign->m_message.m_allocContext;
-#else
-	UNUSED(pSign);
+	cn_cbor_context *context = &pSigner->m_message.m_allocContext;
 #endif
 	size_t cbToBeSigned;
 	bool fRet = false;
 
 	const cn_cbor *cn = _COSE_map_get_int(
 		&pSigner->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
-	if (cn == NULL)
+	if (cn == NULL) {
 		goto errorReturn;
+	}
 
 	if (cn->type == CN_CBOR_TEXT) {
 		FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
-	} else {
+	}
+	else {
 		CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT),
 			COSE_ERR_INVALID_PARAMETER);
 
@@ -386,8 +430,10 @@
 	//  Build authenticated data
 	if (!BuildToBeSigned(&pbToBeSigned, &cbToBeSigned, pcborBody,
 			pcborProtected, cnProtected, pSigner->m_message.m_pbExternal,
-			pSigner->m_message.m_cbExternal, CBOR_CONTEXT_PARAM_COMMA perr))
+			pSigner->m_message.m_cbExternal, contextString,
+			CBOR_CONTEXT_PARAM_COMMA perr)) {
 		goto errorReturn;
+	}
 
 	cn_cbor *cnSignature =
 		_COSE_arrayget_int(&pSigner->m_message, INDEX_SIGNATURE);
@@ -399,32 +445,36 @@
 #ifdef USE_ECDSA_SHA_256
 		case COSE_Algorithm_ECDSA_SHA_256:
 			if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 256, pbToBeSigned, cbToBeSigned, perr))
+					pSigner->m_pkey, 256, pbToBeSigned, cbToBeSigned, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_384
 		case COSE_Algorithm_ECDSA_SHA_384:
 			if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 384, pbToBeSigned, cbToBeSigned, perr))
+					pSigner->m_pkey, 384, pbToBeSigned, cbToBeSigned, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_ECDSA_SHA_512
 		case COSE_Algorithm_ECDSA_SHA_512:
 			if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, 512, pbToBeSigned, cbToBeSigned, perr))
+					pSigner->m_pkey, 512, pbToBeSigned, cbToBeSigned, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
 #ifdef USE_EDDSA
 		case COSE_Algorithm_EdDSA:
 			if (!EdDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE,
-					pSigner->m_pkey, pbToBeSigned, cbToBeSigned, perr))
+					pSigner->m_pkey, pbToBeSigned, cbToBeSigned, perr)) {
 				goto errorReturn;
+			}
 			break;
 #endif
 
@@ -436,20 +486,23 @@
 	fRet = true;
 
 errorReturn:
-	if (pbToBeSigned != NULL)
+	if (pbToBeSigned != NULL) {
 		COSE_FREE(pbToBeSigned, context);
+	}
 
 	return fRet;
 }
 
+#if INCLUDE_SIGN
 cn_cbor *COSE_Signer_map_get_int(HCOSE_SIGNER h,
 	int key,
 	int flags,
 	cose_errback *perr)
 {
 	if (!IsValidSignerHandle(h)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_HANDLE;
+		}
 		return NULL;
 	}
 
@@ -471,5 +524,5 @@
 errorReturn:
 	return false;
 }
-
+#endif
 #endif
diff --git a/src/cbor.c b/src/cbor.c
index 54511bb..2e34d4c 100644
--- a/src/cbor.c
+++ b/src/cbor.c
@@ -57,8 +57,9 @@
 	cn_cbor *cb_temp2;
 
 	if (!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY) {
-		if (errp != NULL)
+		if (errp != NULL) {
 			errp->err = CN_CBOR_ERR_INVALID_PARAMETER;
+		}
 		return false;
 	}
 
@@ -135,8 +136,9 @@
 	switch (pIn->type) {
 		case CN_CBOR_TEXT:
 			sz = CN_CBOR_CALLOC(pIn->length + 1, 1, context);
-			if (sz == NULL)
+			if (sz == NULL) {
 				return NULL;
+			}
 			memcpy(sz, pIn->v.str, pIn->length);
 			sz[pIn->length] = 0;
 			pOut = cn_cbor_string_create(sz CBOR_CONTEXT_PARAM, pcn_cbor_error);
@@ -149,8 +151,9 @@
 
 		case CN_CBOR_BYTES:
 			pb = CN_CBOR_CALLOC((int)pIn->length, 1, context);
-			if (pb == NULL)
+			if (pb == NULL) {
 				return NULL;
+			}
 			memcpy(pb, pIn->v.bytes, pIn->length);
 			pOut = cn_cbor_data_create(
 				pb, (int)pIn->length CBOR_CONTEXT_PARAM, pcn_cbor_error);
@@ -169,8 +172,9 @@
 {
 	cn_cbor *pcnTag = CN_CALLOC(context);
 	if (pcnTag == NULL) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = CN_CBOR_ERR_OUT_OF_MEMORY;
+		}
 		return NULL;
 	}
 
@@ -187,8 +191,9 @@
 {
 	cn_cbor *pcn = CN_CALLOC(context);
 	if (pcn == NULL) {
-		if (errp != NULL)
+		if (errp != NULL) {
 			errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;
+		}
 		return NULL;
 	}
 
@@ -200,8 +205,9 @@
 {
 	cn_cbor *pcn = CN_CALLOC(context);
 	if (pcn == NULL) {
-		if (errp != NULL)
+		if (errp != NULL) {
 			errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;
+		}
 		return NULL;
 	}
 	pcn->type = CN_CBOR_NULL;
diff --git a/src/cose_int.h b/src/cose_int.h
index 4e3b14a..23f7308 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -8,10 +8,10 @@
 // These definitions are here because they aren't required for the public
 // interface, and they were quite confusing in cn-cbor.h
 
-#ifdef USE_COUNTER_SIGNATURES
-struct _COSE_COUNTER_SIGN;
-typedef struct _COSE_COUNTER_SIGN COSE_CounterSign;
-#endif
+struct CounterSign;
+typedef struct CounterSign COSE_CounterSign;
+struct CounterSign1;
+typedef struct CounterSign1 COSE_CounterSign1;
 
 #define UNUSED(x) ((void)(x))
 
@@ -36,8 +36,12 @@
 	cn_cbor_context m_allocContext;
 #endif
 	struct _COSE *m_handleList;
-#ifdef USE_COUNTER_SIGNATURES
-	COSE_CounterSign *m_counterSigners;
+#if INCLUDE_COUNTERSIGNATURE
+	COSE_CounterSign
+		*m_counterSigners;	// Linked list of all counter signatures
+#endif
+#if INCLUDE_COUNTERSIGNATURE1
+	COSE_CounterSign1 *m_counterSign1;
 #endif
 } COSE;
 
@@ -98,12 +102,10 @@
 #endif
 typedef COSE_MacMessage COSE_Mac0Message;
 
-#ifdef USE_COUNTER_SIGNATURES
-typedef struct _COSE_COUNTER_SIGN {
+struct CounterSign {
 	COSE_SignerInfo m_signer;
 	COSE_CounterSign *m_next;
-} COSE_CounterSign;
-#endif
+};
 
 #ifdef USE_CBOR_CONTEXT
 /**
@@ -169,30 +171,34 @@
 bool IsValidEncryptHandle(HCOSE_ENCRYPT h);
 bool IsValidEnvelopedHandle(HCOSE_ENVELOPED h);
 bool IsValidRecipientHandle(HCOSE_RECIPIENT h);
+bool IsValidSignHandle(HCOSE_SIGN h);
 bool IsValidSignerHandle(HCOSE_SIGNER h);
+bool IsValidSign1Handle(HCOSE_SIGN1 h);
 bool IsValidCounterSignHandle(HCOSE_COUNTERSIGN h);
+bool IsValidMacHandle(HCOSE_MAC h);
+bool IsValidMac0Handle(HCOSE_MAC0 h);
 
 bool _COSE_Init(COSE_INIT_FLAGS flags,
 	COSE *pcose,
 	int msgType,
-	CBOR_CONTEXT_COMMA cose_errback *errp);
+	CBOR_CONTEXT_COMMA cose_errback *perr);
 bool _COSE_Init_From_Object(COSE *pobj,
 	cn_cbor *pcbor,
-	CBOR_CONTEXT_COMMA cose_errback *perror);
+	CBOR_CONTEXT_COMMA cose_errback *perr);
 void _COSE_Release(COSE *pcose);
 
 cn_cbor *_COSE_map_get_string(COSE *cose,
 	const char *key,
 	int flags,
 	cose_errback *errp);
-cn_cbor *_COSE_map_get_int(COSE *cose, int key, int flags, cose_errback *errp);
+cn_cbor *_COSE_map_get_int(COSE *cose, int key, int flags, cose_errback *perr);
 bool _COSE_map_put(COSE *cose,
 	int key,
 	cn_cbor *value,
 	int flags,
-	cose_errback *errp);
+	cose_errback *perr);
 
-bool _COSE_SetExternal(COSE *hcose,
+bool _COSE_SetExternal(COSE *pcose,
 	const byte *pbExternalData,
 	size_t cbExternalData,
 	cose_errback *perr);
@@ -264,15 +270,16 @@
 bool _COSE_Signer_sign(COSE_SignerInfo *pSigner,
 	const cn_cbor *pcborBody,
 	const cn_cbor *pcborProtected,
+	const char *const contextString,
 	cose_errback *perr);
 COSE_SignerInfo *_COSE_SignerInfo_Init_From_Object(cn_cbor *cbor,
 	COSE_SignerInfo *pIn,
 	CBOR_CONTEXT_COMMA cose_errback *perr);
-bool _COSE_SignerInfo_Free(COSE_SignerInfo *pSigner);
-bool _COSE_Signer_validate(COSE_SignMessage *pSign,
-	COSE_SignerInfo *pSigner,
+bool _COSE_SignerInfo_Release(COSE_SignerInfo *pSigner);
+bool _COSE_Signer_validate(COSE_SignerInfo *pSigner,
 	const cn_cbor *pbContent,
 	const cn_cbor *pbProtected,
+	const char *const szContext,
 	cose_errback *perr);
 
 // Sign1 items
@@ -319,6 +326,11 @@
 bool _COSE_CountSign_create(COSE *pMessage,
 	cn_cbor *pcnBody,
 	CBOR_CONTEXT_COMMA cose_errback *perr);
+COSE_CounterSign *_COSE_CounterSign_Init_From_Object(cn_cbor *cbor,
+	COSE_CounterSign *,
+	CBOR_CONTEXT_COMMA cose_errback *perr);
+bool _COSE_CounterSign_Sign(COSE *baseMessage,
+	CBOR_CONTEXT_COMMA cose_errback *perr);
 
 //
 //  Debugging Items
@@ -399,8 +411,6 @@
 	cn_cbor *cb_value,
 	int index,
 	CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
-cn_cbor *cn_cbor_bool_create(int boolValue,
-	CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
 
 size_t cn_cbor_encode_size(cn_cbor *object);
 
diff --git a/src/mbedtls.c b/src/mbedtls.c
index a1f2a6f..adf2909 100644
--- a/src/mbedtls.c
+++ b/src/mbedtls.c
@@ -132,7 +132,8 @@
 				COSE_UNPROTECT_ONLY, perr))
 			goto errorReturn;
 		cbor_iv_t = NULL;
-	} else {
+	}
+	else {
 		CHECK_CONDITION(
 			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
 		CHECK_CONDITION(cbor_iv->length == NSize, COSE_ERR_INVALID_PARAMETER);
@@ -309,7 +310,8 @@
 				COSE_UNPROTECT_ONLY, perr))
 			goto errorReturn;
 		cbor_iv_t = NULL;
-	} else {
+	}
+	else {
 		CHECK_CONDITION(
 			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
 		CHECK_CONDITION(cbor_iv->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
@@ -919,7 +921,8 @@
 	if (p->type == CN_CBOR_UINT) {
 		CHECK_CONDITION(
 			p->v.uint == COSE_Key_Type_EC2, COSE_ERR_INVALID_PARAMETER);
-	} else {
+	}
+	else {
 		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
 	}
 
@@ -960,13 +963,16 @@
 		cbKey = cbGroup * 2 + 1;
 		CHECK_CONDITION(p->length == cbGroup, COSE_ERR_INVALID_PARAMETER);
 		memcpy(rgbKey + p->length + 1, p->v.str, p->length);
-	} else if (p->type == CN_CBOR_TRUE) {
+	}
+	else if (p->type == CN_CBOR_TRUE) {
 		cbKey = cbGroup + 1;
 		rgbKey[0] = 0x03;
-	} else if (p->type == CN_CBOR_FALSE) {
+	}
+	else if (p->type == CN_CBOR_FALSE) {
 		cbKey = cbGroup + 1;
 		rgbKey[0] = 0x02;
-	} else
+	}
+	else
 		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
 
 	CHECK_CONDITION(mbedtls_ecp_point_read_binary(
@@ -1551,7 +1557,8 @@
 
 		*ppKeyPrivate = pkey;
 		pkey = NULL;
-	} else {
+	}
+	else {
 		p = cn_cbor_mapget_int(*ppKeyPrivate, COSE_Key_EC_d);
 		CHECK_CONDITION(p != NULL, COSE_ERR_INVALID_PARAMETER);
 
diff --git a/src/openssl.c b/src/openssl.c
index e3b2ccb..5f1c87d 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -88,12 +88,14 @@
 
 	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
 	if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 
 	errorReturn:
-		if (rgbOut != NULL)
+		if (rgbOut != NULL) {
 			COSE_FREE(rgbOut, context);
+		}
 		EVP_CIPHER_CTX_free(ctx);
 		return false;
 	}
@@ -220,10 +222,12 @@
 		pbIV = NULL;
 
 		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
-				COSE_UNPROTECT_ONLY, perr))
+				COSE_UNPROTECT_ONLY, perr)) {
 			goto errorReturn;
+		}
 		cbor_iv_t = NULL;
-	} else {
+	}
+	else {
 		CHECK_CONDITION(
 			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
 		CHECK_CONDITION(cbor_iv->length == NSize, COSE_ERR_INVALID_PARAMETER);
@@ -281,14 +285,18 @@
 	return true;
 
 errorReturn:
-	if (pbIV != NULL)
+	if (pbIV != NULL) {
 		COSE_FREE(pbIV, context);
-	if (cbor_iv_t != NULL)
+	}
+	if (cbor_iv_t != NULL) {
 		COSE_FREE(cbor_iv_t, context);
-	if (rgbOut != NULL)
+	}
+	if (rgbOut != NULL) {
 		COSE_FREE(rgbOut, context);
-	if (cnTmp != NULL)
+	}
+	if (cnTmp != NULL) {
 		COSE_FREE(cnTmp, context);
+	}
 	EVP_CIPHER_CTX_free(ctx);
 	return false;
 }
@@ -321,12 +329,14 @@
 
 	pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL);
 	if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) {
-		if (perr != NULL)
+		if (perr != NULL) {
 			perr->err = COSE_ERR_INVALID_PARAMETER;
+		}
 
 	errorReturn:
-		if (rgbOut != NULL)
+		if (rgbOut != NULL) {
 			COSE_FREE(rgbOut, context);
+		}
 		EVP_CIPHER_CTX_free(ctx);
 		return false;
 	}
@@ -443,10 +453,12 @@
 		pbIV = NULL;
 
 		if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t,
-				COSE_UNPROTECT_ONLY, perr))
+				COSE_UNPROTECT_ONLY, perr)) {
 			goto errorReturn;
+		}
 		cbor_iv_t = NULL;
-	} else {
+	}
+	else {
 		CHECK_CONDITION(
 			cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
 		CHECK_CONDITION(cbor_iv->length == 96 / 8, COSE_ERR_INVALID_PARAMETER);
@@ -509,12 +521,15 @@
 	return true;
 
 errorReturn:
-	if (pbIV != NULL)
+	if (pbIV != NULL) {
 		COSE_FREE(pbIV, context);
-	if (cbor_iv_t != NULL)
+	}
+	if (cbor_iv_t != NULL) {
 		COSE_FREE(cbor_iv_t, context);
-	if (rgbOut != NULL)
+	}
+	if (rgbOut != NULL) {
 		COSE_FREE(rgbOut, context);
+	}
 	EVP_CIPHER_CTX_free(ctx);
 	return false;
 }
@@ -590,10 +605,12 @@
 	return !f;
 
 errorReturn:
-	if (rgbOut != NULL)
+	if (rgbOut != NULL) {
 		COSE_FREE(rgbOut, context);
-	if (cn != NULL)
+	}
+	if (cn != NULL) {
 		CN_CBOR_FREE(cn, context);
+	}
 	EVP_CIPHER_CTX_free(ctx);
 	return false;
 }
@@ -653,8 +670,9 @@
 	cn_cbor *cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
 	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);
 
-	for (i = 0; i < (unsigned int)TSize; i++)
+	for (i = 0; i < (unsigned int)TSize; i++) {
 		f |= (cn->v.bytes[i] != rgbTag[i]);
+	}
 
 	EVP_CIPHER_CTX_free(ctx);
 	return !f;
@@ -796,6 +814,9 @@
 	size_t *pcbDigest,
 	CBOR_CONTEXT_COMMA cose_errback *perr)
 {
+#ifdef USE_CBOR_CONTEXT
+	UNUSED(context);
+#endif
 	byte rgbSalt[EVP_MAX_MD_SIZE] = {0};
 	int cbSalt;
 	cn_cbor *cnSalt;
@@ -836,7 +857,8 @@
 		CHECK_CONDITION(
 			HMAC_Init_ex(ctx, cnSalt->v.bytes, (int)cnSalt->length, pmd, NULL),
 			COSE_ERR_CRYPTO_FAIL);
-	} else {
+	}
+	else {
 		CHECK_CONDITION(HMAC_Init_ex(ctx, rgbSalt, cbSalt, pmd, NULL),
 			COSE_ERR_CRYPTO_FAIL);
 	}
@@ -1018,10 +1040,12 @@
 	cn_cbor *cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG);
 	CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR);
 
-	if (cn->length > (int)cbOut)
+	if (cn->length > (int)cbOut) {
 		return false;
-	for (i = 0; i < (unsigned int)TSize / 8; i++)
+	}
+	for (i = 0; i < (unsigned int)TSize / 8; i++) {
 		f |= (cn->v.bytes[i] != rgbOut[i]);
+	}
 
 	HMAC_CTX_free(ctx);
 	return !f;
@@ -1087,13 +1111,16 @@
 		cbKey = (*cbGroup * 2) + 1;
 		CHECK_CONDITION(p->length == *cbGroup, COSE_ERR_INVALID_PARAMETER);
 		memcpy(rgbKey + p->length + 1, p->v.str, p->length);
-	} else if (p->type == CN_CBOR_TRUE) {
+	}
+	else if (p->type == CN_CBOR_TRUE) {
 		cbKey = (*cbGroup) + 1;
 		rgbKey[0] = POINT_CONVERSION_COMPRESSED + 1;
-	} else if (p->type == CN_CBOR_FALSE) {
+	}
+	else if (p->type == CN_CBOR_FALSE) {
 		cbKey = (*cbGroup) + 1;
 		rgbKey[0] = POINT_CONVERSION_COMPRESSED;
-	} else
+	}
+	else
 		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
 
 	pPoint = EC_POINT_new(ecgroup);
@@ -1117,8 +1144,9 @@
 	return pNewKey;
 
 errorReturn:
-	if (pNewKey != NULL)
+	if (pNewKey != NULL) {
 		EC_KEY_free(pNewKey);
+	}
 	return NULL;
 }
 
@@ -1174,7 +1202,8 @@
 			EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_COMPRESSED,
 				pbOut, cbSize, NULL) == cbSize,
 			COSE_ERR_CRYPTO_FAIL);
-	} else {
+	}
+	else {
 		cbSize = EC_POINT_point2oct(
 			pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
 		CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
@@ -1201,7 +1230,8 @@
 								 CBOR_CONTEXT_PARAM_COMMA & cbor_error),
 			cbor_error);
 		p = NULL;
-	} else {
+	}
+	else {
 		p = cn_cbor_data_create(pbOut + cbSize / 2 + 1, (int)(cbSize / 2),
 			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
 		pbOut = NULL;  // It is already part of the other one.
@@ -1221,10 +1251,12 @@
 	p = NULL;
 
 returnHere:
-	if (pbOut != NULL)
+	if (pbOut != NULL) {
 		COSE_FREE(pbOut, context);
-	if (p != NULL)
+	}
+	if (p != NULL) {
 		CN_CBOR_FREE(p, context);
+	}
 	return pkey;
 
 errorReturn:
@@ -1274,12 +1306,15 @@
 	eckey = ECKey_From(pKey, &cbR, perr);
 	if (eckey == NULL) {
 	errorReturn:
-		if (pbSig != NULL)
+		if (pbSig != NULL) {
 			COSE_FREE(pbSig, context);
-		if (p != NULL)
+		}
+		if (p != NULL) {
 			CN_CBOR_FREE(p, context);
-		if (eckey != NULL)
+		}
+		if (eckey != NULL) {
 			EC_KEY_free(eckey);
+		}
 		return false;
 	}
 
@@ -1326,8 +1361,9 @@
 
 	pbSig = NULL;
 
-	if (eckey != NULL)
+	if (eckey != NULL) {
 		EC_KEY_free(eckey);
+	}
 
 	return true;
 }
@@ -1358,12 +1394,15 @@
 	eckey = ECKey_From(pKey, &cbR, perr);
 	if (eckey == NULL) {
 	errorReturn:
-		if (p != NULL)
+		if (p != NULL) {
 			CN_CBOR_FREE(p, context);
-		if (eckey != NULL)
+		}
+		if (eckey != NULL) {
 			EC_KEY_free(eckey);
-		if (sig != NULL)
+		}
+		if (sig != NULL) {
 			ECDSA_SIG_free(sig);
+		}
 		return false;
 	}
 
@@ -1400,10 +1439,12 @@
 	CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, sig, eckey) == 1,
 		COSE_ERR_CRYPTO_FAIL);
 
-	if (eckey != NULL)
+	if (eckey != NULL) {
 		EC_KEY_free(eckey);
-	if (sig != NULL)
+	}
+	if (sig != NULL) {
 		ECDSA_SIG_free(sig);
+	}
 
 	return true;
 }
@@ -1430,14 +1471,18 @@
 	p = cn_cbor_mapget_int(pKeyIn, COSE_Key_OPK_Curve);
 	if (p == NULL) {
 	errorReturn:
-		if (mdCtx != NULL)
+		if (mdCtx != NULL) {
 			EVP_MD_CTX_free(mdCtx);
-		if (keyCtx != NULL)
+		}
+		if (keyCtx != NULL) {
 			EVP_PKEY_CTX_free(keyCtx);
-		if (pkey != NULL)
+		}
+		if (pkey != NULL) {
 			EVP_PKEY_free(pkey);
-		if (pbSig != NULL)
+		}
+		if (pbSig != NULL) {
 			COSE_FREE(pbSig, context);
+		}
 		return false;
 	}
 
@@ -1491,14 +1536,18 @@
 		_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL),
 		COSE_ERR_CBOR);
 
-	if (mdCtx != NULL)
+	if (mdCtx != NULL) {
 		EVP_MD_CTX_free(mdCtx);
-	if (keyCtx != NULL)
+	}
+	if (keyCtx != NULL) {
 		EVP_PKEY_CTX_free(keyCtx);
-	if (pkey != NULL)
+	}
+	if (pkey != NULL) {
 		EVP_PKEY_free(pkey);
-	if (pbSig != NULL)
+	}
+	if (pbSig != NULL) {
 		COSE_FREE(pbSig, context);
+	}
 
 	return true;
 }
@@ -1516,8 +1565,9 @@
 	cn_cbor *p = cn_cbor_mapget_int(pKey, COSE_Key_OPK_Curve);
 	if (p == NULL) {
 	errorReturn:
-		if (pkey != NULL)
+		if (pkey != NULL) {
 			EVP_PKEY_free(pkey);
+		}
 		return false;
 	}
 
@@ -1556,10 +1606,12 @@
 						rgbToSign, cbToSign) == 1,
 		COSE_ERR_CRYPTO_FAIL);
 
-	if (pmdCtx != NULL)
+	if (pmdCtx != NULL) {
 		EVP_MD_CTX_free(pmdCtx);
-	if (pkey != NULL)
+	}
+	if (pkey != NULL) {
 		EVP_PKEY_free(pkey);
+	}
 
 	return true;
 }
@@ -1630,8 +1682,9 @@
 
 errorReturn:
 	COSE_FREE(cnTmp, context);
-	if (pbOut != NULL)
+	if (pbOut != NULL) {
 		COSE_FREE(pbOut, context);
+	}
 	return false;
 }
 
@@ -1667,17 +1720,20 @@
 	bool fRet = false;
 
 	peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
-	if (peckeyPublic == NULL)
+	if (peckeyPublic == NULL) {
 		goto errorReturn;
+	}
 
 	if (*ppKeyPrivate == NULL) {
 		{
 			cn_cbor *pCompress = _COSE_map_get_int(
 				pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
-			if (pCompress == NULL)
+			if (pCompress == NULL) {
 				FUseCompressed = false;
-			else
+			}
+			else {
 				FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
+			}
 		}
 		peckeyPrivate = EC_KEY_new();
 		EC_KEY_set_group(peckeyPrivate, EC_KEY_get0_group(peckeyPublic));
@@ -1685,12 +1741,15 @@
 			EC_KEY_generate_key(peckeyPrivate) == 1, COSE_ERR_CRYPTO_FAIL);
 		*ppKeyPrivate =
 			EC_FromKey(peckeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
-		if (*ppKeyPrivate == NULL)
+		if (*ppKeyPrivate == NULL) {
 			goto errorReturn;
-	} else {
+		}
+	}
+	else {
 		peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
-		if (peckeyPrivate == NULL)
+		if (peckeyPrivate == NULL) {
 			goto errorReturn;
+		}
 	}
 
 	pbsecret = COSE_CALLOC(cbGroup, 1, context);
@@ -1707,12 +1766,15 @@
 	fRet = true;
 
 errorReturn:
-	if (pbsecret != NULL)
+	if (pbsecret != NULL) {
 		COSE_FREE(pbsecret, context);
-	if (peckeyPublic != NULL)
+	}
+	if (peckeyPublic != NULL) {
 		EC_KEY_free(peckeyPublic);
-	if (peckeyPrivate != NULL)
+	}
+	if (peckeyPrivate != NULL) {
 		EC_KEY_free(peckeyPrivate);
+	}
 
 	return fRet;
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f99e204..58b5ceb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -13,6 +13,11 @@
   target_link_libraries(cose_test PRIVATE ${OPENSSL_LIBRARIES})
 endif()
 
+if(COSE_C_OPTIMIZE)
+  # Don't worry about the compiler optimizations
+  add_definitions(-DNDEBUG)
+endif()
+
 if(MSVC)
   target_link_libraries(cose_test PRIVATE ws2_32)
 endif()
@@ -108,6 +113,12 @@
   NAME sign1
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
   COMMAND cose_test --dir Examples/sign1-tests)
+if(COSE_C_INCLUDE_COUNTERSIGN)
+  add_test(
+    NAME Countersign
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+    COMMAND cose_test --dir Examples/countersign)
+endif()
 
 add_test(
   NAME corner-cases
diff --git a/test/context.c b/test/context.c
index 7a89f6f..881517e 100644
--- a/test/context.c
+++ b/test/context.c
@@ -16,9 +16,11 @@
 	cn_cbor_context context;
 	byte *pFirst;
 	unsigned int iFailLeft;
+	int allocCount;
 } MyContext;
 
 typedef struct _MyItem {
+	int allocNumber;
 	struct _MyItem *pNext;
 	size_t size;
 	byte pad[4];
@@ -39,15 +41,17 @@
 					assert(false);
 				}
 			}
-		} else if (p->pad[0] == (byte)0xef) {
+		}
+		else if (p->pad[0] == (byte)0xef) {
 			for (unsigned i = 0; i < 4; i++) {
 				if ((p->pad[i] != (byte)0xef) ||
 					(p->pad[i + 4 + p->size] != (byte)0xef)) {
-					fprintf(stderr, "Curent block was overrun");
+					fprintf(stderr, "Current block was overrun");
 					assert(false);
 				}
 			}
-		} else {
+		}
+		else {
 			fprintf(stderr, "Incorrect pad value");
 			assert(false);
 		}
@@ -63,9 +67,12 @@
 
 	CheckMemory(myContext);
 
-	if (myContext->iFailLeft == 0)
-		return NULL;
-	myContext->iFailLeft--;
+	if (myContext->iFailLeft != -1) {
+		if (myContext->iFailLeft == 0) {
+			return NULL;
+		}
+		myContext->iFailLeft--;
+	}
 
 	pb = (MyItem *)malloc(sizeof(MyItem) + count * size);
 
@@ -75,6 +82,7 @@
 	pb->pNext = (struct _MyItem *)myContext->pFirst;
 	myContext->pFirst = (byte *)pb;
 	pb->size = count * size;
+	pb->allocNumber = myContext->allocCount++;
 
 	return &pb->data;
 }
@@ -85,8 +93,9 @@
 	MyContext *myContext = (MyContext *)context;
 
 	CheckMemory(myContext);
-	if (ptr == NULL)
+	if (ptr == NULL) {
 		return;
+	}
 
 	memset(&pb->pad, 0xab, pb->size + 8);
 }
@@ -100,6 +109,7 @@
 	p->context.context = p;
 	p->pFirst = NULL;
 	p->iFailLeft = iFailPoint;
+	p->allocCount = 0;
 
 	return &p->context;
 }
@@ -122,4 +132,25 @@
 	return;
 }
 
+int IsContextEmpty(cn_cbor_context *pContext)
+{
+	MyContext *myContext = (MyContext *)pContext;
+	MyItem *p;
+	int i = 0;
+
+	//  Walk memory and check every block
+
+	for (p = (MyItem *)myContext->pFirst; p != NULL; p = p->pNext) {
+		if (p->pad[0] == (byte)0xab) {
+			//  Block has been freed
+		}
+		else {
+			//  This block has not been freed
+			i += 1;
+		}
+	}
+
+	return i;
+}
+
 #endif	// USE_CBOR_CONTEXT
diff --git a/test/encrypt.c b/test/encrypt.c
index 98e4029..a776183 100644
--- a/test/encrypt.c
+++ b/test/encrypt.c
@@ -15,6 +15,7 @@
 #include "json.h"
 #include "test.h"
 #include "context.h"
+#include "cose_int.h"
 
 #ifdef _MSC_VER
 #pragma warning(disable : 4127)
@@ -35,22 +36,24 @@
 	HCOSE_RECIPIENT hRecip1 = NULL;
 	HCOSE_RECIPIENT hRecip2 = NULL;
 	bool fRet = false;
-	int type;
+	int type = 0;
 	cose_errback cose_err;
-	cn_cbor *pkey;
+	cn_cbor *pkey = NULL;
 	bool fNoSupport = false;
 
 	hEnc = (HCOSE_ENVELOPED)COSE_Decode(pbEncoded, cbEncoded, &type,
 		COSE_enveloped_object, CBOR_CONTEXT_PARAM_COMMA & cose_err);
 	if (hEnc == NULL) {
-		if (fFailBody && (cose_err.err == COSE_ERR_INVALID_PARAMETER))
+		if (fFailBody && (cose_err.err == COSE_ERR_INVALID_PARAMETER)) {
 			return true;
+		}
 		goto errorReturn;
 	}
 
 	if (!SetReceivingAttributes(
-			(HCOSE)hEnc, pEnveloped, Attributes_Enveloped_protected))
+			(HCOSE)hEnc, pEnveloped, Attributes_Enveloped_protected)) {
 		goto errorReturn;
+	}
 
 	cn_cbor *alg = COSE_Enveloped_map_get_int(
 		hEnc, COSE_Header_Algorithm, COSE_BOTH, NULL);
@@ -59,26 +62,32 @@
 	}
 
 	hRecip1 = COSE_Enveloped_GetRecipient(hEnc, iRecipient1, NULL);
-	if (hRecip1 == NULL)
+	if (hRecip1 == NULL) {
 		goto errorReturn;
+	}
 	if (!SetReceivingAttributes(
-			(HCOSE)hRecip1, pRecipient1, Attributes_Recipient_protected))
+			(HCOSE)hRecip1, pRecipient1, Attributes_Recipient_protected)) {
 		goto errorReturn;
+	}
 
 	if (pRecipient2 != NULL) {
 		pkey = BuildKey(cn_cbor_mapget_string(pRecipient2, "key"), false);
-		if (pkey == NULL)
+		if (pkey == NULL) {
 			goto errorReturn;
+		}
 
 		hRecip2 = COSE_Recipient_GetRecipient(hRecip1, iRecipient2, NULL);
-		if (hRecip2 == NULL)
+		if (hRecip2 == NULL) {
 			goto errorReturn;
+		}
 
 		if (!SetReceivingAttributes(
-				(HCOSE)hRecip2, pRecipient2, Attributes_Recipient_protected))
+				(HCOSE)hRecip2, pRecipient2, Attributes_Recipient_protected)) {
 			goto errorReturn;
-		if (!COSE_Recipient_SetKey(hRecip2, pkey, NULL))
+		}
+		if (!COSE_Recipient_SetKey(hRecip2, pkey, NULL)) {
 			goto errorReturn;
+		}
 
 		cn_cbor *cnStatic = cn_cbor_mapget_string(pRecipient2, "sender_key");
 		if (cnStatic != NULL) {
@@ -90,12 +99,15 @@
 		}
 
 		hRecip = hRecip2;
-	} else {
+	}
+	else {
 		pkey = BuildKey(cn_cbor_mapget_string(pRecipient1, "key"), false);
-		if (pkey == NULL)
+		if (pkey == NULL) {
 			goto errorReturn;
-		if (!COSE_Recipient_SetKey(hRecip1, pkey, NULL))
+		}
+		if (!COSE_Recipient_SetKey(hRecip1, pkey, NULL)) {
 			goto errorReturn;
+		}
 
 		cn_cbor *cnStatic = cn_cbor_mapget_string(pRecipient1, "sender_key");
 		if (cnStatic != NULL) {
@@ -111,45 +123,205 @@
 
 	if (!fFailBody) {
 		cn_cbor *cn = cn_cbor_mapget_string(pRecipient1, "fail");
-		if (cn != NULL && (cn->type == CN_CBOR_TRUE))
+		if (cn != NULL && (cn->type == CN_CBOR_TRUE)) {
 			fFailBody = true;
+		}
 		if (fFailBody && (pRecipient2 != NULL)) {
 			cn = cn_cbor_mapget_string(pRecipient2, "fail");
-			if (cn != NULL && (cn->type == CN_CBOR_TRUE))
+			if (cn != NULL && (cn->type == CN_CBOR_TRUE)) {
 				fFailBody = true;
+			}
 		}
 
 		if (hRecip2 != NULL) {
 			alg = COSE_Recipient_map_get_int(
 				hRecip2, COSE_Header_Algorithm, COSE_BOTH, NULL);
-			if (!IsAlgorithmSupported(alg))
+			if (!IsAlgorithmSupported(alg)) {
 				fNoSupport = true;
+			}
 		}
 		alg = COSE_Recipient_map_get_int(
 			hRecip1, COSE_Header_Algorithm, COSE_BOTH, NULL);
-		if (!IsAlgorithmSupported(alg))
+		if (!IsAlgorithmSupported(alg)) {
 			fNoSupport = true;
+		}
 	}
 
 	if (COSE_Enveloped_decrypt(hEnc, hRecip, NULL)) {
 		fRet = !fFailBody;
-	} else {
-		if (fNoSupport)
+	}
+	else {
+		if (fNoSupport) {
 			fRet = false;
-		else
+		}
+		else {
 			fRet = fFailBody;
+		}
 	}
 
-	if (!fRet && !fNoSupport)
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Encrypt0 Body
+
+	//  Validate counter signatures on signers
+	cn_cbor *countersignList =
+		cn_cbor_mapget_string(pRecipient1, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			fRet = false;
+			goto errorReturn;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Recipient_map_get_int(hRecip1, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			goto errorReturn;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSupportSign = false;
+
+			HCOSE_COUNTERSIGN h =
+				COSE_Recipient_get_countersignature(hRecip1, counterNo, 0);
+			if (h == NULL) {
+				fRet = false;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fRet = false;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fRet = false;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			alg = COSE_CounterSign_map_get_int(
+				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				noSupportSign = true;
+				fNoSupport = true;
+			}
+
+			if (COSE_Recipient_CounterSign_validate(hRecip1, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fRet = !noSupportSign;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
+
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Enveloped Body
+
+	//  Validate counter signatures on signers
+	countersignList = cn_cbor_mapget_string(pEnveloped, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			fRet = false;
+			goto errorReturn;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Enveloped_map_get_int(hEnc, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			fRet = false;
+			goto errorReturn;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSupportSign = false;
+			HCOSE_COUNTERSIGN h =
+				COSE_Enveloped_get_countersignature(hEnc, counterNo, 0);
+			if (h == NULL) {
+				fRet = false;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fRet = false;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fRet = false;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			alg = COSE_CounterSign_map_get_int(
+				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				noSupportSign = true;
+				fNoSupport = true;
+			}
+
+			if (COSE_Enveloped_CounterSign_validate(hEnc, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fRet = !noSupportSign;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
+
+	if (!fRet && !fNoSupport) {
 		CFails++;
+	}
 
 errorReturn:
-	if (hEnc != NULL)
+	if (hEnc != NULL) {
 		COSE_Enveloped_Free(hEnc);
-	if (hRecip1 != NULL)
+	}
+	if (hRecip1 != NULL) {
 		COSE_Recipient_Free(hRecip1);
-	if (hRecip2 != NULL)
+	}
+	if (hRecip2 != NULL) {
 		COSE_Recipient_Free(hRecip2);
+	}
 
 	return fRet;
 }
@@ -171,15 +343,18 @@
 		fFailBody = true;
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto errorReturn;
+	}
 	pEnveloped = cn_cbor_mapget_string(pInput, "enveloped");
-	if ((pEnveloped == NULL) || (pEnveloped->type != CN_CBOR_MAP))
+	if ((pEnveloped == NULL) || (pEnveloped->type != CN_CBOR_MAP)) {
 		goto errorReturn;
+	}
 
 	pRecipients = cn_cbor_mapget_string(pEnveloped, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto errorReturn;
+	}
 
 	iRecipient = (int)pRecipients->length - 1;
 	pRecipients = pRecipients->first_child;
@@ -187,15 +362,18 @@
 		cn_cbor *pRecip2 = cn_cbor_mapget_string(pRecipients, "recipients");
 		if (pRecip2 == NULL) {
 			if (DecryptMessage(pbEncoded, cbEncoded, fFailBody, pEnveloped,
-					pRecipients, iRecipient, NULL, 0))
+					pRecipients, iRecipient, NULL, 0)) {
 				passCount++;
-		} else {
+			}
+		}
+		else {
 			int iRecipient2 = (int)(pRecip2->length - 1);
 			pRecip2 = pRecip2->first_child;
 			for (; pRecip2 != NULL; pRecip2 = pRecip2->next, iRecipient2--) {
 				if (DecryptMessage(pbEncoded, cbEncoded, fFailBody, pEnveloped,
-						pRecipients, iRecipient, pRecip2, iRecipient2))
+						pRecipients, iRecipient, pRecip2, iRecipient2)) {
 					passCount++;
+				}
 			}
 		}
 	}
@@ -218,31 +396,37 @@
 {
 	HCOSE_RECIPIENT hRecip =
 		COSE_Recipient_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecip == NULL)
+	if (hRecip == NULL) {
 		goto returnError;
+	}
 
 	if (!SetSendingAttributes(
-			(HCOSE)hRecip, pRecipient, Attributes_Recipient_protected))
+			(HCOSE)hRecip, pRecipient, Attributes_Recipient_protected)) {
 		goto returnError;
+	}
 
 	cn_cbor *cnKey = cn_cbor_mapget_string(pRecipient, "key");
 	if (cnKey != NULL) {
 		cn_cbor *pkey = BuildKey(cnKey, true);
-		if (pkey == NULL)
+		if (pkey == NULL) {
 			goto returnError;
+		}
 
-		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL))
+		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
 			goto returnError;
+		}
 	}
 
 	cnKey = cn_cbor_mapget_string(pRecipient, "recipients");
 	if (cnKey != NULL) {
 		for (cnKey = cnKey->first_child; cnKey != NULL; cnKey = cnKey->next) {
 			HCOSE_RECIPIENT hRecip2 = BuildRecipient(cnKey);
-			if (hRecip2 == NULL)
+			if (hRecip2 == NULL) {
 				goto returnError;
-			if (!COSE_Recipient_AddRecipient(hRecip, hRecip2, NULL))
+			}
+			if (!COSE_Recipient_AddRecipient(hRecip, hRecip2, NULL)) {
 				goto returnError;
+			}
 			COSE_Recipient_Free(hRecip2);
 		}
 	}
@@ -252,10 +436,51 @@
 		cn_cbor *pSendKey = BuildKey(pSenderKey, false);
 		cn_cbor *pKid = cn_cbor_mapget_string(pSenderKey, "kid");
 		if (!COSE_Recipient_SetSenderKey(
-				hRecip, pSendKey, (pKid == NULL) ? 2 : 1, NULL))
+				hRecip, pSendKey, (pKid == NULL) ? 2 : 1, NULL)) {
 			goto returnError;
+		}
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	// On the Recipient
+	cn_cbor *countersigns1 = cn_cbor_mapget_string(pRecipient, "countersign");
+	if (countersigns1 != NULL) {
+		countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
+		cn_cbor *countersign = countersigns1->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Recipient_add_countersignature(
+					hRecip, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
 	return hRecip;
 
 returnError:
@@ -272,62 +497,103 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_ENVELOPED hEncObj =
 		COSE_Enveloped_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pEnveloped = cn_cbor_mapget_string(pInputs, "enveloped");
-	if (pEnveloped == NULL)
+	if (pEnveloped == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Enveloped_SetContent(
-			hEncObj, pContent->v.bytes, pContent->length, NULL))
+			hEncObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
 	if (!SetSendingAttributes(
-			(HCOSE)hEncObj, pEnveloped, Attributes_Enveloped_protected))
+			(HCOSE)hEncObj, pEnveloped, Attributes_Enveloped_protected)) {
 		goto returnError;
-
-#if 0
-	const cn_cbor * pCounterSign = cn_cbor_mapget_string(pEnveloped, "countersign");
-	if (pCounterSign != NULL) {
-		HCOSE_COUNTERSIGN hCSign = BuildCounterSign(pCounterSign);
-		if (hCSign == NULL) goto returnError;
-		if (!COSE_Enveloped_AddCounterSigner(hEncObj, hCSign, NULL)) goto returnError;
 	}
-#endif
 
 	const cn_cbor *pAlg =
 		COSE_Enveloped_map_get_int(hEncObj, 1, COSE_BOTH, NULL);
-	if (pAlg == NULL)
+	if (pAlg == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pRecipients =
 		cn_cbor_mapget_string(pEnveloped, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pRecipients = pRecipients->first_child;
 	for (iRecipient = 0; pRecipients != NULL;
 		 iRecipient++, pRecipients = pRecipients->next) {
 		HCOSE_RECIPIENT hRecip = BuildRecipient(pRecipients);
-		if (hRecip == NULL)
+		if (hRecip == NULL) {
 			goto returnError;
+		}
 
-		if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, NULL))
+		if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, NULL)) {
 			goto returnError;
+		}
 
 		COSE_Recipient_Free(hRecip);
 	}
 
-	if (!COSE_Enveloped_encrypt(hEncObj, NULL))
+#if INCLUDE_COUNTERSIGNATURE
+	// On the Evneloped body
+	cn_cbor *countersigns1 = cn_cbor_mapget_string(pEnveloped, "countersign");
+	if (countersigns1 != NULL) {
+		countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
+		cn_cbor *countersign = countersigns1->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Enveloped_add_countersignature(
+					hEncObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Enveloped_encrypt(hEncObj, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -358,39 +624,49 @@
 	char *sz = "This is the content to be used";
 	HCOSE_RECIPIENT hRecip = NULL;
 
-	if (hEncObj == NULL)
+	if (hEncObj == NULL) {
 		goto errorReturn;
+	}
 	if (!COSE_Enveloped_map_put_int(hEncObj, COSE_Header_Algorithm,
 			cn_cbor_int_create(COSE_Algorithm_AES_CCM_16_64_128,
 				CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		goto errorReturn;
-	if (!COSE_Enveloped_SetContent(hEncObj, (byte *)sz, strlen(sz), NULL))
+	}
+	if (!COSE_Enveloped_SetContent(hEncObj, (byte *)sz, strlen(sz), NULL)) {
 		goto errorReturn;
+	}
 	if (!COSE_Enveloped_map_put_int(hEncObj, COSE_Header_IV,
 			cn_cbor_data_create(rgbKid, 13, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_UNPROTECT_ONLY, NULL))
+			COSE_UNPROTECT_ONLY, NULL)) {
 		goto errorReturn;
+	}
 
 	hRecip = COSE_Recipient_from_shared_secret(
 		rgbSecret, cbSecret, rgbKid, cbKid, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecip == NULL)
+	if (hRecip == NULL) {
 		goto errorReturn;
-	if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, NULL))
+	}
+	if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, NULL)) {
 		goto errorReturn;
+	}
 
-	if (!COSE_Enveloped_encrypt(hEncObj, NULL))
+	if (!COSE_Enveloped_encrypt(hEncObj, NULL)) {
 		goto errorReturn;
+	}
 
 	cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0);
-	if (cb < 1)
+	if (cb < 1) {
 		goto errorReturn;
+	}
 	rgb = (byte *)malloc(cb);
-	if (rgb == NULL)
+	if (rgb == NULL) {
 		goto errorReturn;
+	}
 	cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
-	if (cb < 1)
+	if (cb < 1) {
 		goto errorReturn;
+	}
 
 	COSE_Recipient_Free(hRecip);
 	hRecip = NULL;
@@ -418,21 +694,25 @@
 	int typ;
 	hEncObj = (HCOSE_ENVELOPED)COSE_Decode(rgb, (int)cb, &typ,
 		COSE_enveloped_object, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncObj == NULL)
+	if (hEncObj == NULL) {
 		goto errorReturn;
+	}
 
 	int iRecipient = 0;
 	do {
 		hRecip = COSE_Enveloped_GetRecipient(hEncObj, iRecipient, NULL);
-		if (hRecip == NULL)
+		if (hRecip == NULL) {
 			break;
+		}
 
 		if (!COSE_Recipient_SetKey_secret(
-				hRecip, rgbSecret, cbSecret, NULL, 0, NULL))
+				hRecip, rgbSecret, cbSecret, NULL, 0, NULL)) {
 			goto errorReturn;
+		}
 
-		if (!COSE_Enveloped_decrypt(hEncObj, hRecip, NULL))
+		if (!COSE_Enveloped_decrypt(hEncObj, hRecip, NULL)) {
 			goto errorReturn;
+		}
 
 		COSE_Recipient_Free(hRecip);
 		hRecip = NULL;
@@ -445,10 +725,12 @@
 	return 1;
 
 errorReturn:
-	if (hEncObj != NULL)
+	if (hEncObj != NULL) {
 		COSE_Enveloped_Free(hEncObj);
-	if (hRecip != NULL)
+	}
+	if (hRecip != NULL) {
 		COSE_Recipient_Free(hRecip);
+	}
 	CFails++;
 	return 0;
 }
@@ -477,15 +759,18 @@
 		fFailBody = true;
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 	pEncrypt = cn_cbor_mapget_string(pInput, "encrypted");
-	if ((pEncrypt == NULL) || (pEncrypt->type != CN_CBOR_MAP))
+	if ((pEncrypt == NULL) || (pEncrypt->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 
 	pRecipients = cn_cbor_mapget_string(pEncrypt, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pRecipients = pRecipients->first_child;
 
@@ -493,29 +778,36 @@
 		hEnc = (HCOSE_ENCRYPT)COSE_Decode(pbEncoded, cbEncoded, &type,
 			COSE_encrypt_object, CBOR_CONTEXT_PARAM_COMMA NULL);
 		if (hEnc == NULL) {
-			if (fFailBody)
+			if (fFailBody) {
 				return 0;
-			else
+			}
+			else {
 				goto returnError;
+			}
 		}
-	} else {
+	}
+	else {
 		hEnc = COSE_Encrypt_Init_From_Object(
 			pcnEncoded, CBOR_CONTEXT_PARAM_COMMA NULL);
 		if (hEnc == NULL) {
-			if (fFailBody)
+			if (fFailBody) {
 				return 0;
-			else
+			}
+			else {
 				goto returnError;
+			}
 		}
 	}
 
 	if (!SetReceivingAttributes(
-			(HCOSE)hEnc, pEncrypt, Attributes_Encrypt_protected))
+			(HCOSE)hEnc, pEncrypt, Attributes_Encrypt_protected)) {
 		goto returnError;
+	}
 
 	cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"), true);
-	if (pkey == NULL)
+	if (pkey == NULL) {
 		goto returnError;
+	}
 
 	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);
 	if (k == NULL) {
@@ -536,38 +828,121 @@
 		if (!fAlgSupport) {
 			fFail = true;
 			fAlgSupport = false;
-		} else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
+		}
+		else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
 			fFail = true;
 		}
 
 		size_t cb;
-		byte *pb;
+		const byte *pb;
 		pb = COSE_Encrypt_GetContent(hEnc, &cb, NULL);
-	} else {
+	}
+	else {
 		if (fAlgSupport) {
 			fFail = true;
 			fAlgSupport = false;
-		} else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE))
+		}
+		else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
 			fFail = true;
+		}
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Encrypt0 Body
+
+	//  Validate counter signatures on signers
+	cn_cbor *countersignList = cn_cbor_mapget_string(pEncrypt, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			fFail = true;
+			goto exitHere;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Encrypt_map_get_int(hEnc, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			goto returnError;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSupportSign = false;
+			bool failThis = false;
+
+			HCOSE_COUNTERSIGN h =
+				COSE_Encrypt0_get_countersignature(hEnc, counterNo, 0);
+			if (h == NULL) {
+				fFail = true;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			alg = COSE_CounterSign_map_get_int(
+				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				noSupportSign = true;
+				fAlgSupport = false;
+			}
+
+			if (COSE_Encrypt0_CounterSign_validate(hEnc, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fFail = true;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
+
 	COSE_Encrypt_Free(hEnc);
 
 exitHere:
 
 	if (fAlgSupport) {
 		if (fFailBody) {
-			if (!fFail)
+			if (!fFail) {
 				fFail = true;
-			else
+			}
+			else {
 				fFail = false;
+			}
 		}
-	} else {
+	}
+	else {
 		fFail = false;
 	}
 
-	if (fFail)
+	if (fFail) {
 		CFails += 1;
+	}
 	return fAlgSupport ? 1 : 0;
 
 returnError:
@@ -582,13 +957,15 @@
 	int fRet;
 
 	fRet = _ValidateEncrypt(pControl, pbEncoded, cbEncoded, NULL);
-	if (!fRet)
+	if (!fRet) {
 		return fRet;
+	}
 
 	cn_cbor *cbor =
 		cn_cbor_decode(pbEncoded, cbEncoded, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (cbor == NULL)
+	if (cbor == NULL) {
 		return false;
+	}
 
 	return _ValidateEncrypt(pControl, NULL, 0, cbor);
 }
@@ -600,44 +977,93 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_ENCRYPT hEncObj = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pEncrypt = cn_cbor_mapget_string(pInputs, "encrypted");
-	if (pEncrypt == NULL)
+	if (pEncrypt == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Encrypt_SetContent(
-			hEncObj, pContent->v.bytes, pContent->length, NULL))
+			hEncObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
 	if (!SetSendingAttributes(
-			(HCOSE)hEncObj, pEncrypt, Attributes_Encrypt_protected))
+			(HCOSE)hEncObj, pEncrypt, Attributes_Encrypt_protected)) {
 		goto returnError;
+	}
 
 	const cn_cbor *pAlg = COSE_Encrypt_map_get_int(hEncObj, 1, COSE_BOTH, NULL);
-	if (pAlg == NULL)
+	if (pAlg == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pRecipients = cn_cbor_mapget_string(pEncrypt, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pRecipients = pRecipients->first_child;
 	cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"), false);
-	if (pkey == NULL)
+	if (pkey == NULL) {
 		goto returnError;
+	}
 
 	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);
 
-	if (!COSE_Encrypt_encrypt(hEncObj, k->v.bytes, k->length, NULL))
+#if INCLUDE_COUNTERSIGNATURE
+	// On the Encrypt0 body
+	cn_cbor *countersigns = cn_cbor_mapget_string(pEncrypt, "countersign");
+	if (countersigns != NULL) {
+		countersigns = cn_cbor_mapget_string(countersigns, "signers");
+		cn_cbor *countersign = countersigns->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Encrypt0_add_countersignature(
+					hEncObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Encrypt_encrypt(hEncObj, k->v.bytes, k->length, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -759,10 +1185,12 @@
 	CHECK_FAILURE(COSE_Enveloped_SetExternal(hEncrypt, NULL, 10, &cose_error),
 		COSE_ERR_INVALID_PARAMETER, CFails++);
 
-	if (!COSE_Enveloped_Free(hEncrypt))
+	if (!COSE_Enveloped_Free(hEncrypt)) {
 		CFails++;
-	if (!COSE_Recipient_Free(hRecipient))
+	}
+	if (!COSE_Recipient_Free(hRecipient)) {
 		CFails++;
+	}
 
 	//
 	//  Unsupported algorithm
@@ -770,8 +1198,9 @@
 	//  Bad Int algorithm
 
 	hEncrypt = COSE_Enveloped_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncrypt == NULL)
+	if (hEncrypt == NULL) {
 		CFails++;
+	}
 	CHECK_RETURN(
 		COSE_Enveloped_SetContent(hEncrypt, (byte *)"Message", 7, &cose_error),
 		COSE_ERR_NONE, CFails++);
@@ -781,8 +1210,9 @@
 		COSE_ERR_NONE, CFails++);
 	hRecipient = COSE_Recipient_from_shared_secret(
 		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecipient == NULL)
+	if (hRecipient == NULL) {
 		CFails++;
+	}
 	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEncrypt, hRecipient, &cose_error),
 		COSE_ERR_NONE, CFails++);
 	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncrypt, &cose_error),
@@ -791,8 +1221,9 @@
 	COSE_Enveloped_Free(hEncrypt);
 
 	hEncrypt = COSE_Enveloped_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncrypt == NULL)
+	if (hEncrypt == NULL) {
 		CFails++;
+	}
 	CHECK_RETURN(
 		COSE_Enveloped_SetContent(hEncrypt, (byte *)"Message", 7, &cose_error),
 		COSE_ERR_NONE, CFails++);
@@ -803,8 +1234,9 @@
 		COE_ERR_NONE, CFails++);
 	hRecipient = COSE_Recipient_from_shared_secret(
 		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecipient == NULL)
+	if (hRecipient == NULL) {
 		CFails++;
+	}
 	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEncrypt, hRecipient, &cose_error),
 		COSE_ERR_NONE, CFails++);
 	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncrypt, &cose_error),
@@ -837,22 +1269,29 @@
 
 	//  NULL Handle checks
 
-	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, NULL))
+	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+	}
+	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), NULL))
+	}
+	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), NULL)) {
 		CFails++;
-	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), NULL))
+	}
+	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), NULL)) {
 		CFails++;
-	if (COSE_Encrypt_Free((HCOSE_ENCRYPT)hEncrypt))
+	}
+	if (COSE_Encrypt_Free((HCOSE_ENCRYPT)hEncrypt)) {
 		CFails++;
+	}
 
-		//  Wrong type of handle checks
+	//  Wrong type of handle checks
 
 #if INCLUDE_MAC
 	hEncrypt = (HCOSE_ENCRYPT)COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
@@ -860,46 +1299,59 @@
 	hEncrypt = (HCOSE_ENCRYPT)COSE_CALLOC(1, sizeof(COSE), context);
 #endif
 
-	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, NULL))
+	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+	}
+	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), NULL))
+	}
+	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), NULL)) {
 		CFails++;
-	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), NULL))
+	}
+	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), NULL)) {
 		CFails++;
-	if (COSE_Encrypt_Free(hEncrypt))
+	}
+	if (COSE_Encrypt_Free(hEncrypt)) {
 		CFails++;
+	}
 
 	//
 	//  Unsupported algorithm
 
 	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncrypt == NULL)
+	if (hEncrypt == NULL) {
 		CFails++;
-	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Encrypt_map_put_int(hEncrypt, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Encrypt_Free(hEncrypt);
 
 	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncrypt == NULL)
+	if (hEncrypt == NULL) {
 		CFails++;
-	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Encrypt_map_put_int(hEncrypt, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Encrypt_Free(hEncrypt);
diff --git a/test/json.c b/test/json.c
index ce92fd0..0eb426d 100644
--- a/test/json.c
+++ b/test/json.c
@@ -54,9 +54,11 @@
 				break;
 
 			case '"':
-				for (ib2 = ib + 1; ib2 < cch; ib2++)
-					if (rgch[ib2] == '"')
+				for (ib2 = ib + 1; ib2 < cch; ib2++) {
+					if (rgch[ib2] == '"') {
 						break;
+					}
+				}
 				rgch[ib2] = 0;
 				node = cn_cbor_string_create(
 					&rgch[ib + 1], CBOR_CONTEXT_PARAM_COMMA NULL);
@@ -65,8 +67,9 @@
 				break;
 
 			case 't':
-				if (strncmp(&rgch[ib], "true", 4) != 0)
+				if (strncmp(&rgch[ib], "true", 4) != 0) {
 					goto error;
+				}
 				node =
 					cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA NULL);
 				node->type = CN_CBOR_TRUE;
@@ -74,8 +77,9 @@
 				break;
 
 			case 'f':
-				if (strncmp(&rgch[ib], "false", 5) != 0)
+				if (strncmp(&rgch[ib], "false", 5) != 0) {
 					goto error;
+				}
 				node =
 					cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA NULL);
 				node->type = CN_CBOR_FALSE;
@@ -95,10 +99,12 @@
 			case '-':
 				node = cn_cbor_int_create(
 					atol(&rgch[ib]), CBOR_CONTEXT_PARAM_COMMA NULL);
-				if (rgch[ib] == '-')
+				if (rgch[ib] == '-') {
 					ib++;
-				while (isdigit(rgch[ib]))
+				}
+				while (isdigit(rgch[ib])) {
 					ib++;
+				}
 				ib--;
 				break;
 
@@ -113,7 +119,8 @@
 			if (parent->last_child != NULL) {
 				parent->last_child->next = node;
 				parent->last_child = node;
-			} else {
+			}
+			else {
 				parent->first_child = node;
 			}
 			parent->last_child = node;
@@ -125,8 +132,9 @@
 		}
 		if (parent == NULL) {
 			parent = node;
-			if (root == NULL)
+			if (root == NULL) {
 				root = node;
+			}
 		}
 	}
 
@@ -169,8 +177,9 @@
 	*output_length = 4 * ((input_length + 2) / 3);
 
 	char *encoded_data = malloc(*output_length);
-	if (encoded_data == NULL)
+	if (encoded_data == NULL) {
 		return NULL;
+	}
 
 	for (size_t i = 0, j = 0; i < input_length;) {
 		uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
@@ -185,8 +194,9 @@
 		encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
 	}
 
-	for (int i = 0; i < mod_table[input_length % 3]; i++)
+	for (int i = 0; i < mod_table[input_length % 3]; i++) {
 		encoded_data[*output_length - 1 - i] = '=';
+	}
 
 	return encoded_data;
 }
@@ -197,8 +207,9 @@
 {
 	char *p = NULL;
 
-	if (decoding_table == NULL)
+	if (decoding_table == NULL) {
 		build_decoding_table();
+	}
 
 	if (input_length % 4 != 0) {
 		int c = 4 - (input_length % 4);
@@ -210,15 +221,18 @@
 	}
 
 	*output_length = input_length / 4 * 3;
-	if (data[input_length - 1] == '=')
+	if (data[input_length - 1] == '=') {
 		(*output_length)--;
-	if (data[input_length - 2] == '=')
+	}
+	if (data[input_length - 2] == '=') {
 		(*output_length)--;
+	}
 
 	unsigned char *decoded_data = malloc(*output_length);
 	if (decoded_data == NULL) {
-		if (p != NULL)
+		if (p != NULL) {
 			free(p);
+		}
 		return NULL;
 	}
 
@@ -235,12 +249,15 @@
 		uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) +
 						  (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
 
-		if (j < *output_length)
+		if (j < *output_length) {
 			decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
-		if (j < *output_length)
+		}
+		if (j < *output_length) {
 			decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
-		if (j < *output_length)
+		}
+		if (j < *output_length) {
 			decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
+		}
 	}
 
 	free(p);
@@ -251,8 +268,9 @@
 {
 	decoding_table = malloc(256);
 
-	for (int i = 0; i < 64; i++)
+	for (int i = 0; i < 64; i++) {
 		decoding_table[(int)encoding_table[i]] = (unsigned char)i;
+	}
 }
 
 void base64_cleanup()
@@ -278,18 +296,23 @@
 	for (unsigned int i = 0, j = 0; i < input_length; i++) {
 		int c;
 
-		if ('0' <= data[i] && data[i] <= '9')
+		if ('0' <= data[i] && data[i] <= '9') {
 			c = data[i] - '0';
-		else if ('A' <= data[i] && data[i] <= 'F')
+		}
+		else if ('A' <= data[i] && data[i] <= 'F') {
 			c = data[i] - 'A' + 10;
-		else if ('a' <= data[i] && data[i] <= 'f')
+		}
+		else if ('a' <= data[i] && data[i] <= 'f') {
 			c = data[i] - 'a' + 10;
-		else
+		}
+		else {
 			return NULL;
+		}
 
 		if ((i & 0x1) == 0) {
 			decoded_data[j] = ((unsigned char)c << 4);
-		} else {
+		}
+		else {
 			decoded_data[j++] |= (unsigned char)c;
 		}
 	}
diff --git a/test/mac_test.c b/test/mac_test.c
index dcd63aa..2fd1181 100644
--- a/test/mac_test.c
+++ b/test/mac_test.c
@@ -6,6 +6,7 @@
 #include <cose/cose.h>
 #include <cose/cose_configure.h>
 #include <cn-cbor/cn-cbor.h>
+#include "cose_int.h"
 #if INCLUDE_MAC && !INCLUDE_ENCRYPT0
 #include <cose_int.h>
 #endif
@@ -49,18 +50,22 @@
 		goto failTest;
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto failTest;
+	}
 	pMac = cn_cbor_mapget_string(pInput, "mac");
-	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP))
+	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) {
 		goto failTest;
+	}
 
-	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC_protected))
+	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC_protected)) {
 		goto failTest;
+	}
 
 	pRecipients = cn_cbor_mapget_string(pMac, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto failTest;
+	}
 
 	iRecipient = (int)pRecipients->length - 1;
 	pRecipients = pRecipients->first_child;
@@ -80,8 +85,9 @@
 		}
 
 		if (!SetReceivingAttributes(
-				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected))
+				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected)) {
 			goto failTest;
+		}
 
 		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
 			fFail = true;
@@ -114,30 +120,184 @@
 		if (COSE_Mac_validate(hMAC, hRecip, NULL)) {
 			if (fAlgNoSupport) {
 				fFail = true;
-			} else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
+			}
+			else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
 				fFail = true;
 			}
-		} else {
+		}
+		else {
 			if (fAlgNoSupport) {
 				returnCode = 0;
-			} else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE))
+			}
+			else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
 				fFail = true;
+			}
 		}
 
+#if INCLUDE_COUNTERSIGNATURE
+		//  Countersign on Encrypt0 Body
+
+		//  Validate counter signatures on signers
+		cn_cbor *countersignList =
+			cn_cbor_mapget_string(pRecipients, "countersign");
+		if (countersignList != NULL) {
+			cn_cbor *countersigners =
+				cn_cbor_mapget_string(countersignList, "signers");
+			if (countersigners == NULL) {
+				goto failTest;
+			}
+			int count = countersigners->length;
+			bool forward = true;
+
+			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_CounterSign,
+					COSE_UNPROTECT_ONLY, 0) == NULL) {
+				goto failTest;
+			}
+
+			for (int counterNo = 0; counterNo < count; counterNo++) {
+				bool noSignSupport = false;
+				HCOSE_COUNTERSIGN h =
+					COSE_Recipient_get_countersignature(hRecip, counterNo, 0);
+				if (h == NULL) {
+					continue;
+				}
+
+				alg = COSE_CounterSign_map_get_int(
+					h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+				if (!IsAlgorithmSupported(alg)) {
+					fAlgNoSupport = true;
+					noSignSupport = true;
+					returnCode = 0;
+				}
+
+				cn_cbor *counterSigner = cn_cbor_index(countersigners,
+					forward ? counterNo : count - counterNo - 1);
+
+				cn_cbor *pkeyCountersign = BuildKey(
+					cn_cbor_mapget_string(counterSigner, "key"), false);
+				if (pkeyCountersign == NULL) {
+					fFail = true;
+					COSE_CounterSign_Free(h);
+					continue;
+				}
+
+				if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+					fFail = true;
+					CN_CBOR_FREE(pkeyCountersign, context);
+					COSE_CounterSign_Free(h);
+					continue;
+				}
+
+				if (COSE_Recipient_CounterSign_validate(hRecip, h, 0)) {
+					//  I don't think we have any forced errors yet.
+				}
+				else {
+					if (forward && counterNo == 0 && count > 1) {
+						forward = false;
+						counterNo -= 1;
+					}
+					else {
+						fFail |= !noSignSupport;
+					}
+				}
+
+				CN_CBOR_FREE(pkeyCountersign, context);
+				COSE_CounterSign_Free(h);
+			}
+		}
+#endif
+
 		COSE_Recipient_Free(hRecip);
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Signed Body
+
+	//  Validate counter signatures on signers
+	cn_cbor *countersignList = cn_cbor_mapget_string(pMac, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			goto failTest;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Mac_map_get_int(hMAC, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			goto failTest;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSignSupport = false;
+
+			HCOSE_COUNTERSIGN h =
+				COSE_Mac_get_countersignature(hMAC, counterNo, 0);
+			if (h == NULL) {
+				fFail = true;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			cn_cbor *alg = COSE_CounterSign_map_get_int(
+				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				fAlgNoSupport = true;
+				noSignSupport = true;
+				returnCode = 0;
+			}
+
+			if (COSE_Mac_CounterSign_validate(hMAC, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fFail |= !noSignSupport;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
+
 	COSE_Mac_Free(hMAC);
 
 	if (fFailBody) {
-		if (!fFail)
+		if (!fFail) {
 			fFail = true;
-		else
+		}
+		else {
 			fFail = false;
+		}
 	}
 
-	if (fFail)
+	if (fFail && !fAlgNoSupport) {
 		CFails += 1;
+	}
 	return returnCode;
 
 failTest:
@@ -162,65 +322,159 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_MAC hMacObj = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pMac = cn_cbor_mapget_string(pInputs, "mac");
-	if (pMac == NULL)
+	if (pMac == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Mac_SetContent(
-			hMacObj, pContent->v.bytes, pContent->length, NULL))
+			hMacObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
-	if (!SetSendingAttributes((HCOSE)hMacObj, pMac, Attributes_MAC_protected))
+	if (!SetSendingAttributes((HCOSE)hMacObj, pMac, Attributes_MAC_protected)) {
 		goto returnError;
+	}
 
 	const cn_cbor *pRecipients = cn_cbor_mapget_string(pMac, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pRecipients = pRecipients->first_child;
 	for (iRecipient = 0; pRecipients != NULL;
 		 iRecipient++, pRecipients = pRecipients->next) {
 		cn_cbor *pkey =
 			BuildKey(cn_cbor_mapget_string(pRecipients, "key"), true);
-		if (pkey == NULL)
+		if (pkey == NULL) {
 			goto returnError;
+		}
 
 		HCOSE_RECIPIENT hRecip =
 			COSE_Recipient_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-		if (hRecip == NULL)
+		if (hRecip == NULL) {
 			goto returnError;
+		}
 
 		if (!SetSendingAttributes(
-				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected))
+				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected)) {
 			goto returnError;
+		}
 
-		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL))
+		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
 			goto returnError;
+		}
 
 		cn_cbor *pSenderKey = cn_cbor_mapget_string(pRecipients, "sender_key");
 		if (pSenderKey != NULL) {
 			cn_cbor *pSendKey = BuildKey(pSenderKey, false);
-			if (!COSE_Recipient_SetSenderKey(hRecip, pSendKey, 2, NULL))
+			if (!COSE_Recipient_SetSenderKey(hRecip, pSendKey, 2, NULL)) {
 				goto returnError;
+			}
 		}
 
-		if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL))
+		if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL)) {
 			goto returnError;
+		}
+
+#if INCLUDE_COUNTERSIGNATURE
+		// On the Recipient
+		cn_cbor *countersigns1 =
+			cn_cbor_mapget_string(pRecipients, "countersign");
+		if (countersigns1 != NULL) {
+			countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
+			cn_cbor *countersign = countersigns1->first_child;
+
+			for (; countersign != NULL; countersign = countersign->next) {
+				cn_cbor *pkeyCountersign =
+					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+				if (pkeyCountersign == NULL) {
+					goto returnError;
+				}
+
+				HCOSE_COUNTERSIGN hCountersign =
+					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+				if (hCountersign == NULL) {
+					goto returnError;
+				}
+
+				if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+						Attributes_Countersign_protected)) {
+					goto returnError;
+				}
+
+				if (!COSE_CounterSign_SetKey(
+						hCountersign, pkeyCountersign, NULL)) {
+					goto returnError;
+				}
+
+				if (!COSE_Recipient_add_countersignature(
+						hRecip, hCountersign, NULL)) {
+					goto returnError;
+				}
+
+				COSE_CounterSign_Free(hCountersign);
+			}
+		}
+
+#endif
 
 		COSE_Recipient_Free(hRecip);
 	}
 
-	if (!COSE_Mac_encrypt(hMacObj, NULL))
+#if INCLUDE_COUNTERSIGNATURE
+	// On the Evneloped body
+	cn_cbor *countersigns1 = cn_cbor_mapget_string(pMac, "countersign");
+	if (countersigns1 != NULL) {
+		countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
+		cn_cbor *countersign = countersigns1->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Mac_add_countersignature(hMacObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Mac_encrypt(hMacObj, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hMacObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -248,37 +502,46 @@
 	size_t cb = 0;
 	byte *rgb = NULL;
 
-	if (hEncObj == NULL)
+	if (hEncObj == NULL) {
 		goto errorReturn;
+	}
 
 	if (!COSE_Mac_map_put_int(hEncObj, COSE_Header_Algorithm,
 			cn_cbor_int_create(
 				COSE_Algorithm_HMAC_256_256, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		goto errorReturn;
-	if (!COSE_Mac_SetContent(hEncObj, (byte *)sz, strlen(sz), NULL))
+	}
+	if (!COSE_Mac_SetContent(hEncObj, (byte *)sz, strlen(sz), NULL)) {
 		goto errorReturn;
+	}
 
 	HCOSE_RECIPIENT hRecip = COSE_Recipient_from_shared_secret(rgbSecret,
 		sizeof(rgbSecret), rgbKid, cbKid, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecip == NULL)
+	if (hRecip == NULL) {
 		goto errorReturn;
-	if (!COSE_Mac_AddRecipient(hEncObj, hRecip, NULL))
+	}
+	if (!COSE_Mac_AddRecipient(hEncObj, hRecip, NULL)) {
 		goto errorReturn;
+	}
 
-	if (!COSE_Mac_encrypt(hEncObj, NULL))
+	if (!COSE_Mac_encrypt(hEncObj, NULL)) {
 		goto errorReturn;
+	}
 
 	cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0);
-	if (cb == 0)
+	if (cb == 0) {
 		goto errorReturn;
+	}
 
 	rgb = (byte *)malloc(cb);
-	if (rgb == NULL)
+	if (rgb == NULL) {
 		goto errorReturn;
+	}
 	cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
-	if (cb == 0)
+	if (cb == 0) {
 		goto errorReturn;
+	}
 
 	COSE_Mac_Free(hEncObj);
 
@@ -302,23 +565,27 @@
 	int typ;
 	hEncObj = (HCOSE_MAC)COSE_Decode(
 		rgb, (int)cb, &typ, COSE_mac_object, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hEncObj == NULL)
+	if (hEncObj == NULL) {
 		goto errorReturn;
+	}
 
 	int iRecipient = 0;
 	do {
 		HCOSE_RECIPIENT hRecip2;
 
 		hRecip2 = COSE_Mac_GetRecipient(hEncObj, iRecipient, NULL);
-		if (hRecip2 == NULL)
+		if (hRecip2 == NULL) {
 			break;
+		}
 
 		if (!COSE_Recipient_SetKey_secret(
-				hRecip2, rgbSecret, sizeof(rgbSecret), NULL, 0, NULL))
+				hRecip2, rgbSecret, sizeof(rgbSecret), NULL, 0, NULL)) {
 			goto errorReturn;
+		}
 
-		if (!COSE_Mac_validate(hEncObj, hRecip2, NULL))
+		if (!COSE_Mac_validate(hEncObj, hRecip2, NULL)) {
 			goto errorReturn;
+		}
 
 		iRecipient += 1;
 
@@ -359,24 +626,30 @@
 	hMAC = (HCOSE_MAC0)COSE_Decode(pbEncoded, cbEncoded, &type,
 		COSE_mac0_object, CBOR_CONTEXT_PARAM_COMMA NULL);
 	if (hMAC == NULL) {
-		if (fFailBody)
+		if (fFailBody) {
 			return 0;
-		else
+		}
+		else {
 			goto errorReturn;
+		}
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto errorReturn;
+	}
 	pMac = cn_cbor_mapget_string(pInput, "mac0");
-	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP))
+	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) {
 		goto errorReturn;
+	}
 
-	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC0_protected))
+	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC0_protected)) {
 		goto errorReturn;
+	}
 
 	pRecipients = cn_cbor_mapget_string(pMac, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto errorReturn;
+	}
 
 	pRecipients = pRecipients->first_child;
 
@@ -390,35 +663,119 @@
 
 	cn_cbor *alg =
 		COSE_Mac0_map_get_int(hMAC, COSE_Header_Algorithm, COSE_BOTH, NULL);
-	if (!IsAlgorithmSupported(alg))
+	if (!IsAlgorithmSupported(alg)) {
 		fUnsuportedAlg = true;
+	}
 
 	pFail = cn_cbor_mapget_string(pRecipients, "fail");
 	if (COSE_Mac0_validate(hMAC, k->v.bytes, k->length, NULL)) {
 		if (fUnsuportedAlg) {
 			fFail = true;
 			fUnsuportedAlg = false;
-		} else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE))
+		}
+		else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
 			fFail = true;
-	} else {
-		if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE))
-			fFail = true;
-		if (fUnsuportedAlg)
-			fFail = false;
+		}
 	}
+	else {
+		if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
+			fFail = true;
+		}
+		if (fUnsuportedAlg) {
+			fFail = false;
+		}
+	}
+
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Mac0 Body
+
+	//  Validate counter signatures on signers
+	cn_cbor *countersignList = cn_cbor_mapget_string(pMac, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			fFail = true;
+			goto exitHere;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Mac0_map_get_int(hMAC, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			fFail = true;
+			goto exitHere;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSignAlg = false;
+
+			HCOSE_COUNTERSIGN h =
+				COSE_Mac0_get_countersignature(hMAC, counterNo, 0);
+			if (h == NULL) {
+				fFail = true;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			alg = COSE_CounterSign_map_get_int(
+				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				fUnsuportedAlg = true;
+				noSignAlg = true;
+			}
+
+			if (COSE_Mac0_CounterSign_validate(hMAC, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fFail |= !noSignAlg;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
 
 	COSE_Mac0_Free(hMAC);
 
 	if (fFailBody) {
-		if (!fFail)
+		if (!fFail) {
 			fFail = true;
-		else
+		}
+		else {
 			fFail = false;
+		}
 	}
 exitHere:
-	if (fFail)
+	if (fFail) {
 		CFails += 1;
-	return 0;
+	}
+	return fUnsuportedAlg ? 0 : 1;
 
 errorReturn:
 	CFails += 1;
@@ -440,40 +797,88 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_MAC0 hMacObj = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pMac = cn_cbor_mapget_string(pInputs, "mac0");
-	if (pMac == NULL)
+	if (pMac == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Mac0_SetContent(
-			hMacObj, pContent->v.bytes, pContent->length, NULL))
+			hMacObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
-	if (!SetSendingAttributes((HCOSE)hMacObj, pMac, Attributes_MAC0_protected))
+	if (!SetSendingAttributes(
+			(HCOSE)hMacObj, pMac, Attributes_MAC0_protected)) {
 		goto returnError;
+	}
 
 	const cn_cbor *pRecipients = cn_cbor_mapget_string(pMac, "recipients");
-	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY))
+	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pRecipients = pRecipients->first_child;
 
 	cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"), false);
-	if (pkey == NULL)
+	if (pkey == NULL) {
 		goto returnError;
+	}
 
 	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);
 
-	if (!COSE_Mac0_encrypt(hMacObj, k->v.bytes, k->length, NULL))
+#if INCLUDE_COUNTERSIGNATURE
+	// On the sign body
+	cn_cbor *countersigns = cn_cbor_mapget_string(pMac, "countersign");
+	if (countersigns != NULL) {
+		countersigns = cn_cbor_mapget_string(countersigns, "signers");
+		cn_cbor *countersign = countersigns->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Mac0_add_countersignature(hMacObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Mac0_encrypt(hMacObj, k->v.bytes, k->length, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hMacObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -510,25 +915,35 @@
 
 	//  Invalid Handle checks
 
-	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL))
+	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
+	}
 	if (COSE_Mac_map_put_int(
-			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL))
+	}
+	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL)) {
 		CFails++;
-	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL))
+	}
+	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
 		CFails++;
-	if (COSE_Mac_AddRecipient((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL))
+	}
+	if (COSE_Mac_AddRecipient(
+			(HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
 		CFails++;
-	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL))
+	}
+	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL)) {
 		CFails++;
-	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL))
+	}
+	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL)) {
 		CFails++;
-	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt))
+	}
+	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt)) {
 		CFails++;
+	}
 
 #if INCLUDE_ENCRYPT0
 	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
@@ -536,64 +951,84 @@
 	hEncrypt = (HCOSE_ENCRYPT)COSE_CALLOC(1, sizeof(COSE), context);
 #endif
 
-	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL))
+	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
+	}
 	if (COSE_Mac_map_put_int(
-			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL))
+	}
+	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL)) {
 		CFails++;
-	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL))
+	}
+	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
 		CFails++;
-	if (COSE_Mac_AddRecipient((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL))
+	}
+	if (COSE_Mac_AddRecipient(
+			(HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
 		CFails++;
-	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL))
+	}
+	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL)) {
 		CFails++;
-	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL))
+	}
+	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL)) {
 		CFails++;
-	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt))
+	}
+	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt)) {
 		CFails++;
+	}
 
 	//
 	//  Unsupported algorithm
 
 	hMAC = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hMAC == NULL)
+	if (hMAC == NULL) {
 		CFails++;
-	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Mac_map_put_int(hMAC, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	hRecipient = COSE_Recipient_from_shared_secret(
 		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecipient == NULL)
+	if (hRecipient == NULL) {
 		CFails++;
-	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL))
+	}
+	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Mac_encrypt(hMAC, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Mac_Free(hMAC);
 	COSE_Recipient_Free(hRecipient);
 
 	hMAC = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hMAC == NULL)
+	if (hMAC == NULL) {
 		CFails++;
-	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Mac_map_put_int(hMAC, COSE_Header_Algorithm,
 			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	hRecipient = COSE_Recipient_from_shared_secret(
 		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hRecipient == NULL)
+	if (hRecipient == NULL) {
 		CFails++;
-	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL))
+	}
+	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Mac_encrypt(hMAC, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Recipient_Free(hRecipient);
@@ -620,66 +1055,86 @@
 
 	//  Invalid Handle checks
 
-	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
+	}
 	if (COSE_Mac0_map_put_int(
-			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL))
+	}
+	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL)) {
 		CFails++;
-	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt))
+	}
+	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt)) {
 		CFails++;
+	}
 
 	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
-	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL))
+	}
+	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL)) {
 		CFails++;
+	}
 	if (COSE_Mac0_map_put_int(
-			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL))
+			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL))
+	}
+	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
 		CFails++;
-	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL))
+	}
+	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL)) {
 		CFails++;
+	}
 
-	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt))
+	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt)) {
 		CFails++;
+	}
 
 	//
 	//  Unsupported algorithm
 
 	hMAC = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hMAC == NULL)
+	if (hMAC == NULL) {
 		CFails++;
-	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Mac0_map_put_int(hMAC, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Mac0_encrypt(hMAC, rgb, sizeof(rgb), &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Mac0_Free(hMAC);
 
 	hMAC = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hMAC == NULL)
+	if (hMAC == NULL) {
 		CFails++;
-	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL))
+	}
+	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Mac0_map_put_int(hMAC, COSE_Header_Algorithm,
 			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Mac0_encrypt(hMAC, rgb, sizeof(rgb), &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Mac0_Free(hMAC);
diff --git a/test/sign.c b/test/sign.c
index 22a949d..870adc1 100644
--- a/test/sign.c
+++ b/test/sign.c
@@ -16,6 +16,7 @@
 #include "json.h"
 #include "test.h"
 #include "context.h"
+#include "cose_int.h"
 
 #ifdef _MSC_VER
 #pragma warning(disable : 4127)
@@ -42,15 +43,18 @@
 		fFailBody = true;
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 	pSign = cn_cbor_mapget_string(pInput, "sign");
-	if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP))
+	if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 
 	pSigners = cn_cbor_mapget_string(pSign, "signers");
-	if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY))
+	if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	iSigner = (int)pSigners->length - 1;
 	pSigners = pSigners->first_child;
@@ -58,14 +62,17 @@
 		hSig = (HCOSE_SIGN)COSE_Decode(pbEncoded, cbEncoded, &type,
 			COSE_sign_object, CBOR_CONTEXT_PARAM_COMMA NULL);
 		if (hSig == NULL) {
-			if (fFailBody)
+			if (fFailBody) {
 				return 0;
-			else
+			}
+			else {
 				goto returnError;
+			}
 		}
 		if (!SetReceivingAttributes(
-				(HCOSE)hSig, pSign, Attributes_Sign_protected))
+				(HCOSE)hSig, pSign, Attributes_Sign_protected)) {
 			goto returnError;
+		}
 
 		cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pSigners, "key"), false);
 		if (pkey == NULL) {
@@ -79,8 +86,9 @@
 			continue;
 		}
 		if (!SetReceivingAttributes(
-				(HCOSE)hSigner, pSigners, Attributes_Signer_protected))
+				(HCOSE)hSigner, pSigners, Attributes_Signer_protected)) {
 			goto returnError;
+		}
 
 		if (!COSE_Signer_SetKey(hSigner, pkey, NULL)) {
 			fFail = true;
@@ -89,36 +97,194 @@
 
 		cn_cbor *alg = COSE_Signer_map_get_int(
 			hSigner, COSE_Header_Algorithm, COSE_BOTH, 0);
-		if (!IsAlgorithmSupported(alg))
+		if (!IsAlgorithmSupported(alg)) {
 			fNoSupportAlg = true;
+		}
 
 		pFail = cn_cbor_mapget_string(pSigners, "fail");
 		if (COSE_Sign_validate(hSig, hSigner, NULL)) {
 			if (fNoSupportAlg) {
 				fFail = true;
-			} else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE))
+			}
+			else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
 				fFail = true;
-		} else {
+			}
+		}
+		else {
 			if (fNoSupportAlg) {
 				fFailBody = false;
 				fFail = false;
-			} else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE))
+			}
+			else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
 				fFail = true;
+			}
 		}
 
+#if INCLUDE_COUNTERSIGNATURE
+		//  Validate counter signatures on signers
+		cn_cbor *countersignList =
+			cn_cbor_mapget_string(pSigners, "countersign");
+		if (countersignList != NULL) {
+			cn_cbor *countersigners =
+				cn_cbor_mapget_string(countersignList, "signers");
+			if (countersigners == NULL) {
+				fFail = true;
+				continue;
+			}
+			int count = countersigners->length;
+			bool forward = true;
+
+			if (COSE_Signer_map_get_int(hSigner, COSE_Header_CounterSign,
+					COSE_UNPROTECT_ONLY, 0) == NULL) {
+				goto returnError;
+			}
+
+			for (int counterNo = 0; counterNo < count; counterNo++) {
+				bool noSignAlg = false;
+
+				HCOSE_COUNTERSIGN h =
+					COSE_Signer_get_countersignature(hSigner, counterNo, 0);
+				if (h == NULL) {
+					fFail = true;
+					continue;
+				}
+
+				cn_cbor *counterSigner = cn_cbor_index(countersigners,
+					forward ? counterNo : count - counterNo - 1);
+
+				cn_cbor *pkeyCountersign = BuildKey(
+					cn_cbor_mapget_string(counterSigner, "key"), false);
+				if (pkeyCountersign == NULL) {
+					fFail = true;
+					COSE_CounterSign_Free(h);
+					continue;
+				}
+
+				if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+					fFail = true;
+					COSE_CounterSign_Free(h);
+					CN_CBOR_FREE(pkeyCountersign, context);
+					continue;
+				}
+
+				alg = COSE_CounterSign_map_get_int(
+					h, COSE_Header_Algorithm, COSE_BOTH, 0);
+				if (!IsAlgorithmSupported(alg)) {
+					fNoSupportAlg = true;
+					noSignAlg = true;
+				}
+
+				if (COSE_Signer_CounterSign_validate(hSigner, h, 0)) {
+					//  I don't think we have any forced errors yet.
+				}
+				else {
+					if (forward && counterNo == 0 && count > 1) {
+						forward = false;
+						counterNo -= 1;
+					}
+					else {
+						fFail |= !noSignAlg;
+					}
+				}
+
+				CN_CBOR_FREE(pkeyCountersign, context);
+				COSE_CounterSign_Free(h);
+			}
+		}
+#endif
+
+#if INCLUDE_COUNTERSIGNATURE
+		//  Countersign on Signed Body
+
+		if (iSigner == 0) {
+			//  Validate counter signatures on signers
+			countersignList = cn_cbor_mapget_string(pSign, "countersign");
+			if (countersignList != NULL) {
+				cn_cbor *countersigners =
+					cn_cbor_mapget_string(countersignList, "signers");
+				if (countersigners == NULL) {
+					fFail = true;
+					continue;
+				}
+				int count = countersigners->length;
+				bool forward = true;
+
+				if (COSE_Sign_map_get_int(hSig, COSE_Header_CounterSign,
+						COSE_UNPROTECT_ONLY, 0) == NULL) {
+					goto returnError;
+				}
+
+				for (int counterNo = 0; counterNo < count; counterNo++) {
+					bool noSignAlg = false;
+
+					HCOSE_COUNTERSIGN h =
+						COSE_Sign_get_countersignature(hSig, counterNo, 0);
+					if (h == NULL) {
+						fFail = true;
+						continue;
+					}
+
+					cn_cbor *counterSigner = cn_cbor_index(countersigners,
+						forward ? counterNo : count - counterNo - 1);
+
+					cn_cbor *pkeyCountersign = BuildKey(
+						cn_cbor_mapget_string(counterSigner, "key"), false);
+					if (pkeyCountersign == NULL) {
+						fFail = true;
+						COSE_CounterSign_Free(h);
+						continue;
+					}
+
+					if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+						fFail = true;
+						COSE_CounterSign_Free(h);
+						CN_CBOR_FREE(pkeyCountersign, context);
+						continue;
+					}
+
+					alg = COSE_CounterSign_map_get_int(
+						h, COSE_Header_Algorithm, COSE_BOTH, 0);
+					if (!IsAlgorithmSupported(alg)) {
+						fNoSupportAlg = true;
+						noSignAlg = true;
+					}
+
+					if (COSE_Sign_CounterSign_validate(hSig, h, 0)) {
+						//  I don't think we have any forced errors yet.
+					}
+					else {
+						if (forward && counterNo == 0 && count > 1) {
+							forward = false;
+							counterNo -= 1;
+						}
+						else {
+							fFail |= !noSignAlg;
+						}
+					}
+
+					CN_CBOR_FREE(pkeyCountersign, context);
+					COSE_CounterSign_Free(h);
+				}
+			}
+		}
+#endif
+
 		COSE_Sign_Free(hSig);
 		COSE_Signer_Free(hSigner);
 	}
 
 	if (fFailBody) {
-		if (!fFail)
+		if (!fFail) {
 			fFail = true;
-		else
+		}
+		else {
 			fFail = false;
+		}
 	}
 
-	if (fFail)
+	if (fFail) {
 		CFails += 1;
+	}
 	return fNoSupportAlg ? 0 : 1;
 
 returnError:
@@ -143,56 +309,145 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_SIGN hSignObj = COSE_Sign_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pSign = cn_cbor_mapget_string(pInputs, "sign");
-	if (pSign == NULL)
+	if (pSign == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Sign_SetContent(
-			hSignObj, pContent->v.bytes, pContent->length, NULL))
+			hSignObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
 	if (!SetSendingAttributes(
-			(HCOSE)hSignObj, pSign, Attributes_Sign_protected))
+			(HCOSE)hSignObj, pSign, Attributes_Sign_protected)) {
 		goto returnError;
+	}
 
 	const cn_cbor *pSigners = cn_cbor_mapget_string(pSign, "signers");
-	if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY))
+	if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY)) {
 		goto returnError;
+	}
 
 	pSigners = pSigners->first_child;
 	for (iSigner = 0; pSigners != NULL; iSigner++, pSigners = pSigners->next) {
 		cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pSigners, "key"), false);
-		if (pkey == NULL)
+		if (pkey == NULL) {
 			goto returnError;
+		}
 
 		HCOSE_SIGNER hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
-		if (hSigner == NULL)
+		if (hSigner == NULL) {
 			goto returnError;
+		}
 
 		if (!SetSendingAttributes(
-				(HCOSE)hSigner, pSigners, Attributes_Signer_protected))
+				(HCOSE)hSigner, pSigners, Attributes_Signer_protected)) {
 			goto returnError;
+		}
 
-		if (!COSE_Signer_SetKey(hSigner, pkey, NULL))
+		if (!COSE_Signer_SetKey(hSigner, pkey, NULL)) {
 			goto returnError;
+		}
 
-		if (!COSE_Sign_AddSigner(hSignObj, hSigner, NULL))
+		if (!COSE_Sign_AddSigner(hSignObj, hSigner, NULL)) {
 			goto returnError;
+		}
 
+#if INCLUDE_COUNTERSIGNATURE
+		//  On the signer object
+		cn_cbor *countersigns = cn_cbor_mapget_string(pSigners, "countersign");
+		if (countersigns != NULL) {
+			countersigns = cn_cbor_mapget_string(countersigns, "signers");
+			cn_cbor *countersign = countersigns->first_child;
+
+			for (; countersign != NULL; countersign = countersign->next) {
+				cn_cbor *pkeyCountersign =
+					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+				if (pkeyCountersign == NULL) {
+					goto returnError;
+				}
+
+				HCOSE_COUNTERSIGN hCountersign =
+					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+				if (hCountersign == NULL) {
+					goto returnError;
+				}
+
+				if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+						Attributes_Countersign_protected)) {
+					goto returnError;
+				}
+
+				if (!COSE_CounterSign_SetKey(
+						hCountersign, pkeyCountersign, NULL)) {
+					goto returnError;
+				}
+
+				if (!COSE_Signer_add_countersignature(
+						hSigner, hCountersign, NULL)) {
+					goto returnError;
+				}
+
+				COSE_CounterSign_Free(hCountersign);
+			}
+		}
+#endif
 		COSE_Signer_Free(hSigner);
 	}
+#if INCLUDE_COUNTERSIGNATURE
+	// On the sign body
+	cn_cbor *countersigns1 = cn_cbor_mapget_string(pSign, "countersign");
+	if (countersigns1 != NULL) {
+		countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
+		cn_cbor *countersign = countersigns1->first_child;
 
-	if (!COSE_Sign_Sign(hSignObj, NULL))
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Sign_add_countersignature(hSignObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Sign_Sign(hSignObj, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hSignObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -326,23 +581,29 @@
 		fFailBody = true;
 	}
 
-	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP))
+	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 	pSign = cn_cbor_mapget_string(pInput, "sign0");
-	if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP))
+	if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP)) {
 		goto returnError;
+	}
 
 	hSig = (HCOSE_SIGN1)COSE_Decode(pbEncoded, cbEncoded, &type,
 		COSE_sign1_object, CBOR_CONTEXT_PARAM_COMMA NULL);
 	if (hSig == NULL) {
-		if (fFailBody)
+		if (fFailBody) {
 			return 0;
-		else
+		}
+		else {
 			goto returnError;
+		}
 	}
 
-	if (!SetReceivingAttributes((HCOSE)hSig, pSign, Attributes_Sign1_protected))
+	if (!SetReceivingAttributes(
+			(HCOSE)hSig, pSign, Attributes_Sign1_protected)) {
 		goto returnError;
+	}
 
 	cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pSign, "key"), false);
 	if (pkey == NULL) {
@@ -352,36 +613,119 @@
 
 	cn_cbor *alg =
 		COSE_Sign1_map_get_int(hSig, COSE_Header_Algorithm, COSE_BOTH, NULL);
-	if (!IsAlgorithmSupported(alg))
+	if (!IsAlgorithmSupported(alg)) {
 		fNoAlgSupport = true;
+	}
 
 	pFail = cn_cbor_mapget_string(pInput, "fail");
 	if (COSE_Sign1_validate(hSig, pkey, NULL)) {
 		if (fNoAlgSupport) {
 			fFail = true;
-		} else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE))
+		}
+		else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
 			fFail = true;
-	} else {
+		}
+	}
+	else {
 		if (fNoAlgSupport) {
 			fFailBody = false;
 			fFail = false;
-		} else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE))
+		}
+		else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
 			fFail = true;
+		}
 	}
 
+#if INCLUDE_COUNTERSIGNATURE
+	//  Countersign on Signed Body
+
+	//  Validate counter signatures on signers
+	cn_cbor *countersignList = cn_cbor_mapget_string(pSign, "countersign");
+	if (countersignList != NULL) {
+		cn_cbor *countersigners =
+			cn_cbor_mapget_string(countersignList, "signers");
+		if (countersigners == NULL) {
+			fFail = true;
+			goto exitHere;
+		}
+		int count = countersigners->length;
+		bool forward = true;
+
+		if (COSE_Sign1_map_get_int(hSig, COSE_Header_CounterSign,
+				COSE_UNPROTECT_ONLY, 0) == NULL) {
+			goto returnError;
+		}
+
+		for (int counterNo = 0; counterNo < count; counterNo++) {
+			bool noSignAlg = false;
+
+			HCOSE_COUNTERSIGN h =
+				COSE_Sign1_get_countersignature(hSig, counterNo, 0);
+			if (h == NULL) {
+				fFail = true;
+				continue;
+			}
+
+			cn_cbor *counterSigner = cn_cbor_index(
+				countersigners, forward ? counterNo : count - counterNo - 1);
+
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
+			if (pkeyCountersign == NULL) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				continue;
+			}
+
+			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
+				fFail = true;
+				COSE_CounterSign_Free(h);
+				CN_CBOR_FREE(pkeyCountersign, context);
+				continue;
+			}
+
+			alg = COSE_Sign1_map_get_int(
+				hSig, COSE_Header_Algorithm, COSE_BOTH, NULL);
+			if (!IsAlgorithmSupported(alg)) {
+				fNoAlgSupport = true;
+				noSignAlg = true;
+			}
+
+			if (COSE_Sign1_CounterSign_validate(hSig, h, 0)) {
+				//  I don't think we have any forced errors yet.
+			}
+			else {
+				if (forward && counterNo == 0 && count > 1) {
+					forward = false;
+					counterNo -= 1;
+				}
+				else {
+					fFail |= !noSignAlg;
+				}
+			}
+
+			CN_CBOR_FREE(pkeyCountersign, context);
+			COSE_CounterSign_Free(h);
+		}
+	}
+#endif
+
 	COSE_Sign1_Free(hSig);
 
 	if (fFailBody) {
-		if (!fFail)
+		if (!fFail) {
 			fFail = true;
-		else
+		}
+		else {
 			fFail = false;
+		}
 	}
 
 exitHere:
 
-	if (fFail)
+	if (fFail) {
 		CFails += 1;
+	}
 	return fNoAlgSupport ? 0 : 1;
 
 returnError:
@@ -404,33 +748,80 @@
 	//
 
 	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
-	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE))
+	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
 		return 0;
+	}
 
 	HCOSE_SIGN1 hSignObj = COSE_Sign1_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
 
 	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
-	if (pInputs == NULL)
+	if (pInputs == NULL) {
 		goto returnError;
+	}
 	const cn_cbor *pSign = cn_cbor_mapget_string(pInputs, "sign0");
-	if (pSign == NULL)
+	if (pSign == NULL) {
 		goto returnError;
+	}
 
 	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
 	if (!COSE_Sign1_SetContent(
-			hSignObj, pContent->v.bytes, pContent->length, NULL))
+			hSignObj, pContent->v.bytes, pContent->length, NULL)) {
 		goto returnError;
+	}
 
 	if (!SetSendingAttributes(
-			(HCOSE)hSignObj, pSign, Attributes_Sign1_protected))
+			(HCOSE)hSignObj, pSign, Attributes_Sign1_protected)) {
 		goto returnError;
+	}
 
 	cn_cbor *pkey = BuildKey(cn_cbor_mapget_string(pSign, "key"), false);
-	if (pkey == NULL)
+	if (pkey == NULL) {
 		goto returnError;
+	}
 
-	if (!COSE_Sign1_Sign(hSignObj, pkey, NULL))
+#if INCLUDE_COUNTERSIGNATURE
+	// On the sign body
+	cn_cbor *countersigns = cn_cbor_mapget_string(pSign, "countersign");
+	if (countersigns != NULL) {
+		countersigns = cn_cbor_mapget_string(countersigns, "signers");
+		cn_cbor *countersign = countersigns->first_child;
+
+		for (; countersign != NULL; countersign = countersign->next) {
+			cn_cbor *pkeyCountersign =
+				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
+			if (pkeyCountersign == NULL) {
+				goto returnError;
+			}
+
+			HCOSE_COUNTERSIGN hCountersign =
+				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+			if (hCountersign == NULL) {
+				goto returnError;
+			}
+
+			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
+					Attributes_Countersign_protected)) {
+				goto returnError;
+			}
+
+			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
+				goto returnError;
+			}
+
+			if (!COSE_Sign1_add_countersignature(
+					hSignObj, hCountersign, NULL)) {
+				goto returnError;
+			}
+
+			COSE_CounterSign_Free(hCountersign);
+		}
+	}
+
+#endif
+
+	if (!COSE_Sign1_Sign(hSignObj, pkey, NULL)) {
 		goto returnError;
+	}
 
 	size_t cb = COSE_Encode((HCOSE)hSignObj, NULL, 0, 0) + 1;
 	byte *rgb = (byte *)malloc(cb);
@@ -594,54 +985,69 @@
 	//  Unsupported algorithm
 
 	hSign = COSE_Sign_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSign == NULL)
+	if (hSign == NULL) {
 		CFails++;
+	}
 	hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSigner == NULL)
+	if (hSigner == NULL) {
 		CFails++;
+	}
 
-	if (!COSE_Sign_SetContent(hSign, (byte *)"Message", 7, NULL))
+	if (!COSE_Sign_SetContent(hSign, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Signer_map_put_int(hSigner, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (!COSE_Sign_AddSigner(hSign, hSigner, NULL))
+	}
+	if (!COSE_Sign_AddSigner(hSign, hSigner, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Sign_Sign(hSign, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
-	if (COSE_Sign_GetSigner(hSign, 9, NULL))
+	if (COSE_Sign_GetSigner(hSign, 9, NULL)) {
 		CFails++;
+	}
 	COSE_Sign_Free(hSign);
 	COSE_Signer_Free(hSigner);
 
 	hSign = COSE_Sign_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSign == NULL)
+	if (hSign == NULL) {
 		CFails++;
+	}
 	hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSigner == NULL)
+	if (hSigner == NULL) {
 		CFails++;
+	}
 
-	if (!COSE_Sign_SetContent(hSign, (byte *)"Message", 7, NULL))
+	if (!COSE_Sign_SetContent(hSign, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Signer_map_put_int(hSigner, COSE_Header_Algorithm,
 			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
-	if (!COSE_Sign_AddSigner(hSign, hSigner, NULL))
+	}
+	if (!COSE_Sign_AddSigner(hSign, hSigner, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Sign_Sign(hSign, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
-	if (COSE_Sign_GetSigner(hSign, 9, NULL))
+	if (COSE_Sign_GetSigner(hSign, 9, NULL)) {
 		CFails++;
+	}
 
 	cn = COSE_Signer_map_get_int(
 		hSigner, COSE_Header_Algorithm, COSE_BOTH, &cose_error);
 	if (cn != NULL) {
-		if (cn->type != CN_CBOR_TEXT)
+		if (cn->type != CN_CBOR_TEXT) {
 			CFails++;
-	} else
+		}
+	}
+	else {
 		CFails++;
+	}
 
 	return;
 }
@@ -724,31 +1130,37 @@
 	//  Unsupported algorithm
 
 	hSign = COSE_Sign1_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSign == NULL)
+	if (hSign == NULL) {
 		CFails++;
+	}
 
 	cn = cn_cbor_int_create(15, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (!COSE_Sign1_SetContent(hSign, (byte *)"Message", 7, NULL))
+	if (!COSE_Sign1_SetContent(hSign, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 	if (!COSE_Sign1_map_put_int(hSign, COSE_Header_Algorithm,
 			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Sign1_Sign(hSign, cn, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 	COSE_Sign1_Free(hSign);
 
 	hSign = COSE_Sign1_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (hSign == NULL)
+	if (hSign == NULL) {
 		CFails++;
+	}
 
-	if (!COSE_Sign1_SetContent(hSign, (byte *)"Message", 7, NULL))
+	if (!COSE_Sign1_SetContent(hSign, (byte *)"Message", 7, NULL)) {
 		CFails++;
+	}
 
 	if (!COSE_Sign1_map_put_int(hSign, COSE_Header_Algorithm,
 			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
-			COSE_PROTECT_ONLY, NULL))
+			COSE_PROTECT_ONLY, NULL)) {
 		CFails++;
+	}
 	CHECK_FAILURE(COSE_Sign1_Sign(hSign, cn, &cose_error),
 		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
 
diff --git a/test/test.c b/test/test.c
index 237114d..d2f3c2d 100644
--- a/test/test.c
+++ b/test/test.c
@@ -88,11 +88,10 @@
 
 int MapName(const cn_cbor* p, NameMap* rgMap, unsigned int cMap)
 {
-	unsigned int i;
-
-	for (i = 0; i < cMap; i++) {
-		if (strcmp(rgMap[i].sz, p->v.str) == 0)
+	for (unsigned int i = 0; i < cMap; i++) {
+		if (strcmp(rgMap[i].sz, p->v.str) == 0) {
 			return rgMap[i].i;
+		}
 	}
 
 	assert(false);
@@ -107,12 +106,15 @@
 
 byte fromHex(char c)
 {
-	if (('0' <= c) && (c <= '9'))
+	if (('0' <= c) && (c <= '9')) {
 		return c - '0';
-	if (('A' <= c) && (c <= 'F'))
+	}
+	if (('A' <= c) && (c <= 'F')) {
 		return c - 'A' + 10;
-	if (('a' <= c) && (c <= 'f'))
+	}
+	if (('a' <= c) && (c <= 'f')) {
 		return c - 'a' + 10;
+	}
 	fprintf(stderr, "Invalid hex");
 	exit(1);
 }
@@ -121,9 +123,8 @@
 {
 	byte* pb = malloc(cch / 2);
 	const char* pb2 = rgch;
-	int i;
 
-	for (i = 0; i < cch; i += 2) {
+	for (int i = 0; i < cch; i += 2) {
 		pb[i / 2] = fromHex(pb2[i]) * 16 + fromHex(pb2[i + 1]);
 	}
 
@@ -135,8 +136,9 @@
 	//  Pretend we support any algorithm which is not an integer - this is a
 	//  fail test case
 
-	if ((alg->type != CN_CBOR_INT) && (alg->type != CN_CBOR_UINT))
+	if ((alg->type != CN_CBOR_INT) && (alg->type != CN_CBOR_UINT)) {
 		return true;
+	}
 	switch (alg->v.sint) {
 		default:
 			return false;
@@ -265,13 +267,11 @@
 		case -999:	// Unsupported algorithm for testing.
 			return true;
 	}
-	return true;
 }
 
 byte* GetCBOREncoding(const cn_cbor* pControl, int* pcbEncoded)
 {
 	const cn_cbor* pOutputs = cn_cbor_mapget_string(pControl, "output");
-	const cn_cbor* pCBOR;
 	byte* pb = NULL;
 	const byte* pb2;
 	int i;
@@ -281,7 +281,7 @@
 		exit(1);
 	}
 
-	pCBOR = cn_cbor_mapget_string(pOutputs, "cbor");
+	const cn_cbor* pCBOR = cn_cbor_mapget_string(pOutputs, "cbor");
 	if ((pCBOR == NULL) || (pCBOR->type != CN_CBOR_TEXT)) {
 		fprintf(stderr, "Invalid cbor object");
 		exit(1);
@@ -348,48 +348,60 @@
 			keyNew = COSE_Header_Algorithm;
 			pValueNew = cn_cbor_int_create(
 				MapAlgorithmName(pValue), CBOR_CONTEXT_PARAM_COMMA NULL);
-		} else if (strcmp(pKey->v.str, "ctyp") == 0) {
+		}
+		else if (strcmp(pKey->v.str, "ctyp") == 0) {
 			keyNew = COSE_Header_Content_Type;
 			pValueNew = cn_cbor_clone(pValue, CBOR_CONTEXT_PARAM_COMMA NULL);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-		} else if (strcmp(pKey->v.str, "IV_hex") == 0) {
+			}
+		}
+		else if (strcmp(pKey->v.str, "IV_hex") == 0) {
 			keyNew = COSE_Header_IV;
 			pValueNew =
 				cn_cbor_data_create(FromHex(pValue->v.str, (int)pValue->length),
 					(int)pValue->length / 2, CBOR_CONTEXT_PARAM_COMMA NULL);
-		} else if (strcmp(pKey->v.str, "apu_id") == 0) {
+		}
+		else if (strcmp(pKey->v.str, "apu_id") == 0) {
 			keyNew = COSE_Header_KDF_U_name;
 			pValueNew = cn_cbor_data_create(pValue->v.bytes,
 				(int)pValue->length, CBOR_CONTEXT_PARAM_COMMA NULL);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-
-		} else if (strcmp(pKey->v.str, "apv_id") == 0) {
+			}
+		}
+		else if (strcmp(pKey->v.str, "apv_id") == 0) {
 			keyNew = COSE_Header_KDF_V_name;
 			pValueNew = cn_cbor_data_create(pValue->v.bytes,
 				(int)pValue->length, CBOR_CONTEXT_PARAM_COMMA NULL);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-
-		} else if (strcmp(pKey->v.str, "pub_other") == 0) {
+			}
+		}
+		else if (strcmp(pKey->v.str, "pub_other") == 0) {
 			keyNew = COSE_Header_KDF_PUB_other;
 			pValueNew = cn_cbor_data_create(pValue->v.bytes,
 				(int)pValue->length, CBOR_CONTEXT_PARAM_COMMA NULL);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-		} else if (strcmp(pKey->v.str, "priv_other") == 0) {
+			}
+		}
+		else if (strcmp(pKey->v.str, "priv_other") == 0) {
 			keyNew = COSE_Header_KDF_PRIV;
 			pValueNew = cn_cbor_data_create(pValue->v.bytes,
 				(int)pValue->length, CBOR_CONTEXT_PARAM_COMMA NULL);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-		} else if (strcmp(pKey->v.str, "spk") == 0) {
+			}
+		}
+		else if (strcmp(pKey->v.str, "spk") == 0) {
 			keyNew = COSE_Header_ECDH_STATIC;
 			pValueNew = BuildKey(pValue, fPublicKey);
-			if (pValueNew == NULL)
+			if (pValueNew == NULL) {
 				return false;
-		} else {
+			}
+		}
+		else {
 			continue;
 		}
 
@@ -449,8 +461,20 @@
 					(HCOSE_SIGN1)hHandle, keyNew, pValueNew, which, NULL);
 				break;
 #endif
-				assert(fRet);
+
+#if INCLUDE_COUNTERSIGNATURE
+			case Attributes_Countersign_protected:
+				fRet &= COSE_CounterSign_map_put_int(
+					(HCOSE_COUNTERSIGN)hHandle, keyNew, pValueNew, which, NULL);
+				break;
+#endif
+
+			default:
+				assert(false);
+				break;
 		}
+		//  If you uncomment this then the memory test will fail.
+		// assert(fRet);
 	}
 
 	return fRet;
@@ -461,27 +485,32 @@
 	bool f = false;
 
 	if (!SetAttributes(hMsg, cn_cbor_mapget_string(pIn, "protected"),
-			COSE_PROTECT_ONLY, base, true))
+			COSE_PROTECT_ONLY, base, true)) {
 		goto returnError;
+	}
 	if (!SetAttributes(hMsg, cn_cbor_mapget_string(pIn, "unprotected"),
-			COSE_UNPROTECT_ONLY, base, true))
+			COSE_UNPROTECT_ONLY, base, true)) {
 		goto returnError;
+	}
 	if (!SetAttributes(hMsg, cn_cbor_mapget_string(pIn, "unsent"),
-			COSE_DONT_SEND, base, false))
+			COSE_DONT_SEND, base, false)) {
 		goto returnError;
+	}
 
 	cn_cbor* pExternal = cn_cbor_mapget_string(pIn, "external");
 	if (pExternal != NULL) {
 		cn_cbor* pcn = cn_cbor_clone(pExternal, CBOR_CONTEXT_PARAM_COMMA NULL);
-		if (pcn == NULL)
+		if (pcn == NULL) {
 			goto returnError;
+		}
 		switch (base) {
 #if INCLUDE_ENCRYPT0
 			case Attributes_Encrypt_protected:
 				if (!COSE_Encrypt_SetExternal((HCOSE_ENCRYPT)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -489,8 +518,9 @@
 			case Attributes_Enveloped_protected:
 				if (!COSE_Enveloped_SetExternal((HCOSE_ENVELOPED)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -498,8 +528,9 @@
 			case Attributes_MAC_protected:
 				if (!COSE_Mac_SetExternal((HCOSE_MAC)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -507,8 +538,9 @@
 			case Attributes_MAC0_protected:
 				if (!COSE_Mac0_SetExternal((HCOSE_MAC0)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -516,8 +548,9 @@
 			case Attributes_Signer_protected:
 				if (!COSE_Signer_SetExternal((HCOSE_SIGNER)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -525,10 +558,23 @@
 			case Attributes_Sign1_protected:
 				if (!COSE_Sign1_SetExternal((HCOSE_SIGN1)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
+#if INCLUDE_COUNTERSIGNATURE
+			case Attributes_Countersign_protected:
+				if (!COSE_CounterSign_SetExternal((HCOSE_COUNTERSIGN)hMsg,
+						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
+						NULL)) {
+					goto returnError;
+				}
+				break;
+#endif
+			default:
+				assert(false);
+				break;
 		}
 	}
 
@@ -542,21 +588,24 @@
 	bool f = false;
 
 	if (!SetAttributes(hMsg, cn_cbor_mapget_string(pIn, "unsent"),
-			COSE_DONT_SEND, base, true))
+			COSE_DONT_SEND, base, true)) {
 		goto returnError;
+	}
 
 	cn_cbor* pExternal = cn_cbor_mapget_string(pIn, "external");
 	if (pExternal != NULL) {
 		cn_cbor* pcn = cn_cbor_clone(pExternal, CBOR_CONTEXT_PARAM_COMMA NULL);
-		if (pcn == NULL)
+		if (pcn == NULL) {
 			goto returnError;
+		}
 		switch (base) {
 #if INCLUDE_ENCRYPT0
 			case Attributes_Encrypt_protected:
 				if (!COSE_Encrypt_SetExternal((HCOSE_ENCRYPT)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -564,8 +613,9 @@
 			case Attributes_Enveloped_protected:
 				if (!COSE_Enveloped_SetExternal((HCOSE_ENVELOPED)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -573,8 +623,9 @@
 			case Attributes_MAC_protected:
 				if (!COSE_Mac_SetExternal((HCOSE_MAC)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -582,8 +633,9 @@
 			case Attributes_MAC0_protected:
 				if (!COSE_Mac0_SetExternal((HCOSE_MAC0)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -591,8 +643,9 @@
 			case Attributes_Signer_protected:
 				if (!COSE_Signer_SetExternal((HCOSE_SIGNER)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
 				break;
 #endif
 
@@ -600,8 +653,18 @@
 			case Attributes_Sign1_protected:
 				if (!COSE_Sign1_SetExternal((HCOSE_SIGN1)hMsg,
 						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
-						NULL))
+						NULL)) {
 					goto returnError;
+				}
+				break;
+#endif
+#if INCLUDE_COUNTERSIGNATURE
+			case Attributes_Countersign_protected:
+				if (!COSE_CounterSign_SetExternal((HCOSE_COUNTERSIGN)hMsg,
+						FromHex(pcn->v.str, (int)pcn->length), pcn->length / 2,
+						NULL)) {
+					goto returnError;
+				}
 				break;
 #endif
 		}
@@ -624,31 +687,43 @@
 	unsigned char* pb = NULL;
 	size_t cb;
 
-	if (pKeyOut == NULL)
+	if (pKeyOut == NULL) {
 		return NULL;
+	}
 
-	if ((pKty == NULL) || (pKty->type != CN_CBOR_TEXT))
+	if ((pKty == NULL) || (pKty->type != CN_CBOR_TEXT)) {
 		return NULL;
+	}
 	if (pKty->length == 2) {
-		if (strncmp(pKty->v.str, "EC", 2) == 0)
+		if (strncmp(pKty->v.str, "EC", 2) == 0) {
 			kty = 2;
-		else
+		}
+		else {
 			return NULL;
-	} else if (pKty->length == 3) {
-		if (strncmp(pKty->v.str, "oct", 3) == 0)
+		}
+	}
+	else if (pKty->length == 3) {
+		if (strncmp(pKty->v.str, "oct", 3) == 0) {
 			kty = 4;
-		else if (strncmp(pKty->v.str, "OKP", 3) == 0)
+		}
+		else if (strncmp(pKty->v.str, "OKP", 3) == 0) {
 			kty = COSE_Key_Type_OKP;
-		else
+		}
+		else {
 			return NULL;
-	} else
+		}
+	}
+	else {
 		return NULL;
+	}
 
 	p = cn_cbor_int_create(kty, CBOR_CONTEXT_PARAM_COMMA NULL);
-	if (p == NULL)
+	if (p == NULL) {
 		return NULL;
-	if (!cn_cbor_mapput_int(pKeyOut, 1, p, CBOR_CONTEXT_PARAM_COMMA NULL))
+	}
+	if (!cn_cbor_mapput_int(pKeyOut, 1, p, CBOR_CONTEXT_PARAM_COMMA NULL)) {
 		return NULL;
+	}
 
 	for (pKey = pKeyIn->first_child; pKey != NULL; pKey = pKey->next->next) {
 		pValue = pKey->next;
@@ -665,55 +740,65 @@
 						case OPERATION_NONE:
 							p = cn_cbor_clone(
 								pValue, CBOR_CONTEXT_PARAM_COMMA NULL);
-							if (p == NULL)
+							if (p == NULL) {
 								return NULL;
+							}
 							if (!cn_cbor_mapput_int(pKeyOut,
 									RgStringKeys[i].keyNew, p,
-									CBOR_CONTEXT_PARAM_COMMA NULL))
+									CBOR_CONTEXT_PARAM_COMMA NULL)) {
 								return NULL;
+							}
 							break;
 
 						case OPERATION_BASE64:
-							if ((strcmp(pKey->v.str, "d") == 0) && fPublicKey)
+							if ((strcmp(pKey->v.str, "d") == 0) && fPublicKey) {
 								continue;
+							}
 
 							pb = base64_decode(
 								pValue->v.str, pValue->length, &cb);
 							p = cn_cbor_data_create(
 								pb, (int)cb, CBOR_CONTEXT_PARAM_COMMA NULL);
-							if (p == NULL)
+							if (p == NULL) {
 								return NULL;
+							}
 							if (!cn_cbor_mapput_int(pKeyOut,
 									RgStringKeys[i].keyNew, p,
-									CBOR_CONTEXT_PARAM_COMMA NULL))
+									CBOR_CONTEXT_PARAM_COMMA NULL)) {
 								return NULL;
+							}
 							break;
 
 						case OPERATION_STRING:
 							p = cn_cbor_int_create(MapName(pValue, RgCurveNames,
 													   _countof(RgCurveNames)),
 								CBOR_CONTEXT_PARAM_COMMA NULL);
-							if (p == NULL)
+							if (p == NULL) {
 								return NULL;
+							}
 							if (!cn_cbor_mapput_int(pKeyOut,
 									RgStringKeys[i].keyNew, p,
-									CBOR_CONTEXT_PARAM_COMMA NULL))
+									CBOR_CONTEXT_PARAM_COMMA NULL)) {
 								return NULL;
+							}
 							break;
 
 						case OPERATION_HEX:
 							if ((strcmp(pKey->v.str, "d_hex") == 0) &&
-								fPublicKey)
+								fPublicKey) {
 								continue;
+							}
 							pb = hex_decode(pValue->v.str, pValue->length, &cb);
 							p = cn_cbor_data_create(
 								pb, (int)cb, CBOR_CONTEXT_PARAM_COMMA NULL);
-							if (p == NULL)
+							if (p == NULL) {
 								return NULL;
+							}
 							if (!cn_cbor_mapput_int(pKeyOut,
 									RgStringKeys[i].keyNew, p,
-									CBOR_CONTEXT_PARAM_COMMA NULL))
+									CBOR_CONTEXT_PARAM_COMMA NULL)) {
 								return NULL;
+							}
 							break;
 					}
 					i = 99;
@@ -754,6 +839,8 @@
 	return true;
 }
 
+bool AreListsEmpty();
+
 void RunCorners()
 {
 	Test_cn_cbor_array_replace();
@@ -805,15 +892,20 @@
 	bool fValidateDone = false;
 	bool fBuildDone = false;
 
-	for (iFail = 0; (!fValidateDone || !fBuildDone) && (iFail < 3); iFail++) {
+	for (iFail = 0; (!fValidateDone || !fBuildDone) && (iFail < 100000);
+		 iFail++) {
 		if (cn_cbor_mapget_string(pInput, "mac") != NULL) {
 #if INCLUDE_MAC
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateMAC(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -821,22 +913,31 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildMacMessage(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
 			fValidateDone = true;
 			fBuildDone = true;
 #endif
-		} else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
+		}
+		else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
 #if INCLUDE_MAC0
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateMac0(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -844,22 +945,31 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildMac0Message(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
 			fValidateDone = true;
 			fBuildDone = true;
 #endif
-		} else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
+		}
+		else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
 #if INCLUDE_ENCRYPT0
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateEncrypt(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -867,22 +977,31 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildEncryptMessage(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
 			fValidateDone = true;
 			fBuildDone = true;
 #endif
-		} else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
+		}
+		else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
 #if INCLUDE_ENCRYPT
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateEnveloped(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -890,22 +1009,31 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildEnvelopedMessage(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
 			fValidateDone = true;
 			fBuildDone = true;
 #endif
-		} else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
+		}
+		else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
 #if INCLUDE_SIGN
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateSigned(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -913,22 +1041,31 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildSignedMessage(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
 			fValidateDone = true;
 			fBuildDone = true;
 #endif
-		} else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
+		}
+		else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
 #if INCLUDE_SIGN1
 			if (!fValidateDone) {
 				context = CreateContext(iFail);
 				CFails = 0;
 				ValidateSign1(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fValidateDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 
@@ -936,8 +1073,12 @@
 				context = CreateContext(iFail);
 				CFails = 0;
 				BuildSign1Message(pControl);
-				if (CFails == 0)
+				if (CFails == 0) {
 					fBuildDone = true;
+				}
+				if (IsContextEmpty(context) != 0) {
+					CFails += 1;
+				}
 				FreeContext(context);
 			}
 #else
@@ -953,6 +1094,53 @@
 #endif
 }
 
+typedef int (*ValidatePtr)(const cn_cbor* pControl);
+
+bool ProcessFile(const cn_cbor* pControl,
+	ValidatePtr validateFunction,
+	ValidatePtr buildFunction)
+{
+#ifdef USE_CBOR_CONTEXT
+	context = CreateContext(-1);
+#endif
+	if (validateFunction(pControl)) {
+#ifdef USE_CBOR_CONTEXT
+		if (IsContextEmpty(context) != 0) {
+			printf("Memory Cleanup Failure - Validate\n");
+			// CFails += 1;
+		}
+#endif
+#ifndef NDEBUG
+		if (!AreListsEmpty()) {
+			printf("Left over handle - P1\n");
+			CFails += 1;
+		}
+#endif
+#ifdef USE_CBOR_CONTEXT
+		FreeContext(context);
+		context = CreateContext(-1);
+#endif
+		buildFunction(pControl);
+#ifdef USE_CBOR_CONTEXT
+		if (IsContextEmpty(context) != 0) {
+			printf("Memory Cleanup Failure - Build\n");
+			// CFails += 1;
+		}
+#endif
+	}
+#ifndef NDEBUG
+	if (!AreListsEmpty()) {
+		printf("Left over handle - P2\n");
+		CFails += 1;
+	}
+#endif
+#ifdef USE_CBOR_CONTEXT
+	FreeContext(context);
+	context = NULL;
+#endif
+	return true;
+}
+
 void RunFileTest(const char* szFileName)
 {
 	const cn_cbor* pControl = NULL;
@@ -979,39 +1167,32 @@
 
 	if (cn_cbor_mapget_string(pInput, "mac") != NULL) {
 #if INCLUDE_MAC
-		if (ValidateMAC(pControl)) {
-			BuildMacMessage(pControl);
-		}
+		ProcessFile(pControl, ValidateMAC, BuildMacMessage);
 #endif
-	} else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
+	}
+	else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
 #if INCLUDE_MAC0
-		if (ValidateMac0(pControl)) {
-			BuildMac0Message(pControl);
-		}
+		ProcessFile(pControl, ValidateMac0, BuildMac0Message);
 #endif
-	} else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
+	}
+	else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
 #if INCLUDE_ENCRYPT
-		if (ValidateEnveloped(pControl)) {
-			BuildEnvelopedMessage(pControl);
-		}
+		ProcessFile(pControl, ValidateEnveloped, BuildEnvelopedMessage);
 #endif
-	} else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
+	}
+	else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
 #if INCLUDE_SIGN
-		if (ValidateSigned(pControl)) {
-			BuildSignedMessage(pControl);
-		}
+		ProcessFile(pControl, ValidateSigned, BuildSignedMessage);
 #endif
-	} else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
+	}
+	else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
 #if INCLUDE_SIGN1
-		if (ValidateSign1(pControl)) {
-			BuildSign1Message(pControl);
-		}
+		ProcessFile(pControl, ValidateSign1, BuildSign1Message);
 #endif
-	} else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
+	}
+	else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
 #if INCLUDE_ENCRYPT0
-		if (ValidateEncrypt(pControl)) {
-			BuildEncryptMessage(pControl);
-		}
+		ProcessFile(pControl, ValidateEncrypt, BuildEncryptMessage);
 #endif
 	}
 }
@@ -1121,12 +1302,15 @@
 		if (argv[i][0] == '-') {
 			if (strcmp(argv[i], "--dir") == 0) {
 				fDir = true;
-			} else if (strcmp(argv[i], "--corners") == 0) {
+			}
+			else if (strcmp(argv[i], "--corners") == 0) {
 				fCorners = true;
-			} else if (strcmp(argv[i], "--memory") == 0) {
+			}
+			else if (strcmp(argv[i], "--memory") == 0) {
 				fMemory = true;
 			}
-		} else {
+		}
+		else {
 			szWhere = argv[i];
 		}
 	}
@@ -1146,18 +1330,23 @@
 			exit(1);
 		}
 		RunMemoryTest(szWhere);
-	} else if (szWhere != NULL) {
+	}
+	else if (szWhere != NULL) {
 		if (szWhere == NULL) {
 			fprintf(stderr, "Must specify a file name\n");
 			exit(1);
 		}
-		if (fDir)
+		if (fDir) {
 			RunTestsInDirectory(szWhere);
-		else
+		}
+		else {
 			RunFileTest(szWhere);
-	} else if (fCorners) {
+		}
+	}
+	else if (fCorners) {
 		RunCorners();
-	} else {
+	}
+	else {
 #ifdef USE_CBOR_CONTEXT
 		context = CreateContext((unsigned int)-1);
 #endif
@@ -1175,10 +1364,12 @@
 #endif
 	}
 
-	if (CFails > 0)
+	if (CFails > 0) {
 		fprintf(stderr, "Failed %d tests\n", CFails);
-	else
+	}
+	else {
 		fprintf(stderr, "SUCCESS\n");
+	}
 
 	exit(CFails);
 }
diff --git a/test/test.h b/test/test.h
index 1e0a292..7fefe47 100644
--- a/test/test.h
+++ b/test/test.h
@@ -46,6 +46,7 @@
 //  context.c
 extern cn_cbor_context* CreateContext(unsigned int iFailPoint);
 void FreeContext(cn_cbor_context* pContext);
+int IsContextEmpty(cn_cbor_context* pContext);
 #endif
 
 //  test.c
@@ -58,6 +59,7 @@
 	Attributes_Sign_protected,
 	Attributes_Signer_protected,
 	Attributes_Sign1_protected,
+	Attributes_Countersign_protected
 } whichSet;
 
 extern int CFails;
@@ -88,7 +90,8 @@
 		if (!bReturn) {                                     \
 			if (cose_error.err != errorReturn)              \
 				onFailure;                                  \
-		} else if (errorReturn != COSE_ERR_NONE)            \
+		}                                                   \
+		else if (errorReturn != COSE_ERR_NONE)              \
 			onFailure;                                      \
 	}
 
@@ -98,6 +101,7 @@
 		if (bReturn == NULL) {                                  \
 			if (cose_error.err != errorReturn)                  \
 				onFailure;                                      \
-		} else if (errorReturn != COSE_ERR_NONE)                \
+		}                                                       \
+		else if (errorReturn != COSE_ERR_NONE)                  \
 			onFailure;                                          \
 	}