Без опису

AWSCognitoIdentityProviderHKDF.m 2.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //
  2. // Copyright 2014-2016 Amazon.com,
  3. // Inc. or its affiliates. All Rights Reserved.
  4. //
  5. // SPDX-License-Identifier: Apache-2.0
  6. //
  7. #import "AWSCognitoIdentityProviderHKDF.h"
  8. #import <CommonCrypto/CommonCrypto.h>
  9. #import <CommonCrypto/CommonKeyDerivation.h>
  10. #import <CommonCrypto/CommonDigest.h>
  11. @interface AWSCognitoIdentityProviderHKDF ()
  12. + (NSData*)extractWithInputKeyingMaterial:(NSData*)ikm salt:(NSData*)salt;
  13. + (NSData*)expand:(NSData*)prk info:(NSData*)info outputLength:(NSUInteger)outputLength;
  14. @end
  15. //https://tools.ietf.org/html/rfc5869
  16. @implementation AWSCognitoIdentityProviderHKDF
  17. + (NSData*)deriveKeyWithInputKeyingMaterial:(NSData*)ikm salt:(NSData*)salt info:(NSData*)info outputLength:(NSUInteger)outputLength {
  18. NSData *prk = [self extractWithInputKeyingMaterial:ikm salt:salt];
  19. return [self expand:prk info:info outputLength:outputLength];
  20. }
  21. + (NSData*)extractWithInputKeyingMaterial:(NSData*)ikm salt:(NSData*)salt {
  22. uint8_t output[CC_SHA256_DIGEST_LENGTH] = {0};
  23. CCHmac(kCCHmacAlgSHA256,
  24. [salt bytes], [salt length],
  25. [ikm bytes], [ikm length],
  26. output);
  27. return [NSData dataWithBytes:output length:CC_SHA256_DIGEST_LENGTH];
  28. }
  29. NSData* calculateT(NSData *prk, NSData *previousT, NSData *info, uint8_t i) {
  30. CCHmacContext ctx;
  31. CCHmacInit(&ctx, kCCHmacAlgSHA256, [prk bytes], [prk length]);
  32. CCHmacUpdate(&ctx, [previousT bytes], [previousT length]);
  33. if (info != nil) {
  34. CCHmacUpdate(&ctx, [info bytes], [info length]);
  35. }
  36. CCHmacUpdate(&ctx, &i, sizeof(uint8_t));
  37. uint8_t output[CC_SHA256_DIGEST_LENGTH];
  38. CCHmacFinal(&ctx, output);
  39. return [NSData dataWithBytes:output length:sizeof(output)];
  40. }
  41. + (NSData*)expand:(NSData*)prk info:(NSData*)info outputLength:(NSUInteger)outputLength {
  42. NSUInteger n = (NSUInteger)ceil((double)outputLength / CC_SHA256_DIGEST_LENGTH);
  43. NSMutableData *outputKeyMaterial = [NSMutableData data];
  44. NSData *previousT = [NSData data];
  45. for (NSUInteger i = 0; i < n; i++) {
  46. NSData *T = calculateT(prk, previousT, info, i+1);
  47. [outputKeyMaterial appendData:T];
  48. previousT = [T copy];
  49. }
  50. return [NSData dataWithData:[outputKeyMaterial subdataWithRange:NSMakeRange(0, outputLength)]];
  51. }
  52. @end