Want more features on Pastebin? Sign Up, it's FREE!
Guest

OpenSSL ECDH Objective-C

By: a guest on Apr 17th, 2013  |  syntax: Objective C  |  size: 4.85 KB  |  views: 256  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <openssl/md5.h>
  2. #include <openssl/sha.h>
  3. #include <openssl/opensslv.h>
  4.  
  5. #include <openssl/ssl.h>
  6. #include <openssl/ecdh.h>
  7. #include <openssl/sha.h>
  8. #include <openssl/crypto.h>
  9. #include <openssl/ec.h>
  10. #include <openssl/ecdsa.h>
  11. #include <openssl/ec_lcl.h>
  12. #include <openssl/evp.h>
  13. #include <openssl/aes.h>
  14. #include "RNDecryptor.h"
  15. #include "RNEncryptor.h"
  16. #include "NSData+CommonCrypto.h"
  17. #include "KeychainItemWrapper.h"
  18.  
  19. CryptoHelper *helperInstance = nil;
  20. FILE *f; //Used for printing out BN stuff
  21.  
  22. #define PRIVATE_KEY (__bridge id)kSecAttrAccount
  23. #define PUBLIC_KEY (__bridge id)kSecValueData
  24.  
  25. #define ECDH_SIZE 256
  26.  
  27. static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
  28. {
  29. #ifndef OPENSSL_NO_SHA
  30.     if (*outlen < SHA_DIGEST_LENGTH)
  31.         return NULL;
  32.     else
  33.         *outlen = SHA_DIGEST_LENGTH;
  34.    
  35.     void *sha1 = SHA1(in, inlen, out);
  36.     NSData *data = [[NSData alloc] initWithBytes:(char *)in length:inlen];
  37.     NSLog(@"Encoded :: %@", [data base64EncodedString]);
  38.     out = (void *)in;
  39.     return (void *)inlen;
  40.     return sha1;
  41. #else
  42.     return NULL;
  43. #endif
  44. }
  45.  
  46.  
  47. #pragma mark - Secret Helper Methods!
  48. - (EC_POINT *)getPointFromX:(char *)x andY:(char *)y andGroup:(EC_GROUP *)ec_group
  49. {
  50.     EC_POINT *new_point = EC_POINT_new(ec_group);
  51.    
  52.     BIGNUM *x_coord = BN_new();
  53.     BIGNUM *y_coord = BN_new();
  54.    
  55.     BN_hex2bn(&x_coord, x);
  56.     BN_hex2bn(&y_coord, y);
  57.    
  58.     EC_POINT_set_affine_coordinates_GFp(ec_group, new_point, x_coord, y_coord, NULL);
  59.    
  60.     return new_point;
  61. }
  62.  
  63.  
  64. - (BIGNUM *)bnFromString:(char *)str
  65. {
  66.     BIGNUM *b = BN_new();
  67.     BN_hex2bn(&b, str);
  68.     return b;
  69. }
  70.  
  71. - (void)printBN:(const BIGNUM *)bn withTitle:(char *)title
  72. {
  73.     printf("%s :: ", title);
  74.     BN_print_fp(f, bn);
  75.     printf("\n");
  76. }
  77.  
  78. - (NSData *)computeSharedKey:(EC_POINT *)otherPublicKey andPrivateKey:(EC_KEY *)privateKey
  79. {
  80.     int alen = 0;
  81.     int aout = 0;
  82.     static const int KDF1_SHA1_len = 256;
  83.     unsigned char *abuf = NULL;
  84.    
  85.     alen = KDF1_SHA1_len;
  86.     abuf = (unsigned char *) OPENSSL_malloc (alen);
  87.    
  88.     aout = ECDH_compute_key(abuf, alen, otherPublicKey, privateKey, NULL);
  89.    
  90.     NSData *data = [[NSData alloc] initWithBytes:abuf length:aout];
  91.     NSLog(@"Data : %@", data);
  92.     NSLog(@"Data length : %d", data.length);
  93.     if(abuf)
  94.         free(abuf);
  95.    
  96.     return data;
  97. }
  98.  
  99. - (void)regenerateKeys
  100. {
  101.     self.sharedKey = nil;
  102.     self.privateKey = nil;
  103.     SSL_library_init();
  104.     SSL_load_error_strings();
  105.    
  106.     EC_KEY *ecdh = NULL;
  107.     const EC_GROUP *group = NULL;
  108.    
  109.     OpenSSL_add_all_ciphers();
  110.     OpenSSL_add_all_algorithms();
  111.    
  112.     //Generate Public
  113.     ecdh = EC_KEY_new_by_curve_name(NID_secp256k1);
  114.     EC_KEY_generate_key(ecdh);
  115.     group = EC_KEY_get0_group(ecdh);
  116.    
  117.    
  118.     BIGNUM *x = BN_new();
  119.     BIGNUM *y = BN_new();
  120.    
  121.     EC_POINT_get_affine_coordinates_GFp(group, EC_KEY_get0_public_key(ecdh), x, y, NULL);
  122.    
  123.     char *xString = BN_bn2hex(x);
  124.     char *yString = BN_bn2hex(y);
  125.     char *privateString = BN_bn2hex(EC_KEY_get0_private_key(ecdh));
  126.    
  127.     self.publicX = [[NSString alloc] initWithCString:xString encoding:NSUTF8StringEncoding];
  128.     self.publicY = [[NSString alloc] initWithCString:yString encoding:NSUTF8StringEncoding];
  129.     self.privateKey = [[NSString alloc] initWithCString:privateString encoding:NSUTF8StringEncoding];
  130.  
  131.     [self.keychain setObject:[@{@"publicX" : self.publicX, @"publicY" : self.publicY} description] forKey:PUBLIC_KEY];
  132.     [self.keychain setObject:self.privateKey forKey:PRIVATE_KEY];
  133.    
  134.     NSLog(@"Public X : %@", self.publicX);
  135.     NSLog(@"Public Y : %@", self.publicY);
  136.     NSLog(@"Private Key : %@", self.privateKey);
  137. }
  138.  
  139. - (void)setSharedWithX:(NSString *)x andY:(NSString *)y
  140. {
  141.     const char *xString = [x cStringUsingEncoding:NSUTF8StringEncoding];
  142.     const char *yString = [y cStringUsingEncoding:NSUTF8StringEncoding];
  143.    
  144.     EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp256k1);
  145.    
  146.     const BIGNUM *privatKey = [self bnFromString:(char *)[self.privateKey cStringUsingEncoding:NSUTF8StringEncoding]];
  147.     const EC_POINT *publicKey = [self getPointFromX:(char *)[self.publicX cStringUsingEncoding:NSUTF8StringEncoding] andY:(char *)[self.publicY cStringUsingEncoding:NSUTF8StringEncoding] andGroup:(EC_GROUP *)EC_KEY_get0_group(ecdh)];
  148.    
  149.    
  150.     EC_POINT *otherPublic = [self getPointFromX:(char *)xString andY:(char *)yString andGroup:(EC_GROUP *)EC_KEY_get0_group(ecdh)];
  151.    
  152.     EC_KEY_set_private_key(ecdh, privatKey);
  153.     EC_KEY_set_public_key(ecdh, publicKey);
  154.  
  155.     self.sharedKey = [self computeSharedKey:otherPublic andPrivateKey:ecdh];
  156.  
  157.     NSLog(@"%@", [self.sharedKey base64EncodedString]);
  158.     NSLog(@"shared :: %@", [self.sharedKey base64EncodedString]);
  159. //    EC_POINT_free(otherPublic);
  160.     EC_KEY_free(ecdh);
  161. }
clone this paste RAW Paste Data