convert uint8_t to NSData - ios

I have implemented publickey privatekey RSA encryption in iOS application based on the examples provided on the Apple Developer site.
It works perfectly if I encrypt and return the uint8_t cipherBuffer, and then decrypt from the uint8_t cipherBuffer. However I need to store the encrypted data to an .xcdata model as NSData.
The problem I'm having is reliably converting the uint8_t cipherBuffer to NSData and/or converting the NSData back to uint8_t when it's time to decrypt. The decrypted data appears to be truncated.
This is how I'm converting the uint8_t encrypted buffer to NSData:
return [NSData dataWithBytesNoCopy:cipherBuffer length:BUFFER_SIZE];
This is how I'm converting the encrypted NSData back to a uint8_t buffer when it is time to decrypt it:
uint8_t *cipherBuffer = (uint8_t*)[cipherText bytes];

Thanks jgh and Jody;
I changed the encryption method to "malloc" the buffer and tried several approaches to write the bytes to NSData, wound up with:
return [NSData dataWithBytes:(const void *)cipherBuffer length:CIPHER_BUFFER_SIZE];
What finally fixed the issue was changing the way I was creating the uint8_t in the decryption method:
const uint8_t *cipherBuffer = (const uint8_t*)[data bytes];

Without seeing how you're creating cipherBuffer, it's difficult to say exactly why it's not working. However, from the documentation on dataWithBytesNoCopy:
The returned object takes ownership of the bytes pointer and frees it on deallocation. Therefore, bytes must point to a memory block allocated with malloc.
If you're just declaring cipherBuffer as
uint8_t cipherBuffer[BUFFER_SIZE];
it may explain your problems. Instead, use malloc:
uint8_t* cipherBuffer = malloc(BUFFER_SIZE);

It sounds like you are giving it a raw pointer, then re-using that pointer.
dataWithBytesNoCopy: wants to keep the pointer you give it. In fact, you must give it a pointer that you created with malloc, because it will free it when it's done with the data.
If you do not want the NSData object to take ownership, you should use dataWithBytesNoCopy:length:freeWhenDone:.

Related

OBJ-C wipe NSData content before nullifying it

For security reasons we need Always to wipe sensitive data from memory.
Usually it is not something that i see done in IOS but for apps and need extended security it is very important.
The Data that Usually needs to be wiped if NSData and NSString objects (pointing to nil does not wipe the data and it is a security breach)
I've managed to wipe my NSStrings with the code below (When password is NSString):
unsigned char *charPass;
if (password != nil) {
charPass = (unsigned char*) CFStringGetCStringPtr((CFStringRef) password, CFStringGetSystemEncoding());
memset(charPass, 0, [password length]);
password = nil;
}
Big remark on this implementation: You HAVE to check for NULL before calling the charPass or it might crash. There is NO guarantee that CFStringGetCStringPtr will return a value!
When password is NSData It suppose to be even more strait forward and the code bellow suppose to work:
memset([password bytes], 0, [password length]);
But this gives me a compilation error:
No matching function for call to 'memset'
I can't find a workaround to point to the password address and wipe the bytes over there like I did with the string (bytes method should let me do just that from what I understand but it doesn't compile for some reason that I cant figure out)
Any one has an idea for this?
10x
Your string deallocator is fragile. You write:
Big remark on this implementation: You HAVE to check for NULL before calling the charPass or it might crash. There is NO guarantee that CFStringGetCStringPtr will return a value!
This is documented behaviour as CFString (and hence NSString) does not guarantee you direct access to its internal buffer. You don't say what how you handle this situation, but if you don't erase the memory you presumably have a security problem.
In the case you do get a valid pointer back you are using the wrong byte count. The call [password length] returns:
The number of UTF-16 code units in the receiver.
which is not the same as the number of bytes. However CFStringGetCStringPtr returns:
A pointer to a C string or NULL if the internal storage of theString does not allow this to be returned efficiently.
If you have a C string you can use C library function strlen() to find its length.
To address the case when CFStringGetCStringPtr returns NULL you could create the string yourself as a CFString and supply a custom CFAllocater. You shouldn't need to write a complete allocator yourself, instead you could build one based on the system one. You can get the default allocators CFAllocatorContext which will return you the function pointers the system uses. You can then create a new CFAllocator based of a CFAllocatorContext which is a copy of the default one except you've changed the deallocate and reallocate pointers to functions which you have implemented in terms of the default allocate, reallocate and deallocate but also call memset appropriately to clear out memory.
Once you've done that doing your security wipe comes down to making sure these custom created CFString objects, aka NSString objects, are deallocated before your app quits.
You can find out about CFAllocator, CFAllocatorContext etc. in Memory Management Programming Guide for Core Foundation.
Which brings us to your actual question, how to zero an NSData. Here you are in luck an NSData object is a CFData object, and CFData's CFDataGetBytePtr, unlike CFStringGetCStringPtr, is guaranteed to return a pointer to the actual bytes, straight from the documentation:
This function is guaranteed to return a pointer to a CFData object's internal bytes. CFData, unlike CFString, does not hide its internal storage.
So code following your pattern for CFString will work here. Note that using NSData's bytes is not guaranteed in the documentation to call CFDataGetBytePtr, it could for example call CFDataGetBytes and return a copy of the bytes, use the CFData functions.
HTH
While I cannot speak for the actual safety of doing this, your problem is that NSData's bytes method returns a const void *
https://developer.apple.com/documentation/foundation/nsdata/1410616-bytes?language=objc
You can cast it to a void * if you want by
memset((void *)[password bytes], 0, [password length]);
If you use a NSMutableData, you won't have to do this.

