1 
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 #include "ta_internals.h"
  6 
  7 
  8 
  9 typedef struct TAInvar {
 10   int           is_used;
 11   void          *data;
 12   unsigned int  size;
 13   unsigned char hash[HASH_SIZE];
 14 #ifdef __SANCUS_MSP430
 15 // struct size has to be a power of 2 so that bit shifting instead of
 16 // multiplication is used to address elements of a struct array.
 17 #if   HASH_SIZE ==  8
 18   unsigned char padding[2];
 19 #elif HASH_SIZE == 16
 20   unsigned char padding[10];
 21 #else
 22   #error "Padding undefined."
 23 #endif
 24 #endif
 25 } TAInvar;
 26 
 27 
 28 static TAInvar       SM_DATA(TA_SM_NAME) TAInvars[MAX_INVARS];
 29 
 30 #ifdef __DEBUG
 31 static unsigned char hash_declas[HASH_SIZE];
 32 #endif
 33 
 34 
 35 
 36 static int SM_FUNC(TA_SM_NAME)
 37   TAHash (void *data, unsigned int dsize, unsigned char *hash,
 38     unsigned int hsize)
 39 {
 40   if (data == NULL || dsize < 1 ||
 41       hash == NULL || hsize < HASH_SIZE) {
 42     return (TA_FAILURE);
 43   }
 44   sancus_tag(data, dsize, hash);
 45 
 46   return (TA_SUCCESS);
 47 }
 48 
 49 static int SM_FUNC(TA_SM_NAME)
 50   TACompareHashes (unsigned char *h1, unsigned char *h2)
 51 {
 52   int i;
 53 
 54   for (i = 0; i < HASH_SIZE; i++) {
 55     if (h1[i] != h2[i]) {
 56       return (TA_FAILURE); }
 57   }
 58 
 59   return (TA_SUCCESS);
 60 }
 61 
 62 int SM_FUNC(TA_SM_NAME)
 63   TAInvarInit (void)
 64 {
 65   int i;
 66 
 67   for (i = 0; i < MAX_INVARS; i++) {
 68     TAInvars[i].is_used = 0;
 69   }
 70 
 71   return (TA_SUCCESS);
 72 }
 73 
 74 /*---------------------------------------------------------------------------*/
 75 /* Interface function: TARegisterInvar                                       */
 76 
 77 int SM_ENTRY(TA_SM_NAME) TARegisterInvar (void *data, unsigned int size)
 78 {
 79   int i;
 80 
 81   __TIMING_INIT();
 82 
 83   if (! TAInitialised) {
 84     goto FAIL;
 85   }
 86 
 87   for (i = 0; i < MAX_INVARS; i++) {
 88     if (! TAInvars[i].is_used) {
 89       TAInvars[i].data = data;
 90       TAInvars[i].size = size;
 91       if (TAHash (data, size, TAInvars[i].hash, HASH_SIZE) != TA_SUCCESS)
 92        { return (TA_FAILURE); }
 93       TAInvars[i].is_used = 1;
 94 
 95   __TIMING_PRINT("+++ TARegisterInvar(): ");
 96 
 97 #ifdef __DEBUG
 98       TAmemcpy(hash_declas, TAInvars[i].hash, HASH_SIZE);
 99       char *tmp = TAHashToString(hash_declas);
100       if (tmp != NULL) {
101         printf3("TA: invar @ %p+%u: %s\n",
102           (void *) TAInvars[i].data, (void *) TAInvars[i].size, (void *) tmp);
103         free (tmp);
104       }
105 #endif
106 
107       return (TA_SUCCESS);
108     }
109   }
110 
111 FAIL:
112   puts("*** TA: invar not registered.");
113   return (TA_FAILURE);  return (TA_SUCCESS);
114 }
115 
116 
117 /*---------------------------------------------------------------------------*/
118 /* TACheckInvars                                                             */
119 
120 int SM_FUNC(TA_SM_NAME) TACheckInvars (void)
121 {
122   unsigned char hash[HASH_SIZE];
123   int i, res = TA_SUCCESS;
124 
125   if (! TAInitialised) {
126     return (res);
127   }
128 
129   for (i = 0; i < MAX_INVARS; i++) {
130     if (TAInvars[i].is_used) {
131 #ifdef __DEBUG
132       printf2("TA: checking %p+%u...",
133         (void *) TAInvars[i].data, (void *) TAInvars[i].size);
134 #endif
135       if (TAHash (TAInvars[i].data, TAInvars[i].size, hash, HASH_SIZE)
136           != TA_SUCCESS)
137        {
138 #ifdef __DEBUG
139          puts ("failed.");
140 #endif
141          res = TA_FAILURE;
142          continue; }
143       if (TACompareHashes(hash, TAInvars[i].hash) == TA_SUCCESS) {
144 #ifdef __DEBUG
145         puts ("ok.");
146 #endif
147       } else {
148 #ifdef __DEBUG
149         puts ("failed.");
150 #endif
151         res = TA_FAILURE;
152       }
153     }
154   }
155 
156   return (res);
157 }
158 
159 /*---------------------------------------------------------------------------*/
160 /* TAInvarsStatus                                                            */
161 
162 unsigned char* SM_ENTRY(TA_SM_NAME) TAInvarsStatus (unsigned char *nonce,
163   int nonce_len, int* status_len)
164 {
165   static unsigned char *InvarStatus = NULL;
166   static int sl;
167 
168   __TIMING_INIT();
169 
170   sl = (sizeof(struct TAInvar) * MAX_INVARS) + nonce_len;
171   *status_len = sl + HASH_SIZE;
172   InvarStatus = malloc (*status_len);
173   if (!InvarStatus) { goto FAIL; }
174 
175   sancus_wrap(nonce, nonce_len, TAInvars, *status_len, InvarStatus,
176     InvarStatus + sl);
177 
178   __TIMING_PRINT("+++ TAInvarsStatus(): ");
179   return (InvarStatus);
180 
181 FAIL:
182   *status_len = 0;
183   return (NULL);
184 }
185 
186