- Upgrade to 1.0
This commit is contained in:
1 parent
4e66c377fd
commit
0c2b3f1c25
452 files changed
+33888
-16806
No files matched your search
Generated
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Gabriel Handford
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// NAAEAD.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NAAEAD : NSObject
|
||||
|
||||
@property (getter=isSecureDataEnabled) BOOL secureDataEnabled;
|
||||
|
||||
- (NSData *)encryptChaCha20Poly1305:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key additionalData:(NSData *)additionalData error:(NSError **)error;
|
||||
|
||||
- (NSData *)decryptChaCha20Poly1305:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key additionalData:(NSData *)additionalData error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// NAAEAD.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAAEAD.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
#import "NASecureData.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NAAEAD
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)encryptChaCha20Poly1305:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key additionalData:(NSData *)additionalData error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NAAEADNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!additionalData) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidAdditionalData, @"Invalid additional data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!key || [key length] != NAAEADKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:[data length] + NAAEADASize];
|
||||
|
||||
unsigned long long outLength;
|
||||
int retval = crypto_aead_chacha20poly1305_encrypt([outData mutableBytes], &outLength,
|
||||
[data bytes], [data length],
|
||||
[additionalData bytes], [additionalData length],
|
||||
NULL,
|
||||
[nonce bytes],
|
||||
[key bytes]);
|
||||
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"AEAD encrypt failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
- (NSData *)decryptChaCha20Poly1305:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key additionalData:(NSData *)additionalData error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NAAEADNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!additionalData) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidAdditionalData, @"Invalid additional data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!key || [key length] != NAAEADKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block unsigned long long outLength;
|
||||
__block int retval = -1;
|
||||
NSMutableData *outData = NAData(self.secureDataEnabled, data.length, ^(void *bytes, NSUInteger length) {
|
||||
retval = crypto_aead_chacha20poly1305_decrypt(bytes, &outLength,
|
||||
NULL,
|
||||
[data bytes], [data length],
|
||||
[additionalData bytes], [additionalData length],
|
||||
[nonce bytes],
|
||||
[key bytes]);
|
||||
});
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeVerificationFailed, @"Verification failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [outData na_truncate:outData.length - (NSUInteger)outLength];
|
||||
}
|
||||
|
||||
@end
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// NAAuth.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/16/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*!
|
||||
Computes an authentication tag for a message and a secret key, and provides a way to verify that a given tag is valid for a given message and a key.
|
||||
*/
|
||||
@interface NAAuth : NSObject
|
||||
|
||||
- (NSData *)auth:(NSData *)data key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
/*!
|
||||
Returns YES if verifies OK.
|
||||
*/
|
||||
- (BOOL)verify:(NSData *)auth data:(NSData *)data key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
|
||||
@end
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// NAAuth.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/16/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAAuth.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NAAuth
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)auth:(NSData *)data key:(NSData *)key error:(NSError **)error {
|
||||
if (!key || [key length] != NAAuthKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:NAAuthSize];
|
||||
|
||||
crypto_auth([outData mutableBytes], [data bytes], [data length], [key bytes]);
|
||||
return outData;
|
||||
}
|
||||
|
||||
- (BOOL)verify:(NSData *)auth data:(NSData *)data key:(NSData *)key error:(NSError **)error {
|
||||
if (!key || [key length] != NAAuthKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!auth || [auth length] != NAAuthSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (crypto_auth_verify([auth bytes], [data bytes], [data length], [key bytes]) != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeVerificationFailed, @"Verification failed");
|
||||
return NO; // Message forged!
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// NABox.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "NABoxKeypair.h"
|
||||
|
||||
@interface NABox : NSObject
|
||||
|
||||
@property (getter=isSecureDataEnabled) BOOL secureDataEnabled;
|
||||
|
||||
- (NSData *)encrypt:(NSData *)data nonce:(NSData *)nonce keypair:(NABoxKeypair *)keypair error:(NSError **)error;
|
||||
|
||||
- (NSData *)decrypt:(NSData *)data nonce:(NSData *)nonce keypair:(NABoxKeypair *)keypair error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// NABox.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NABox.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NABox
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)encrypt:(NSData *)data nonce:(NSData *)nonce keypair:(NABoxKeypair *)keypair error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NABoxNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!keypair) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid keypair");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:[data length] + NABoxMACSize];
|
||||
|
||||
int retval = crypto_box_easy([outData mutableBytes],
|
||||
[data bytes], [data length],
|
||||
[nonce bytes],
|
||||
[keypair.publicKey bytes],
|
||||
[keypair.secretKey bytes]);
|
||||
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Encrypt (box) failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
- (NSData *)decrypt:(NSData *)data nonce:(NSData *)nonce keypair:(NABoxKeypair *)keypair error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NABoxNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block int retval = -1;
|
||||
NSMutableData *outData = NAData(self.secureDataEnabled, data.length, ^(void *bytes, NSUInteger length) {
|
||||
retval = crypto_box_open_easy(bytes,
|
||||
[data bytes], [data length],
|
||||
[nonce bytes],
|
||||
[keypair.publicKey bytes],
|
||||
[keypair.secretKey bytes]);
|
||||
});
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeVerificationFailed, @"Verification failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [outData na_truncate:NABoxMACSize];
|
||||
}
|
||||
|
||||
@end
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// NABoxKeypair.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "NASecureData.h"
|
||||
|
||||
@interface NABoxKeypair : NSObject
|
||||
|
||||
@property (readonly) NSData *publicKey;
|
||||
@property (readonly) NASecureData *secretKey;
|
||||
|
||||
- (instancetype)initWithPublicKey:(NSData *)publicKey secretKey:(NASecureData *)secretKey error:(NSError **)error;
|
||||
|
||||
+ (instancetype)generate:(NSError **)error;
|
||||
|
||||
@end
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// NABoxKeypair.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NABoxKeypair.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
#import "NASecureData.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@interface NABoxKeypair ()
|
||||
@property NSData *publicKey;
|
||||
@property NASecureData *secretKey;
|
||||
@end
|
||||
|
||||
@implementation NABoxKeypair
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (instancetype)initWithPublicKey:(NSData *)publicKey secretKey:(NASecureData *)secretKey error:(NSError **)error {
|
||||
if ((self = [super init])) {
|
||||
|
||||
if (!publicKey || [publicKey length] != NABoxPublicKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid public key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!secretKey || [secretKey length] != NABoxPublicKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid secret key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
_publicKey = publicKey;
|
||||
_secretKey = secretKey;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)generate:(NSError **)error {
|
||||
NSMutableData *publicKey = [NSMutableData dataWithLength:NABoxPublicKeySize];
|
||||
__block int retval = -1;
|
||||
NASecureData *secretKey = [NASecureData secureReadOnlyDataWithLength:NABoxSecretKeySize completion:^(void *bytes, NSUInteger length) {
|
||||
retval = crypto_box_keypair([publicKey mutableBytes], bytes);
|
||||
}];
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Keypair generate failed");
|
||||
return nil;
|
||||
}
|
||||
return [[NABoxKeypair alloc] initWithPublicKey:publicKey secretKey:secretKey error:error];
|
||||
}
|
||||
|
||||
@end
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// NAChloride.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel Handford on 1/16/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for NAChloride.
|
||||
FOUNDATION_EXPORT double NAChlorideVersionNumber;
|
||||
|
||||
//! Project version string for NAChloride.
|
||||
FOUNDATION_EXPORT const unsigned char NAChlorideVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <NAChloride/PublicHeader.h>
|
||||
|
||||
#import <NAChloride/NAInterface.h>
|
||||
|
||||
#import <NAChloride/NASecretBox.h>
|
||||
#import <NAChloride/NABox.h>
|
||||
#import <NAChloride/NABoxKeypair.h>
|
||||
#import <NAChloride/NAAuth.h>
|
||||
#import <NAChloride/NAAEAD.h>
|
||||
#import <NAChloride/NAOneTimeAuth.h>
|
||||
#import <NAChloride/NAScrypt.h>
|
||||
#import <NAChloride/NAStream.h>
|
||||
#import <NAChloride/NARandom.h>
|
||||
#import <NAChloride/NASecureData.h>
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// NAInterface.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/25/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM (NSInteger, NAErrorCode) {
|
||||
NAErrorCodeFailure = 1, // Generic failure
|
||||
|
||||
NAErrorCodeInvalidNonce = 100,
|
||||
NAErrorCodeInvalidKey = 101,
|
||||
NAErrorCodeInvalidData = 102,
|
||||
NAErrorCodeInvalidSalt = 103,
|
||||
NAErrorCodeInvalidAdditionalData = 104, // For AEAD
|
||||
|
||||
NAErrorCodeVerificationFailed = 205, // Verification failed
|
||||
};
|
||||
|
||||
extern const size_t NASecretBoxKeySize;
|
||||
extern const size_t NASecretBoxNonceSize;
|
||||
extern const size_t NASecretBoxMACSize;
|
||||
|
||||
extern const size_t NABoxPublicKeySize;
|
||||
extern const size_t NABoxSecretKeySize;
|
||||
extern const size_t NABoxNonceSize;
|
||||
extern const size_t NABoxMACSize;
|
||||
|
||||
extern const size_t NAAuthKeySize;
|
||||
extern const size_t NAAuthSize;
|
||||
|
||||
extern const size_t NAOneTimeAuthKeySize;
|
||||
extern const size_t NAOneTimeAuthSize;
|
||||
|
||||
extern const size_t NAScryptSaltSize;
|
||||
|
||||
extern const size_t NAStreamKeySize;
|
||||
extern const size_t NAStreamNonceSize;
|
||||
|
||||
extern const size_t NAXSalsaKeySize;
|
||||
extern const size_t NAXSalsaNonceSize;
|
||||
|
||||
extern const size_t NAAEADKeySize;
|
||||
extern const size_t NAAEADNonceSize;
|
||||
extern const size_t NAAEADASize;
|
||||
|
||||
|
||||
// Thread safe libsodium init
|
||||
void NAChlorideInit(void);
|
||||
|
||||
// Don't call this directly (use NAChlorideInit). This is made accessible for testing.
|
||||
int NASodiumInit(void);
|
||||
|
||||
|
||||
typedef id (^NAWork)(NSError **error);
|
||||
typedef void (^NACompletion)(NSError *error, id output);
|
||||
void NADispatch(dispatch_queue_t queue, NAWork work, NACompletion completion);
|
||||
|
||||
#define NAError(CODE, DESC) [NSError errorWithDomain:@"NAChloride" code:CODE userInfo:@{NSLocalizedDescriptionKey: DESC}];
|
||||
|
||||
typedef void (^NADataCompletion)(void *bytes, NSUInteger length);
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// NAInterface.m
|
||||
// NACL
|
||||
//
|
||||
// Created by Gabriel Handford on 1/16/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
const size_t NASecretBoxKeySize = crypto_secretbox_KEYBYTES;
|
||||
const size_t NASecretBoxNonceSize = crypto_secretbox_NONCEBYTES;
|
||||
const size_t NASecretBoxMACSize = crypto_secretbox_MACBYTES;
|
||||
|
||||
const size_t NABoxPublicKeySize = crypto_box_PUBLICKEYBYTES;
|
||||
const size_t NABoxSecretKeySize = crypto_box_SECRETKEYBYTES;
|
||||
const size_t NABoxNonceSize = crypto_box_NONCEBYTES;
|
||||
const size_t NABoxMACSize = crypto_box_MACBYTES;
|
||||
|
||||
const size_t NAAuthKeySize = crypto_auth_KEYBYTES;
|
||||
const size_t NAAuthSize = crypto_auth_BYTES;
|
||||
|
||||
const size_t NAOneTimeAuthKeySize = crypto_onetimeauth_KEYBYTES;
|
||||
const size_t NAOneTimeAuthSize = crypto_onetimeauth_BYTES;
|
||||
|
||||
const size_t NAScryptSaltSize = crypto_pwhash_scryptsalsa208sha256_SALTBYTES;
|
||||
|
||||
const size_t NAStreamKeySize = crypto_stream_KEYBYTES;
|
||||
const size_t NAStreamNonceSize = crypto_stream_NONCEBYTES;
|
||||
|
||||
const size_t NAXSalsaKeySize = crypto_stream_xsalsa20_KEYBYTES;
|
||||
const size_t NAXSalsaNonceSize = crypto_stream_xsalsa20_NONCEBYTES;
|
||||
|
||||
const size_t NAAEADKeySize = crypto_aead_chacha20poly1305_KEYBYTES;
|
||||
const size_t NAAEADNonceSize = crypto_aead_chacha20poly1305_NPUBBYTES;
|
||||
const size_t NAAEADASize = crypto_aead_chacha20poly1305_ABYTES;
|
||||
|
||||
|
||||
void NAChlorideInit(void) {
|
||||
static dispatch_once_t sodiumInit;
|
||||
dispatch_once(&sodiumInit, ^{ NASodiumInit(); });
|
||||
}
|
||||
|
||||
int NASodiumInit(void) {
|
||||
return sodium_init();
|
||||
}
|
||||
|
||||
void NADispatch(dispatch_queue_t queue, NAWork work, NACompletion completion) {
|
||||
dispatch_async(queue, ^{
|
||||
|
||||
NSError *error = nil;
|
||||
id output = work(&error);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(error, output);
|
||||
});
|
||||
});
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// NAOneTimeAuth.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 9/24/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*!
|
||||
Generates a MAC for a given message and shared key using Poly1305 algorithm
|
||||
(key may NOT be reused across messages).
|
||||
*/
|
||||
@interface NAOneTimeAuth : NSObject
|
||||
|
||||
- (NSData *)auth:(NSData *)data key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
/*!
|
||||
Returns YES if verifies OK.
|
||||
*/
|
||||
- (BOOL)verify:(NSData *)auth data:(NSData *)data key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// NAOneTimeAuth.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 9/24/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAOneTimeAuth.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NAOneTimeAuth
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)auth:(NSData *)data key:(NSData *)key error:(NSError **)error {
|
||||
if (!key || [key length] != NAOneTimeAuthKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:NAOneTimeAuthSize];
|
||||
|
||||
crypto_onetimeauth([outData mutableBytes], [data bytes], [data length], [key bytes]);
|
||||
return outData;
|
||||
}
|
||||
|
||||
- (BOOL)verify:(NSData *)auth data:(NSData *)data key:(NSData *)key error:(NSError **)error {
|
||||
if (!key || [key length] != NAOneTimeAuthKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!auth || [auth length] != NAOneTimeAuthSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (crypto_onetimeauth_verify([auth bytes], [data bytes], [data length], [key bytes]) != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeVerificationFailed, @"Verification failed");
|
||||
return NO; // Message forged!
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// NARandom.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/16/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "NASecureData.h"
|
||||
|
||||
@interface NARandom : NSObject
|
||||
|
||||
/*!
|
||||
Random data of length bytes.
|
||||
*/
|
||||
+ (NSData *)randomData:(NSUInteger)length;
|
||||
|
||||
/*!
|
||||
Random & secure data of length bytes.
|
||||
*/
|
||||
+ (NASecureData *)randomSecureReadOnlyData:(NSUInteger)length;
|
||||
|
||||
@end
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// NARandom.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/16/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NARandom.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NARandom
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
+ (NSData *)randomData:(NSUInteger)length {
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:length];
|
||||
randombytes_buf([outData mutableBytes], length);
|
||||
return outData;
|
||||
}
|
||||
|
||||
+ (NASecureData *)randomSecureReadOnlyData:(NSUInteger)length {
|
||||
NASecureData *secureData = [NASecureData secureReadOnlyDataWithLength:length completion:^(void *bytes, NSUInteger length) {
|
||||
randombytes_buf(bytes, length);
|
||||
}];
|
||||
return secureData;
|
||||
}
|
||||
|
||||
@end
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// NAScrypt.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/19/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NAScrypt : NSObject
|
||||
|
||||
/*!
|
||||
Key derivation.
|
||||
|
||||
@param password Password
|
||||
@param salt Must be NAScryptSaltSize
|
||||
|
||||
Default opslimit is crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE.
|
||||
Default memlimit is crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE.
|
||||
*/
|
||||
+ (NSData *)scrypt:(NSData *)password salt:(NSData *)salt error:(NSError **)error;
|
||||
|
||||
/*!
|
||||
Use the default scrypt. This is for advanced use only.
|
||||
*/
|
||||
+ (NSData *)scrypt:(NSData *)password salt:(NSData *)salt N:(uint64_t)N r:(uint32_t)r p:(uint32_t)p length:(size_t)length error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// NAScrypt.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/19/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAScrypt.h"
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NAScrypt
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
+ (NSData *)scrypt:(NSData *)password salt:(NSData *)salt error:(NSError **)error {
|
||||
if (!salt || [salt length] != NAScryptSaltSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidSalt, @"Invalid salt")
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *key = [NSMutableData dataWithLength:crypto_box_SEEDBYTES];
|
||||
|
||||
int retval = crypto_pwhash_scryptsalsa208sha256([key mutableBytes], key.length, password.bytes, password.length, salt.bytes, crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);
|
||||
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Scrypt failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
+ (NSData *)scrypt:(NSData *)password salt:(NSData *)salt N:(uint64_t)N r:(uint32_t)r p:(uint32_t)p length:(size_t)length error:(NSError **)error {
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:length];
|
||||
|
||||
int retval = crypto_pwhash_scryptsalsa208sha256_ll((uint8_t *)password.bytes, password.length, (uint8_t *)salt.bytes, salt.length, N, r, p, [outData mutableBytes], outData.length);
|
||||
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Scrypt failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSAssert([outData length] == length, @"Mismatched output length");
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
@end
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// NASecretBox.h
|
||||
// NACL
|
||||
//
|
||||
// Created by Gabriel Handford on 1/16/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*!
|
||||
Encrypts and authenticates a message using a shared key and nonce.
|
||||
*/
|
||||
@interface NASecretBox : NSObject
|
||||
|
||||
@property (getter=isSecureDataEnabled) BOOL secureDataEnabled;
|
||||
|
||||
- (NSData *)encrypt:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
- (NSData *)decrypt:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// NASecretBox.m
|
||||
// NACL
|
||||
//
|
||||
// Created by Gabriel Handford on 1/16/14.
|
||||
// Copyright (c) 2014 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NASecretBox.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
#import "NASecureData.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NASecretBox
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)encrypt:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NASecretBoxNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!key || [key length] != NASecretBoxKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Add space for authentication tag of size MACBYTES
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:[data length] + NASecretBoxMACSize];
|
||||
|
||||
int retval = crypto_secretbox_easy([outData mutableBytes],
|
||||
[data bytes], [data length],
|
||||
[nonce bytes],
|
||||
[key bytes]);
|
||||
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Encrypt (secret box) failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
- (NSData *)decrypt:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error {
|
||||
if (!nonce || [nonce length] != NASecretBoxNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidData, @"Invalid data");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!key || [key length] != NASecretBoxKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block int retval = -1;
|
||||
NSMutableData *outData = NAData(self.secureDataEnabled, data.length, ^(void *bytes, NSUInteger length) {
|
||||
retval = crypto_secretbox_open_easy(bytes,
|
||||
[data bytes], [data length],
|
||||
[nonce bytes], [key bytes]);
|
||||
});
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeVerificationFailed, @"Verification failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Remove MAC bytes from data
|
||||
return [outData na_truncate:NASecretBoxMACSize];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// NASecureData.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/19/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
typedef NS_ENUM (NSInteger, NASecureDataProtection) {
|
||||
NASecureDataProtectionReadWrite = 0, // Default no protection
|
||||
NASecureDataProtectionReadOnly,
|
||||
NASecureDataProtectionNoAccess,
|
||||
};
|
||||
|
||||
/*!
|
||||
Secure memory using libsodium.
|
||||
*/
|
||||
@interface NASecureData : NSMutableData // Subclassing for convienience
|
||||
|
||||
@property (nonatomic) NASecureDataProtection protection;
|
||||
|
||||
/*!
|
||||
Secure and read only data.
|
||||
*/
|
||||
+ (instancetype)secureReadOnlyDataWithLength:(NSUInteger)length completion:(NADataCompletion)completion;
|
||||
|
||||
/*!
|
||||
Secure data is has read/write protection in this block.
|
||||
*/
|
||||
- (void)readWrite:(void (^)(NASecureData *secureData))completion;
|
||||
|
||||
/*!
|
||||
Truncate.
|
||||
*/
|
||||
- (NASecureData *)truncate:(NSUInteger)length;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Optional building of secure NSData
|
||||
NSMutableData *NAData(BOOL secure, NSUInteger length, NADataCompletion completion);
|
||||
|
||||
|
||||
@interface NSMutableData (NASecureData)
|
||||
|
||||
- (NSData *)na_truncate:(NSUInteger)length;
|
||||
|
||||
@end
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// NASecureData.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/19/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NASecureData.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@interface NASecureData ()
|
||||
@property void *secureBytes;
|
||||
@property NSUInteger secureLength;
|
||||
@end
|
||||
|
||||
@implementation NASecureData
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (instancetype)initWithLength:(NSUInteger)length {
|
||||
if ((self = [super init])) {
|
||||
NAChlorideInit(); // It's already init'ed, but just to be safe
|
||||
_secureLength = length;
|
||||
_secureBytes = sodium_malloc(length);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)secureReadOnlyDataWithLength:(NSUInteger)length completion:(NADataCompletion)completion {
|
||||
NASecureData *secureData = [[NASecureData alloc] initWithLength:length];
|
||||
completion(secureData.secureBytes, secureData.length);
|
||||
secureData.protection = NASecureDataProtectionReadOnly;
|
||||
return secureData;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
sodium_free(_secureBytes);
|
||||
}
|
||||
|
||||
- (void)setProtection:(NASecureDataProtection)protection {
|
||||
switch (protection) {
|
||||
// Keep these case statements order from most secure to least secure in case some jerk removes a break;
|
||||
case NASecureDataProtectionReadWrite: sodium_mprotect_readwrite(_secureBytes); break;
|
||||
case NASecureDataProtectionReadOnly: sodium_mprotect_readonly(_secureBytes); break;
|
||||
case NASecureDataProtectionNoAccess: sodium_mprotect_noaccess(_secureBytes); break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)length {
|
||||
return _secureLength;
|
||||
}
|
||||
|
||||
- (const void *)bytes {
|
||||
return _secureBytes;
|
||||
}
|
||||
|
||||
- (void *)mutableBytes {
|
||||
return _secureBytes;
|
||||
}
|
||||
|
||||
- (void)readWrite:(void (^)(NASecureData *secureData))completion {
|
||||
NASecureDataProtection protection = self.protection;
|
||||
self.protection = NASecureDataProtectionReadWrite;
|
||||
completion(self);
|
||||
self.protection = protection;
|
||||
}
|
||||
|
||||
- (NASecureData *)truncate:(NSUInteger)length {
|
||||
if (length == 0) return self;
|
||||
return [NASecureData secureReadOnlyDataWithLength:(self.length - length) completion:^(void *bytes, NSUInteger length) {
|
||||
memcpy(bytes, self.bytes, length);
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSData *)na_truncate:(NSUInteger)length { return [self truncate:length]; }
|
||||
|
||||
@end
|
||||
|
||||
NSMutableData *NAData(BOOL secure, NSUInteger length, NADataCompletion completion) {
|
||||
if (!secure) {
|
||||
NSMutableData *data = [NSMutableData dataWithLength:length];
|
||||
completion([data mutableBytes], length);
|
||||
return data;
|
||||
} else {
|
||||
return [NASecureData secureReadOnlyDataWithLength:length completion:completion];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation NSMutableData (NASecureData)
|
||||
|
||||
- (NSData *)na_truncate:(NSUInteger)length {
|
||||
if (length == 0) return self;
|
||||
return [NSData dataWithBytes:self.bytes length:self.length - length];
|
||||
}
|
||||
|
||||
@end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// NAStream.h
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NAStream : NSObject
|
||||
|
||||
- (NSData *)xor:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error;
|
||||
|
||||
@end
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// NAStream.m
|
||||
// NAChloride
|
||||
//
|
||||
// Created by Gabriel on 6/18/15.
|
||||
// Copyright (c) 2015 Gabriel Handford. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NAStream.h"
|
||||
|
||||
#import "NAInterface.h"
|
||||
|
||||
#import "sodium.h"
|
||||
|
||||
@implementation NAStream
|
||||
|
||||
+ (void)initialize { NAChlorideInit(); }
|
||||
|
||||
- (NSData *)xor:(NSData *)data nonce:(NSData *)nonce key:(NSData *)key error:(NSError **)error {
|
||||
if (!nonce || [nonce length] < NAStreamNonceSize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidNonce, @"Invalid stream nonce");
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!key || [key length] != NAStreamKeySize) {
|
||||
if (error) *error = NAError(NAErrorCodeInvalidKey, @"Invalid stream key");
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [NSMutableData dataWithLength:[data length]];
|
||||
|
||||
int retval = crypto_stream_xor([outData mutableBytes], [data bytes], [data length], [nonce bytes], [key bytes]);
|
||||
if (retval != 0) {
|
||||
if (error) *error = NAError(NAErrorCodeFailure, @"Stream failed");
|
||||
return nil;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+189
@@ -0,0 +1,189 @@
|
||||
NAChloride
|
||||
===========
|
||||
|
||||
This project wraps [libsodium](https://github.com/jedisct1/libsodium) for:
|
||||
|
||||
* Secure Memory
|
||||
* Random Data
|
||||
* Secret-Key
|
||||
* Authenticated Encryption
|
||||
* Authentication
|
||||
* AEAD
|
||||
* Public-Key
|
||||
* Authenticated Encryption
|
||||
* One-Time Authentication
|
||||
* Password Hashing: *Scrypt*
|
||||
* Stream Ciphers: *XSalsa20*
|
||||
|
||||
More wrappers are coming soon.
|
||||
|
||||
Do you want to work on crypto at Keybase? [We're hiring](https://keybase.io/jobs).
|
||||
|
||||
If you are looking for other non-libsodium related crypto (that used to be here), see [NACrypto](https://github.com/gabriel/NACrypto).
|
||||
|
||||
# Podfile
|
||||
|
||||
```ruby
|
||||
pod "NAChloride"
|
||||
```
|
||||
|
||||
# Init
|
||||
|
||||
You should call `NAChlorideInit()` to initialize on app start. It is thread safe and multiple calls are ignored. We automatically call this as well as a safety measure.
|
||||
|
||||
```objc
|
||||
NAChlorideInit();
|
||||
```
|
||||
|
||||
# Secure Memory
|
||||
|
||||
See [Securing Memory Allocations](https://download.libsodium.org/doc/helpers/memory_management.html).
|
||||
|
||||
```objc
|
||||
NASecureData *secureData = [NASecureData secureReadOnlyDataWithLength:length completion:^(void *bytes, NSUInteger length) {
|
||||
// Set the bytes here. After this it will be read-only.
|
||||
}];
|
||||
|
||||
// After the block executes, secureData is read-only. You can set it to no access (or read/write).
|
||||
// If you set it to no access and secureData.bytes is accessed, it will SIGABRT. For example,
|
||||
// secureData.protection = NASecureDataProtectionNoAccess;
|
||||
```
|
||||
|
||||
Some classes like NASecretBox, NABox and NAAEAD have an option to enable secureMemory (on decrypt).
|
||||
|
||||
NASecureData subclasses NSMutableData for compatibility and usage with other APIs.
|
||||
|
||||
# Generating Random Data
|
||||
|
||||
See [Generating Random Data](https://download.libsodium.org/doc/generating_random_data/index.html).
|
||||
|
||||
```objc
|
||||
NSData *data = [NARandom randomData:32]; // 32 bytes of random data
|
||||
NSData *data = [NARandom randomSecureReadOnlyData:32]; // 32 bytes of random, secure, read-only data
|
||||
```
|
||||
|
||||
# Secret-Key Cryptography
|
||||
|
||||
## Authenticated Encryption
|
||||
|
||||
Encrypts and authenticates a message using a shared key and nonce.
|
||||
|
||||
See [Authenticated Encryption](https://download.libsodium.org/doc/secret-key_cryptography/authenticated_encryption.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [NARandom randomData:NASecretBoxKeySize];
|
||||
NSData *nonce = [NARandom randomData:NASecretBoxNonceSize];
|
||||
NSData *message = [@"This is a secret message" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NASecretBox *secretBox = [[NASecretBox alloc] init];
|
||||
NSError *error = nil;
|
||||
NSData *encrypted = [secretBox encrypt:message nonce:nonce key:key error:&error];
|
||||
// If an error occurred encrypted will be nil and error set
|
||||
|
||||
NSData *decrypted = [secretBox decrypt:encrypted nonce:nonce key:key error:&error];
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
See [Authentication](https://download.libsodium.org/doc/secret-key_cryptography/secret-key_authentication.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [NARandom randomData:NAAuthKeySize];
|
||||
NSData *message = [@"This is a message" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSError *error = nil;
|
||||
NAAuth *auth = [[NAAuth alloc] init];
|
||||
NSData *authData = [auth auth:message key:key &error];
|
||||
BOOL verified = [auth verify:authData data:message key:key error:&error];
|
||||
```
|
||||
|
||||
## AEAD
|
||||
|
||||
See [Authenticated Encryption with Additional Data](https://download.libsodium.org/doc/secret-key_cryptography/aead.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [NARandom randomData:NAAEADKeySize];
|
||||
NSData *nonce = [NARandom randomData:NAAEADNonceSize];
|
||||
NSData *message = [@"This is a secret message" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *additionalData = [@"Additional data" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NAAEAD *AEAD = [[NAAEAD alloc] init];
|
||||
NSError *error = nil;
|
||||
NSData *encryptedData = [AEAD encryptChaCha20Poly1305:message nonce:nonce key:key additionalData:additionalData error:&error];
|
||||
NSData *decryptedData = [AEAD decryptChaCha20Poly1305:encryptedData nonce:nonce key:key additionalData:additionalData error:&error];
|
||||
```
|
||||
|
||||
# Public-Key Cryptography
|
||||
|
||||
## Authenticated Encryption
|
||||
|
||||
See [Authenticated Encryption](https://download.libsodium.org/doc/public-key_cryptography/authenticated_encryption.html).
|
||||
|
||||
```objc
|
||||
NSError *error = nil;
|
||||
NABoxKeypair *keypair = [NABoxKeypair generate:&error];
|
||||
|
||||
NSData *nonce = [NARandom randomData:NABoxNonceSize];
|
||||
NSData *message = [@"This is a secret message" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NABox *box = [[NABox alloc] init];
|
||||
NSData *encryptedData = [box encrypt:message nonce:nonce keypair:keypair error:&error];
|
||||
NSData *decryptedData = [box decrypt:encryptedData nonce:nonce keypair:keypair error:&error];
|
||||
```
|
||||
|
||||
# Password Hashing
|
||||
|
||||
See [Password Hashing](https://download.libsodium.org/doc/password_hashing/index.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [@"toomanysecrets" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSData *salt = [NARandom randomData:NAScryptSaltSize];
|
||||
NSError *error = nil;
|
||||
NSData *data = [NAScrypt scrypt:key salt:salt error:&error];
|
||||
```
|
||||
|
||||
# Advanced
|
||||
|
||||
## One-Time Authentication
|
||||
|
||||
Generates a MAC for a given message and shared key using Poly1305 algorithm.
|
||||
Key may NOT be reused across messages.
|
||||
|
||||
See [One-Time Authentication](https://download.libsodium.org/doc/advanced/poly1305.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [NARandom randomData:NAOneTimeAuthKeySize];
|
||||
NSData *message = [@"This is a message" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
NSError *error = nil;
|
||||
NAOneTimeAuth *oneTimeAuth = [[NAOneTimeAuth alloc] init];
|
||||
NSData *auth = [oneTimeAuth auth:message key:key error:&error];
|
||||
BOOL verified = [oneTimeAuth verify:auth data:message key:key error:&error];
|
||||
```
|
||||
|
||||
## Stream Ciphers
|
||||
|
||||
See [XSalsa20](https://download.libsodium.org/doc/advanced/xsalsa20.html).
|
||||
|
||||
```objc
|
||||
NSData *key = [NARandom randomData:NAStreamKeySize];
|
||||
NSData *nonce = [NARandom randomData:NAStreamNonceSize];
|
||||
NAStream *stream = [[NAStream alloc] init];
|
||||
NSError *error = nil;
|
||||
NSData *encrypted = [stream xor:message nonce:nonce key:key error:&error];
|
||||
NSData *decrypted = [stream xor:encrypted nonce:nonce key:key error:&error];
|
||||
```
|
||||
|
||||
## Dispatch
|
||||
|
||||
There is a helper to dispatch these operations on a queue:
|
||||
|
||||
```objc
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
NADispatch(queue, ^id(NSError **error) {
|
||||
return [NAScrypt scrypt:password salt:salt error:error];
|
||||
}, ^(NSError *error, NSData *data) {
|
||||
// This is on the main queue.
|
||||
// Error is set if it failed.
|
||||
});
|
||||
```
|
||||
Reference in new issue
Block a user