How to decode a live555 rtsp stream (h.264) MediaSink data using iOS8's VideoToolbox?

Ok, I know that this question is almost the same as get-rtsp-stream-from-live555-and-decode-with-avfoundation, but now VideoToolbox for iOS8 became public for use and although I know that it can be done using this framework, I have no idea of how to do this.
My goals are:
Connect with a WiFiCamera using rtsp protocol and receive stream data (Done with live555)
Decode the data and convert to UIImages to display on the screen (motionJPEG like)
And save the streamed data on a .mov file
I reached all this goals using ffmpeg, but unfortunately I can't use it due to my company's policy.
I know that I can display on the screen using openGL too, but this time I have to convert to UIImages. I also tried to use the libraries below:
ffmpeg: can't use this time due to company's policy. (don't ask me why)
libVLC: display lags about 2secs and I don't have access to stream data to save into a .mov file...
gstreamer: same as above
I believe that live555 + VideoToolbox will do the job, just can't figure out how to do this happen ...
I did it. VideoToolbox is still poor documented and we have no much information about video programming (without using ffmpeg) so it cost me more time than I really expected.
For stream using live555, I got the SPS and PPS info to create the CMVideoFormatDescription like this:
const uint8_t *props[] = {[spsData bytes], [ppsData bytes]};
size_t sizes[] = {[spsData length], [ppsData length]};
OSStatus result = CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL, 2, props, sizes, 4, &videoFormat);
Now, the difficult part (because I'm noob on video programming): Replace the NALunit header with a 4 byte length code as described here
int headerEnd = 23; //where the real data starts
uint32_t hSize = (uint32_t)([rawData length] - headerEnd - 4);
uint32_t bigEndianSize = CFSwapInt32HostToBig(hSize);
NSMutableData *videoData = [NSMutableData dataWithBytes:&bigEndianSize length:sizeof(bigEndianSize)];
[videoData appendData:[rawData subdataWithRange:NSMakeRange(headerEnd + 4, [rawData length] - headerEnd - 4)]];
Now I was able to create a CMBlockBuffer successfully using this raw data and pass the buffer to VTDecompressionSessionDecodeFrame. From here is easy to convert the response CVImageBufferRef to UIImage... I used this stack overflow thread as reference.
And finally, save the stream data converted on UIImage following the explanation described on How do I export UIImage array as a movie?
I just posted a little bit of my code because I believe this is the important part, or in other words, it is where I was having problems.

iOS AES Encryption with Vulnerability: Signed Memory Arithmetic

I'm using AES encryption to encrypt / decrypt user's info in my app.
This is the code I'm using:
https://gist.github.com/matsuda/9204276
Everything works just fine.
But the code got scanned for security vulnerability recently and there's an issue that got flagged.
The vulnerability:
Signed Memory Arithmetic
Description:
The software reads or writes to a buffer using an index or pointer that references a memory location after the end of the buffer.
Line 39-40 of NSData+AES.m of the code in the above link is where it got highlighted
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
I'm not sure what I should do.
The buffer size is calculated with dataLength + kCCBlockSizeAES128 just before allocation so the length should be okay?
Thanks for your help in advance.

IOS NSData constructor VS NSMutableData for real time using purpose

I have void* buffer...
I need to encapsulate it as fast as possible in a NSData structure (NSData or NSMutableData)
I'm guessing using only one NSMutableData (defined in the class) with
- (void)resetBytesInRange:(NSRange)range
- (void)appendBytes:(const void *)bytes length:(NSUInteger)length
or even
- (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)bytes
will be much faster than using [NSData dataWithData:] every function call...
This is for audio process, so it needs to be the fastest it can be.
Does anyone can confirm that i'll be faster to use NSMutableData instead of NSData constructor ?
EDIT :
the buffer is always the same size, the NSMutableData won't need to re-allocate memory...
If you just want to replace the contents of an (already initialized) NSMutableData *data object with new data from buffer of the same length, then the fastest method is probably
void *mutableBytes = [data mutableBytes];
memcpy(mutableBytes, buffer, length);
because no range check and no (re-)allocation is done. See also the examples in Working With Mutable Binary Data.
But of course, as it is often said in this forum, you should profile your app with Instruments to find out where to optimize the program.

What is the correct way to clear sensitive data from memory in iOS?

I want to clear sensitive data from memory in my iOS app.
In Windows I used to use SecureZeroMemory. Now, in iOS, I use plain old memset, but I'm a little worried the compiler might optimize it:
https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/771-BSI.html
code snippet:
NSData *someSensitiveData;
memset((void *)someSensitiveData.bytes, 0, someSensitiveData.length);
Paraphrasing 771-BSI (link see OP):
A way to avoid having the memset call optimized out by the compiler is to access the buffer again after the memset call in a way that would force the compiler not to optimize the location. This can be achieved by
*(volatile char*)buffer = *(volatile char*)buffer;
after the memset() call.
In fact, you could write a secure_memset() function
void* secure_memset(void *v, int c, size_t n) {
volatile char *p = v;
while (n--) *p++ = c;
return v;
}
(Code taken from 771-BSI. Thanks to Daniel Trebbien for pointing out for a possible defect of the previous code proposal.)
Why does volatile prevent optimization? See https://stackoverflow.com/a/3604588/220060
UPDATE Please also read Sensitive Data In Memory because if you have an adversary on your iOS system, your are already more or less screwed even before he tries to read that memory. In a summary SecureZeroMemory() or secure_memset() do not really help.
The problem is NSData is immutable and you do not have control over what happens. If the buffer is controlled by you, you could use dataWithBytesNoCopy:length: and NSData will act as a wrapper. When finished you could memset your buffer.

Resources