SOSECWrapUnwrap.c
1 // 2 // cc_CFData.c 3 // ProtectedCloudStorage 4 // 5 // Copyright (c) 2014 Apple Inc. All rights reserved. 6 // 7 8 #include "keychain/SecureObjectSync/SOSInternal.h" 9 10 #include <AssertMacros.h> 11 12 #include <utilities/SecCFWrappers.h> 13 #include <utilities/SecCFError.h> 14 #include <utilities/SecBuffer.h> 15 #import <corecrypto/ccec.h> 16 #import <corecrypto/ccrng.h> 17 18 19 #if 0 && defined(CCEC_RFC6637_DEBUG_KEYS) 20 #define DEBUGKEYS CCEC_RFC6637_DEBUG_KEYS 21 #else 22 #define DEBUGKEYS 0 23 #endif 24 25 const char fingerprint[20] = "fingerprint"; 26 27 const uint8_t kAlgorithmID = 1; 28 29 CFMutableDataRef 30 SOSCopyECWrappedData(ccec_pub_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error) 31 { 32 CFMutableDataRef result = NULL; 33 CFMutableDataRef output = NULL; 34 size_t outputLength; 35 int res; 36 37 require_quiet(SecRequirementError(data != NULL, error, CFSTR("data required for wrapping")), exit); 38 require_quiet(SecRequirementError(ec_ctx != NULL, error, CFSTR("ec pub key required for wrapping")), exit); 39 require_quiet(ec_ctx != NULL, exit); 40 41 outputLength = ccec_rfc6637_wrap_key_size(ec_ctx, CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, CFDataGetLength(data)); 42 43 output = CFDataCreateMutableWithScratch(NULL, outputLength); 44 require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit); 45 46 res = ccec_rfc6637_wrap_key(ec_ctx, CFDataGetMutableBytePtr(output), CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, kAlgorithmID, 47 CFDataGetLength(data), CFDataGetBytePtr(data), &ccec_rfc6637_dh_curve_p256, 48 &ccec_rfc6637_wrap_sha256_kek_aes128, (const uint8_t *)fingerprint, 49 ccrng(NULL)); 50 require_noerr_action(res, exit, SOSErrorCreate(kSOSErrorProcessingFailure, error, NULL, CFSTR("Wrap failed with %d"), res)); 51 52 CFTransferRetained(result, output); 53 54 exit: 55 CFReleaseNull(output); 56 return result; 57 } 58 59 bool SOSPerformWithUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error, 60 void (^operation)(size_t size, uint8_t *buffer)) 61 { 62 __block bool result = false; 63 64 PerformWithBufferAndClear(CFDataGetLength(data), ^(size_t size, uint8_t *buffer) { 65 size_t outputLength = size; 66 int ec_result; 67 uint8_t alg; 68 ec_result = ccec_rfc6637_unwrap_key(ec_ctx, &outputLength, buffer, 69 CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, &alg, &ccec_rfc6637_dh_curve_p256, 70 &ccec_rfc6637_unwrap_sha256_kek_aes128, (const uint8_t *)fingerprint, 71 CFDataGetLength(data), CFDataGetBytePtr(data)); 72 73 require_noerr_action(ec_result, exit, SOSErrorCreate(kSOSErrorProcessingFailure, error, NULL, CFSTR("ccec_rfc6637_unwrap_key failed with %d"), ec_result)); 74 require_quiet(SecRequirementError(alg == kAlgorithmID, error, CFSTR("Unexpected algorithm: %d"), (int)alg), exit); 75 76 operation(outputLength, buffer); 77 78 result = true; 79 exit: 80 ; 81 }); 82 83 return result; 84 } 85 86 CFMutableDataRef 87 SOSCopyECUnwrappedData(ccec_full_ctx_t ec_ctx, CFDataRef data, CFErrorRef *error) 88 { 89 uint8_t alg; 90 CFMutableDataRef result = NULL; 91 CFMutableDataRef output = NULL; 92 size_t outputLength = CFDataGetLength(data); 93 int res; 94 95 output = CFDataCreateMutableWithScratch(NULL, outputLength); 96 require_quiet(SecAllocationError(output, error, CFSTR("%s CFData allocation failed"), __FUNCTION__), exit); 97 98 res = ccec_rfc6637_unwrap_key(ec_ctx, &outputLength, CFDataGetMutableBytePtr(output), 99 CCEC_RFC6637_COMPACT_KEYS | DEBUGKEYS, &alg, &ccec_rfc6637_dh_curve_p256, 100 &ccec_rfc6637_unwrap_sha256_kek_aes128, (const uint8_t *)fingerprint, 101 CFDataGetLength(data), CFDataGetBytePtr(data)); 102 require_noerr_action(res, exit, SOSErrorCreate(kSOSErrorProcessingFailure, error, NULL, CFSTR("Unwrap failed with %d"), res)); 103 require_quiet(SecRequirementError(alg == kAlgorithmID, error, CFSTR("Unexpected algorithm: %d"), (int)alg), exit); 104 105 CFDataSetLength(output, outputLength); 106 107 CFTransferRetained(result, output); 108 109 exit: 110 CFReleaseNull(output); 111 return result; 112 }