/ lib / tls_record_crypto.c
tls_record_crypto.c
  1  /*
  2   * Copyright (c) 2002,2005-2007,2010-2011 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  /*
 25   * tls_record_crypto.c - actual record layer crypto routines.
 26   */
 27  
 28  /* THIS FILE CONTAINS KERNEL CODE */
 29  
 30  #include "tls_record_internal.h"
 31  #include "sslMemory.h"
 32  #include "sslDebug.h"
 33  #include "sslUtils.h"
 34  
 35  
 36  #include <corecrypto/ccmd5.h>
 37  #include <corecrypto/cchmac.h>
 38  
 39  #include <AssertMacros.h>
 40  #include <string.h>
 41  
 42  // Borrowed from corecrypto - portable versions
 43  #define	STORE32_LE(x, y) do {                                    \
 44  ((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255);		\
 45  ((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255);		\
 46  ((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255);		\
 47  ((unsigned char *)(y))[0] = (unsigned char)((x)&255);			\
 48  } while(0)
 49  
 50  #define	LOAD32_LE(x, y) do {                                     \
 51  x = ((uint32_t)(((const unsigned char *)(y))[3] & 255)<<24) |			    \
 52  ((uint32_t)(((const unsigned char *)(y))[2] & 255)<<16) |			    \
 53  ((uint32_t)(((const unsigned char *)(y))[1] & 255)<<8)  |			    \
 54  ((uint32_t)(((const unsigned char *)(y))[0] & 255));				    \
 55  } while(0)
 56  
 57  #define	STORE32_BE(x, y) do {                                \
 58  ((unsigned char *)(y))[0] = (unsigned char)(((x)>>24)&255);	\
 59  ((unsigned char *)(y))[1] = (unsigned char)(((x)>>16)&255);	\
 60  ((unsigned char *)(y))[2] = (unsigned char)(((x)>>8)&255);	\
 61  ((unsigned char *)(y))[3] = (unsigned char)((x)&255);       \
 62  } while(0)
 63  
 64  #define	LOAD32_BE(x, y) do {                             \
 65  x = ((uint32_t)(((const unsigned char *)(y))[0] & 255)<<24) |	    \
 66  ((uint32_t)(((const unsigned char *)(y))[1] & 255)<<16) |		\
 67  ((uint32_t)(((const unsigned char *)(y))[2] & 255)<<8)  |		\
 68  ((uint32_t)(((const unsigned char *)(y))[3] & 255));          \
 69  } while(0)
 70  
 71  
 72  #define	STORE64_LE(x, y) do {                                    \
 73  ((unsigned char *)(y))[7] = (unsigned char)(((x)>>56)&255);     \
 74  ((unsigned char *)(y))[6] = (unsigned char)(((x)>>48)&255);		\
 75  ((unsigned char *)(y))[5] = (unsigned char)(((x)>>40)&255);		\
 76  ((unsigned char *)(y))[4] = (unsigned char)(((x)>>32)&255);		\
 77  ((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255);		\
 78  ((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255);		\
 79  ((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255);		\
 80  ((unsigned char *)(y))[0] = (unsigned char)((x)&255);			\
 81  } while(0)
 82  
 83  
 84  #define STORE64_BE(x, y) do {                                    \
 85  ((unsigned char *)(y))[0] = (unsigned char)(((x)>>56)&255);		\
 86  ((unsigned char *)(y))[1] = (unsigned char)(((x)>>48)&255);		\
 87  ((unsigned char *)(y))[2] = (unsigned char)(((x)>>40)&255);		\
 88  ((unsigned char *)(y))[3] = (unsigned char)(((x)>>32)&255);		\
 89  ((unsigned char *)(y))[4] = (unsigned char)(((x)>>24)&255);		\
 90  ((unsigned char *)(y))[5] = (unsigned char)(((x)>>16)&255);		\
 91  ((unsigned char *)(y))[6] = (unsigned char)(((x)>>8)&255);		\
 92  ((unsigned char *)(y))[7] = (unsigned char)((x)&255);			\
 93  } while(0)
 94  
 95  #define	LOAD64_BE(x, y) do {                                     \
 96  x = (((uint64_t)(((const unsigned char *)(y))[0] & 255))<<56) |           \
 97  (((uint64_t)(((const unsigned char *)(y))[1] & 255))<<48) |           \
 98  (((uint64_t)(((const unsigned char *)(y))[2] & 255))<<40) |           \
 99  (((uint64_t)(((const unsigned char *)(y))[3] & 255))<<32) |           \
100  (((uint64_t)(((const unsigned char *)(y))[4] & 255))<<24) |           \
101  (((uint64_t)(((const unsigned char *)(y))[5] & 255))<<16) |           \
102  (((uint64_t)(((const unsigned char *)(y))[6] & 255))<<8)  |          	\
103  (((uint64_t)(((const unsigned char *)(y))[7] & 255)));	            \
104  } while(0)
105  
106  
107  uint8_t muxb(bool s, uint8_t a, uint8_t b)
108  {
109      uint8_t cond =~((uint8_t)s-(uint8_t)1);//s?~zero:zero; see above
110      uint8_t rc = (cond&a)|(~cond&b);
111      return rc;
112  }
113  
114  uint32_t mux32(bool s, uint32_t a, uint32_t b)
115  {
116      uint32_t cond =~((uint32_t)s-(uint32_t)1);//s?~zero:zero; see above
117      uint32_t rc = (cond&a)|(~cond&b);
118      return rc;
119  }
120  
121  /* constant time memory extraction - constant for a given len, src_len, dst and src */
122  void mem_extract(uint8_t *dst, const uint8_t *src, size_t offset, size_t dst_len, size_t src_len)
123  {
124      for(size_t i=0; i<=src_len-dst_len; i++) {
125          for(int j=0; j<dst_len; j++) {
126              uint8_t b = src[i+j];
127              uint8_t c = dst[j];
128              dst[j]=muxb(i==offset, b, c);
129          }
130      }
131  }
132  
133  /* SSL3:
134   * MAC = hash( MAC_write_secret + pad_2 +
135   *		       hash( MAC_write_secret + pad_1 + seq_num + type +
136   *			         length + content )
137   *			 )
138   */
139  /* sequence, type, length */
140  #define SSL3_HDR_LENGTH (8 + 1 + 2)
141  
142  
143  /* TLS:
144   * mac = HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
145   *					TLSCompressed.version + TLSCompressed.length +
146   *					TLSCompressed.fragment));
147   */
148  
149  /* sequence, type, version, length */
150  #define TLS_HDR_LENGTH (8 + 1 + 2 + 2)
151  
152  
153  /* common for sslv3 and tlsv1 */
154  /* Constant time no matter the value of padLen */
155  int SSLComputeMac(uint8_t type,
156                    tls_buffer *data,
157                    size_t padLen,
158                    uint8_t *outputMAC,
159                    CipherContext *cipherCtx,
160                    tls_protocol_version pv)
161  {
162      uint8_t *p;
163      unsigned long j;
164      size_t hdr_len;
165      size_t ssl3_mac_pad_len = 40;
166      size_t actual_data_len = data->length - padLen;
167  
168      const struct ccdigest_info *di = cipherCtx->di;
169      size_t blocksize = di->block_size;
170      uint8_t inner_hash[di->output_size];
171  
172      memset(inner_hash, 0, di->output_size);
173  
174      if(pv == tls_protocol_version_SSL_3) {
175          if(di->output_size==CCMD5_OUTPUT_SIZE) {
176              ssl3_mac_pad_len = 48;
177          }
178          hdr_len = di->output_size + ssl3_mac_pad_len + SSL3_HDR_LENGTH; // SSL3
179      } else {
180          hdr_len = blocksize + TLS_HDR_LENGTH; // TLS.
181      }
182      uint8_t hdr[hdr_len];
183      p = hdr;
184  
185  
186      if(pv == tls_protocol_version_SSL_3) {
187          memcpy(p, cipherCtx->macSecret, di->output_size); p += di->output_size;
188          memset(p, 0x36, ssl3_mac_pad_len); p += ssl3_mac_pad_len;
189          p = SSLEncodeUInt64(p, cipherCtx->sequenceNum);
190          *p++ = type;
191          *p++ = actual_data_len >> 8;
192          *p   = actual_data_len & 0xff;
193      } else {
194          memset(p, 0x36, blocksize); //hmac IPAD
195          for(j=0;j<di->output_size;j++) {
196              p[j]=p[j]^cipherCtx->macSecret[j];
197          }
198          p += blocksize;
199          p = SSLEncodeUInt64(p, cipherCtx->sequenceNum);
200          *p++ = type;
201          *p++ = pv >> 8;
202          *p++ = pv & 0xff;
203          *p++ = actual_data_len >> 8;
204          *p   = actual_data_len & 0xff;
205      }
206  
207      uint8_t block[blocksize];
208  
209      unsigned long i;
210      cc_ctx_decl(struct ccdigest_state, di->state_size, inner_state);
211      cc_ctx_decl(struct ccdigest_state, di->state_size, final_inner_state);
212  
213      memcpy(inner_state, di->initial_state, di->state_size);
214      memset(inner_hash, 0, di->output_size);
215  
216  
217      uint64_t actual_bitlen = (hdr_len + actual_data_len) * 8;
218  
219      // Hack to identify MD5 vs SHA1/SHA256 vs SHA384
220      uint8_t hash_bitlen[8] = {0,};
221      size_t hash_bitlenlen;
222      if(di->output_size==16) { // MD5
223          hash_bitlenlen = 8;
224          STORE64_LE(actual_bitlen, hash_bitlen);
225      } else if (di->block_size==128) { //SHA384
226          hash_bitlenlen = 16;
227          STORE64_BE(actual_bitlen, hash_bitlen);
228      } else { //SHA1/SHA256
229          hash_bitlenlen = 8;
230          STORE64_BE(actual_bitlen, hash_bitlen);
231      }
232  
233      //number of blocks to process
234      unsigned long nblocks = (hdr_len + data->length + 1 + hash_bitlenlen - 1)/blocksize + 1;
235      // Offset of the first byte of hash padding.
236      size_t hash_pad_first_byte = hdr_len + actual_data_len;
237      // Actual last block
238      size_t actual_last_block = (hdr_len + actual_data_len + 1 + hash_bitlenlen - 1)/blocksize;
239      size_t hash_pad_last_byte = (actual_last_block+1)*blocksize-1;
240  
241      unsigned long fast_blocks;
242  
243      if(nblocks<6) {
244          fast_blocks = 0;
245      } else {
246          fast_blocks = nblocks - 6;
247      }
248  
249      for(i=0; i<fast_blocks; i++)
250      {
251          size_t k=i*blocksize;
252          if((k+blocksize)<hdr_len) {
253              di->compress(inner_state, 1, hdr+k);
254          } else if (k<hdr_len) {
255              memcpy(block, hdr+k, hdr_len-k);
256              memcpy(block+hdr_len-k, data->data, blocksize-(hdr_len-k));
257              di->compress(inner_state, 1, block);
258          } else {
259              di->compress(inner_state, 1, data->data+(k-hdr_len));
260          }
261      }
262  
263      for(i=fast_blocks;i<nblocks;i++)
264      {
265          for(j=0;j<blocksize;j++)
266          {
267              size_t k = i*blocksize+j;
268              uint8_t b = 0;
269              if(k<hdr_len) {
270                  b=hdr[k];
271              } else {
272                  if((k-hdr_len)<data->length)
273                      b = data->data[k-hdr_len];
274                  b = muxb(k^hash_pad_first_byte, b,  0x80);
275                  b = muxb((k>hash_pad_first_byte) & (k<=hash_pad_last_byte-8), 0x00, b);
276                  if(j>=(blocksize-8))
277                      b = muxb((k>hash_pad_last_byte-8) & ((k<=hash_pad_last_byte)),hash_bitlen[j-(blocksize-8)], b);
278              }
279              block[j]=b;
280          }
281  
282          di->compress(inner_state, 1, block);
283  
284          for(j=0; j<di->state_size/4; j++) {
285              uint32_t h = ccdigest_u32(final_inner_state)[j];
286              h = mux32(i==actual_last_block,ccdigest_u32(inner_state)[j],h);
287              ccdigest_u32(final_inner_state)[j] = h;
288          }
289  
290      }
291  
292      if(di->output_size<=16) { //MD4 or MD5
293          for (unsigned int i = 0; i < di->output_size / 4; i++) {
294              STORE32_LE(ccdigest_u32(final_inner_state)[i], inner_hash+(4*i));
295          }
296      } else if(di->output_size<=32) { // SHA1/SHA224/SHA256
297          for (unsigned int i = 0; i < di->output_size / 4; i++) {
298              STORE32_BE(ccdigest_u32(final_inner_state)[i], inner_hash+(4*i));
299          }
300      } else { //SHA384/512
301          for (unsigned int i = 0; i < di->output_size / 8; i++) {
302              STORE64_BE(ccdigest_u64(final_inner_state)[i], inner_hash+(8*i));
303          }
304      }
305  
306      memset(inner_state, 0, di->state_size);
307  
308      // Final hash with oPAD
309      memset(block, 0x5c, blocksize);
310      ccdigest_di_decl(di, outer);
311      ccdigest_init(di, outer);
312  
313      if(pv == tls_protocol_version_SSL_3) {
314          ccdigest_update(di, outer, di->output_size, cipherCtx->macSecret);
315          ccdigest_update(di, outer, ssl3_mac_pad_len, block);
316      } else {
317          for(j=0;j<di->output_size; j++)
318          {
319              block[j]=block[j]^cipherCtx->macSecret[j];
320          }
321          ccdigest_update(di, outer, blocksize, block);
322      }
323      ccdigest_update(di, outer, di->output_size, inner_hash);
324      ccdigest_final(di, outer, outputMAC);
325  
326      ccdigest_di_clear(di, outer);
327      memset(inner_hash, 0, di->output_size);
328  
329      return 0;
330  }
331  
332  
333  static
334  int SSLVerifyMac(uint8_t type,
335                   tls_buffer *data,
336                   size_t padLen,
337                   uint8_t *compareMAC,
338                   tls_record_t ctx)
339  {
340      int rc;
341      uint8_t outMAC[ctx->readCipher.di->output_size];
342  
343  
344      //    printf("SSLVerifyMac dataLen=%zd, padLen=%zd\n", data->length, padLen);
345      SSLComputeMac(type, data, padLen, outMAC, &ctx->readCipher, ctx->negProtocolVersion);
346  
347  
348      rc = cc_cmp_safe(ctx->readCipher.di->output_size, outMAC, compareMAC);
349  
350  
351  
352      return (~rc)&1; // return 0 for failed, 1 for good.
353  }
354  
355  
356  int SSLDecryptRecord(
357  	uint8_t type,
358  	tls_buffer *payload,
359  	tls_record_t ctx)
360  {
361  	int    err;
362      tls_buffer   content;
363  
364      CipherType cipherType = ctx->readCipher.symCipher->params->cipherType;
365  
366      /* Decrypt in place */
367      switch (cipherType) {
368          case aeadCipherType:
369              if ((err = ctx->readCipher.symCipher->c.aead.decrypt(payload->data+TLS_AES_GCM_EXPLICIT_IV_SIZE,
370                                                                   payload->data+TLS_AES_GCM_EXPLICIT_IV_SIZE,
371                                                                   payload->length-TLS_AES_GCM_EXPLICIT_IV_SIZE,
372                                                                     ctx->readCipher.cipherCtx)) != 0) {
373                  return errSSLRecordDecryptionFail;
374              }
375              content.data = payload->data + TLS_AES_GCM_EXPLICIT_IV_SIZE;
376              content.length = payload->length - (TLS_AES_GCM_EXPLICIT_IV_SIZE+TLS_AES_GCM_TAG_SIZE);
377              /* Test for underflow - if the record size is smaller than required */
378              if(content.length > payload->length) {
379                  return errSSLRecordClosedAbort;
380              }
381              err = 0;
382  
383              break;
384          case blockCipherType:
385  
386              if ((payload->length % ctx->readCipher.symCipher->params->blockSize) != 0)
387                  return errSSLRecordRecordOverflow;
388  
389              if ((err = ctx->readCipher.symCipher->c.cipher.decrypt(payload->data,
390                                                                     payload->data, payload->length,
391                                                                     ctx->readCipher.cipherCtx)) != 0) {
392                  return errSSLRecordDecryptionFail;
393              }
394              /* Remove IV (optional), mac and padlen */
395              if (ctx->negProtocolVersion>=tls_protocol_version_TLS_1_1) {
396                  /* TLS 1.1 and DTLS 1.0 block ciphers */
397                  content.data = payload->data + ctx->readCipher.symCipher->params->blockSize;
398                  content.length = payload->length - (ctx->readCipher.di->output_size + ctx->readCipher.symCipher->params->blockSize + 1)  ;
399              } else {
400                  content.data = payload->data;
401                  content.length = payload->length - (ctx->readCipher.di->output_size + 1) ;
402              }
403              /* Test for underflow - if the record size is smaller than required */
404              if(content.length > payload->length) {
405                  return errSSLRecordClosedAbort;
406              }
407  
408              err = 0;
409              /* for TLSv1, padding can be anywhere from 0 to 255 bytes, all bytes need to be the same value.
410                 for SSLv3, padding can be from 0 to blocksize-1 bytes,  */
411              uint8_t padLen = payload->data[payload->length - 1];
412              size_t maxPadLen;
413              uint8_t good = 1;
414  
415              if(ctx->negProtocolVersion == tls_protocol_version_SSL_3) {
416                  maxPadLen = ctx->readCipher.symCipher->params->blockSize - 1;
417              } else {
418                  maxPadLen = 255;
419              }
420              if(maxPadLen>content.length) maxPadLen = content.length;
421  
422              // check actual padLen is within bound.
423              good &= (padLen <= maxPadLen);
424  
425              padLen = muxb(good, padLen, maxPadLen);
426  
427              if(ctx->negProtocolVersion != tls_protocol_version_SSL_3) {
428                  /* TLS: Need to check all padding bytes */
429                  for(int i=0;i<maxPadLen;i++) {
430                      uint8_t b = payload->data[payload->length - (i+1)];
431                      good &= muxb((b==padLen) | (i>=padLen), 1, 0);
432                  }
433              }
434  
435              /* Verify MAC on payload - Optimize away for null case */
436              if (ctx->readCipher.di->output_size > 0) {
437                  /* Memory access to the MAC is constant time */
438                  uint8_t recordMAC[ctx->readCipher.di->output_size];
439                  memset(recordMAC, 0, ctx->readCipher.di->output_size);
440                  size_t macBufferSize = ctx->readCipher.di->output_size + maxPadLen;
441                  uint8_t *macBuffer = payload->data + payload->length - 1 - macBufferSize;
442                  size_t macOffsetReal = maxPadLen - padLen;
443                  mem_extract(recordMAC, macBuffer, macOffsetReal, sizeof(recordMAC), macBufferSize);
444  
445                  good &= SSLVerifyMac(type, &content, padLen,
446                                       recordMAC, ctx);
447  
448                  content.length -= padLen;
449              }
450  
451              if(!good) {
452                  err = errSSLRecordBadRecordMac;
453              }
454  
455              break;
456  
457          case streamCipherType:
458  
459              if ((err = ctx->readCipher.symCipher->c.cipher.decrypt(payload->data,
460                                                                     payload->data, payload->length,
461                                                                     ctx->readCipher.cipherCtx)) != 0)
462              {
463                  return errSSLRecordDecryptionFail;
464              }
465              content.data = payload->data;
466              content.length = payload->length - ctx->readCipher.di->output_size;
467              /* Test for underflow - if the record size is smaller than required */
468              if(content.length > payload->length) {
469                  return errSSLRecordClosedAbort;
470              }
471  
472              err = 0;
473              /* Verify MAC on payload */
474              if (ctx->readCipher.di->output_size > 0)
475              /* Optimize away MAC for null case */
476              if(!SSLVerifyMac(type, &content, 0, content.data + content.length, ctx))
477              {
478                  err = errSSLRecordBadRecordMac;
479              }
480              break;
481      }
482  
483      *payload = content;     /* Modify payload buffer to indicate content length */
484  
485      return err;
486  }