Secure Memory For Swift Objects - ios

I am writing a swift application that requires handling private keys in memory. Because of the sensitivity of such objects, the keys need to be cleared (a.k.a. written to all zeros) when the object is deallocated, and the memory cannot be paged to disk (which is typically done using mlock()).
In Objective-C, you can provide a custom CFAllocator object, which allows you to use your own functions to allocate/deallocate/reallocate the memory used by an object.
So one solution is to just implement a "SecureData" object in objective-c, which internally creates an NSMutableData object using a custom CFAllocator (also in objective-c).
However, is there any way for me to provide my own custom memory allocation functions for a pure swift object (for example, a struct or a [UInt8])? Or is there a better, "proper" way to implement secure memory like this in swift?

If you want complete control over a region of memory you allocate yourself, you can use UnsafePointer and co:
// allocate enough memory for ten Ints
var ump = UnsafeMutablePointer<Int>.alloc(10)
// memory is in an uninitialized raw state
// initialize that memory with Int objects
// (here, from a collection)
ump.initializeFrom(reverse(0..<10))
// memory property gives you access to the underlying value
ump.memory // 9
// UnsafeMutablePointer acts like an IndexType
ump.successor().memory // 8
// and it has a subscript, but it's not a CollectionType
ump[3] // = 6
// wrap it in an UnsafeMutableBufferPointer to treat it
// like a collection (or UnsafeBufferPointer if you don't
// need to be able to alter the values)
let col = UnsafeMutableBufferPointer(start: ump, count: 10)
col[3] = 99
println(",".join(map(col,toString)))
// prints 9,8,7,99,5,4,3,2,1,0
ump.destroy(10)
// now the allocated memory is back in a raw state
// you could re-allocate it...
ump.initializeFrom(0..<10)
ump.destroy(10)
// when you're done, deallocate the memory
ump.dealloc(10)
You can also have UnsafePointer point to other memory, such as memory you’re handed by some C API.
UnsafePointer can be passed into C functions that take a pointer to a contiguous block of memory. So for your purposes, you could then pass this pointer into a function like mlock:
let count = 10
let ump = UnsafeMutablePointer.allocate<Int>(count)
mlock(ump, UInt(sizeof(Int) * count))
// initialize, use, and destroy the memory
munlock(ump, UInt(sizeof(Int) * count))
ump.dealloc(count)
You can even hold your own custom types:
struct MyStruct {
let a: Int
let b: Int
}
var pointerToStruct = UnsafeMutablePointer<MyStruct>.alloc(1)
pointerToStruct.initialize(MyStruct(a: 1, b: 2))
pointerToStruct.memory.b // 2
pointerToStruct.destroy()
pointerToStruct.dealloc(1)
However be aware if doing this with classes, or even arrays or strings (or a struct that contains them), that all you will be holding in your memory is pointers to other memory that these objects allocate and own. If this matters to you (i.e. you are doing something special to this memory such as securing it, in your example), this is probably not what you want.
So either you need to use fixed-size objects, or make further use of UnsafePointer to hold pointers to more memory regions. If they don't need to dynamically resize, then just a single allocation of an unsafe pointer, possibly wrapped in a UnsafeBufferPointer for a collection interface, could do it.
If you need more dynamic behavior, below is a very bare-bones implementation of a collection that can resize as necessary, that could be enhanced to cover specialty memory-handling logic:
// Note this is a class not a struct, so it does NOT have value semantics,
// changing a copy changes all copies.
public class UnsafeCollection<T> {
private var _len: Int = 0
private var _buflen: Int = 0
private var _buf: UnsafeMutablePointer<T> = nil
public func removeAll(keepCapacity: Bool = false) {
_buf.destroy(_len)
_len = 0
if !keepCapacity {
_buf.dealloc(_buflen)
_buflen = 0
_buf = nil
}
}
public required init() { }
deinit { self.removeAll(keepCapacity: false) }
public var count: Int { return _len }
public var isEmpty: Bool { return _len == 0 }
}
To cover the requirements of MutableCollectionType (i.e. CollectionType plus assignable subscript):
extension UnsafeCollection: MutableCollectionType {
typealias Index = Int
public var startIndex: Int { return 0 }
public var endIndex: Int { return _len }
public subscript(idx: Int) -> T {
get {
precondition(idx < _len)
return _buf[idx]
}
set(newElement) {
precondition(idx < _len)
let ptr = _buf.advancedBy(idx)
ptr.destroy()
ptr.initialize(newElement)
}
}
typealias Generator = IndexingGenerator<UnsafeCollection>
public func generate() -> Generator {
return Generator(self)
}
}
And ExtensibleCollectionType, to allow for dynamic growth:
extension UnsafeCollection: ExtensibleCollectionType {
public func reserveCapacity(n: Index.Distance) {
if n > _buflen {
let newBuf = UnsafeMutablePointer<T>.alloc(n)
newBuf.moveInitializeBackwardFrom(_buf, count: _len)
_buf.dealloc(_buflen)
_buf = newBuf
_buflen = n
}
}
public func append(x: T) {
if _len == _buflen {
reserveCapacity(Int(Double(_len) * 1.6) + 1)
}
_buf.advancedBy(_len++).initialize(x)
}
public func extend<S: SequenceType where S.Generator.Element == T>
(newElements: S) {
var g = newElements.generate()
while let x: T = g.next() {
self.append(x)
}
}
}

I know this question is old but something for those who land here: since iOS 10 you can use Secure Enclave to store private keys securely. The way it works is that all the operations that require decryption is performed inside the Secure Enclave so you do not have to worry about runtime hooking of your classes or memory leaks.
Take a look here: https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave

Related

How can I create a HashMap on the heap in Zig?

The conventional way to make an object on the heap is to make a create fn:
const Something = struct {
a:Allocator,
b:[1000]u8,
pub fn create(a:Allocator) !*Something {
var mem = try a.create(Something)
mem.* = {
.a =a,
.b = undefined
};
return mem;
}
}
But what about if I want to put a std lib ArrayHashMap on the heap? For example:
const StringStringArrayHashMap = std.StringArrayHashMap([]const u8);
fn makeMap(a:Allocator) StringStringArrayHashMap {
return StringStringArrayHashMap.init(a);
}
const WithMap = struct {
map:StringStringHashMap
};
fn fillMap(a:Allocator) !WithMap {
var map = makeMap(a);
try map.put("a", "hello");
try map.put("b", "world");
return WithMap { .map = map };
}
fn badMemory(a:Allocator) !void {
const with_map = fillMap(a);
_ = with_map;
}
badMemory will receive a WithMap but it's internal map, having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsade in badMemory.
I can't see any way to make a valid HashMap without somehow hacking the internals of the zig stdlib.
You can put the map on the heap the same way you did with Something type:
var map: *StringStringArrayHashMap = try allocator.create(StringStringArrayHashMap);
map.* = StringStringArrayHashMap.init(allocator);
badMemory will receive a WithMap but it's internal map, having been made on the stack in fillMap will be freed at the end of fillMap and consequently unsafe in badMemory.
This is false. The map is safe to use in badMemory as it's copied to the stack in badMemory. (Or maybe the compiler could decide to pass it as a pointer, I'm not sure if parameter's pass-by-value rule applies to the return value. Doesn't matter here.) But you should probably be careful when copying the map or you might step into the same issue as this question.

Typescript, How to avoid code duplication in constructor?

Consider this class that is used as a data model in a Model-View-Controller scenario (I'm using TypeScript 3.5):
export class ViewSource {
private viewName : string;
private viewStruct : IViewStruct;
private rows : any[];
private rowIndex : number|null;
constructor(viewName : string) {
// Same as this.setViewName(viewName);
this.viewName = viewName;
this.viewStruct = api.meta.get_view_struct(viewName);
if (!this.viewStruct) {
throw new Error("Clould not load structure for view, name=" + (viewName));
}
this.rows = [];
this.rowIndex = null;
}
public setViewName = (viewName: string) => {
this.viewName = viewName;
this.viewStruct = api.meta.get_view_struct(viewName);
if (!this.viewStruct) {
throw new Error("Clould not load structure for view, name=" + (viewName));
}
this.rows = [];
this.rowIndex = null;
}
public getViewStruct = ():IViewStruct => { return this.viewStruct; }
public getCellValue = (rowIndex: number, columnName: string) : any => {
const row = this.rows[rowIndex] as any;
return row[columnName];
}
}
This is not a complete class, I only included a few methods to demonstrate the problem. ViewSource is a mutable object. It can be referenced from multiple parts of the application. (Please note that being a mutable object is a fact. This question is not about choosing a different data model that uses immutable objects.)
Whenever I want to change the state of a ViewSource object, I call its setViewName method. It does work, but it is also very clumsy. Every line of code in the constructor is repeated in the setViewName method.
Of course, it is not possible to use this constructor:
constructor(viewName : string) {
this.setViewName(viewName);
}
because that results in TS2564 error:
Property 'viewStruct' has no initializer and is not definitely assigned in the constructor.ts(2564)
I do not want to ignore TS2564 errors in general. But I also do not want to repeat all attribute initializations. I have some other classes with even more properties (>10), and the corresponding code duplication looks ugly, and it is error prone. (I might forget that some things have to bee modified in two methods...)
So how can I avoid duplicating many lines of code?
I think the best method to avoid code duplication in this case would be to create a function that contains the initialization code, but instead of setting the value, it retunrs the value that need to be set.
Something like the following:
export class ViewSource {
private viewName : string;
private viewStruct : IViewStruct;
private rows : any[];
private rowIndex : number|null;
constructor(viewName : string) {
const {newViewName, newViewStruct, newRows, newRowIndex} = this.getNewValues(viewName);
this.viewName = newViewName;
this.newViewStruct = newViewStruct;
// Rest of initialization goes here
}
public setViewName = (viewName: string) => {
const {newViewName, newViewStruct, newRows, newRowIndex} = this.getNewValues(viewName);
// Rest of initialization goes here
}
privat getNewValues = (viewName) => {
const newViewName = viewName;
const newViewStruct = api.meta.get_view_struct(viewName);
if (!newViewStruct) {
throw new Error("Clould not load structure for view, name=" + (viewName));
}
const newRows = [];
const newRowIndex = null;
return {newViewName, newViewStruct, newRows, newRowIndex};
}
}
This way the only thing you duplicate is setting the values, not calculating them, and if the values calculations will get more complicated you can simply expand the returned value.
A less complex approach than the accepted answer is to use the //#ts-ignore[1] comment above each member that is initialized elsewhere.
Consider this contrived example
class Foo {
// #ts-ignore TS2564 - initialized in the init method
a: number;
// #ts-ignore TS2564 - initialized in the init method
b: string;
// #ts-ignore TS2564 - initialized in the init method
c: number;
constructor(a: number, b: string) {
if(a === 0) {
this.init(a,b,100);
} else {
this.init(a,b,4912);
}
}
private init(a: number, b: string, c: number): void {
this.a = a;
this.b = b;
this.c = c;
}
}
Since TypeScript 3.9 there exists the //#ts-expect-error[2] comment, but I think #ts-ignore is suitable.
[1] Suppress errors in .ts files
[2] TS expect errors comment
Since TypeScript 2.7 you can use the definite assignment assertion modifier which means adding an exclamation mark between the variable name and the colon:
private viewName!: string
This has the same effect as adding a // #ts-ignore TS2564 comment above it as #RamblinRose suggested.

Error message when defining struct

I am writing a struct in Swift:
struct LevelDictionary {
let kNumberOfSegments: Int = 10
static func loadLevelData() -> NSDictionary {
for var segmentNumber = 0; segmentNumber < kNumberOfSegments; ++segmentNumber {
//My code here
}
return dictionary
}
}
For some reason I get an error on compiling: Instance member 'kNumberOfSegments' cannot be used on type 'LevelDictionary'. What am I missing? I get the same error when I set up LevelDictionary as a Class.
loadLevelData() is a static function which is called on "class" level
LevelDictionary.loadLevelData()
To use kNumberOfSegments in the static function it must be static as well
static let kNumberOfSegments: Int = 10
The direct answer to your question is that you can't use a property in class scope.
A different answer is that you seem to want a static function that returns a dictionary after doing something a certain number of times; which is why you have kNumberOfSegments in the first place. But do you really need to have a variable for something that you aren't going to use again. Another way to do this is to have a default variable in your class method:
struct LevelDictionary {
static func loadLevelData(numberOfSegments: Int = 10) -> NSDictionary {
for segment in 0 ..< numberOfSegments {
// your code here
}
return dictionary
}
}
Now you can call the method without an argument to use the default
let dictionary = LevelDictionary.loadLevelData() // Will use 10 segments
Or you can use a parameter to override the default
let dictianary = LevelDictionary.loadLevelData(20) // Will use 20 segments
You can't use instance member variables/constants inside the static function. (In terms of Objective C you can't use instance member objects inside class function)
Either you should declare the kNumberOfSegments as static or make that function as non-static. I prefer the first option,
struct LevelDictionary
{
static let kNumberOfSegments: Int = 10
static func loadLevelData() -> NSDictionary
{
for var segmentNumber = 0; segmentNumber < kNumberOfSegments; ++segmentNumber
{
//My code here
}
return dictionary
}
}

Implement opApply with nogc and inferred parameters

Note: I initially posted an over-simplified version of my problem. A more
accurate description follows:
I have the following struct:
struct Thing(T) {
T[3] values;
int opApply(scope int delegate(size_t, ref T) dg) {
int res = 0;
foreach(idx, ref val; values) {
res = dg(idx, val);
if (res) break;
}
return res;
}
}
Foreach can be used like so:
unittest {
Thing!(size_t[]) thing;
foreach(i, ref val ; thing) val ~= i;
}
However, it is not #nogc friendly:
#nogc unittest {
Thing!size_t thing;
foreach(i, ref val ; thing) val = i;
}
If I change the signature to
int opApply(scope int delegate(size_t, ref T) #nogc dg) { ... }
It works for the #nogc case, but fails to compile for non-#nogc cases.
The solutions I have tried are:
Cast the delegate
int opApply(scope int delegate(size_t, ref T) dg) {
auto callme = cast(int delegate(size_t, ref T) #nogc) dg;
// use callme instead of dg to support nogc
This seems wrong as I am willfully casting a #nogc attribute even onto
functions that do may not support it.
Use opSlice instead of opApply:
I'm not sure how to return an (index, ref value) tuple from my range. Even if
I could, I think it would have to contain a pointer to my static array, which
could have a shorter lifetime than the returned range.
Use a templated opApply:
All attempts to work with this have failed to automatically determine the
foreach argument types. For example, I needed to specify:
foreach(size_t idx, ref int value ; thing)
Which I see as a significant hindrance to the API.
Sorry for underspecifying my problem before. For total transparency,
Enumap is the "real-world" example. It
currently uses opSlice, which does not support ref access to values. My
attempts to support 'foreach with ref' while maintaining #nogc support is what
prompted this question.
Instead of overloading the opApplyoperator you can implement an input range for your type. Input ranges work automatically as the agregate argument in foreach statements:
struct Thing(K,V) {
import std.typecons;
#nogc bool empty(){return true;}
#nogc auto front(){return tuple(K.init, V.init);}
#nogc void popFront(){}
}
unittest {
Thing!(int, int) w;
foreach(val ; w) {
int[] i = [1,2,3]; // spurious allocation
}
}
#nogc unittest {
Thing!(int, int) w;
foreach(idx, val ; w) { assert(idx == val); }
}
This solves the problem caused by the allocation of the delegate used in foreach.
Note that the example is shitty (the range doesn't work at all, and usually ranges are provided via opSlice, etc) but you should get the idea.

Terribly Slow migrated Objc to swift code

In an application I've written I have a process that parses a large amount of data from Core-Data and displays it to a graph. While doing this processing I also end up writing the data out to a CSV File. I created a separate class called CSVLine which assists with the creation of the CSV file.
For my test case of 140k recorded my Objective-C code takes aprox 12 seconds to run. After "migrating" the class over to swift It now takes somewhere between 280-360 seconds to run. Obviously I've done something terrible.
Using Instruments I was able to identify the "slow" method and I was wondering if I've done something clear in SWIFT to cause the issue.
Objc
- (void)newLine {
// NSLog(#"Appending %#", self.csvString);
[outData appendData:[self csvData] ];
[self clear];
}
- (void)clear {
// Erase every single value
for (NSUInteger i = 0; i < [values count]; i ++) {
values[i] = #"";
}
}
Swift
func newLine() {
outData.appendData(csvData())
clear()
}
// Clear out the Array
func clear() {
for (var i = 0; i < values.count; i++) {
values[i] = ""
}
}
I'm working with various types of data that are all being written to a single CSV file so there are many blank lines. To accommodate for this I designed this class so that it has an array of keys and an array of values. The keys store the "column" names for the CSV file and values will store either a blank or a value for the index of the key for that data element.
Example:
Keys = [speed,heading,lat,lon]
values might be [200,300,"",""]
or ["","","38.553","25.2256"]
Once I'm done with a line i will write a comma joined list of the values into an internal data structure and clear out the line (erase all the items in the values array). This seems to be where the slowdown is with the swift class. Is there something blatantly "slow" i'm doing when i zero out my array?
Full Swift Class
#objc class CSVLineSwift : NSObject {
// Define Arrays
var keys: [String] = [String]()
var values: [String] = [String]()
var outData : NSMutableData = NSMutableData()
override init() {
}
// Singelton Operator - Thread Safe :: http://code.martinrue.com/posts/the-singleton-pattern-in-swift
class var instance : CSVLineSwift {
// Computed Property
struct Static {
static var instance : CSVLineSwift?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = CSVLineSwift();
}
return Static.instance!
}
// Erase existing Data
func newFile() {
outData = NSMutableData();
outData.appendData(headerData())
}
func csvString() -> String {
return ",".join(values)
}
func csvData() -> NSData {
let string = csvString()
let data = string.dataUsingEncoding(NSUTF8StringEncoding)
return data!
}
func addField(field : String) {
keys.append(field)
values.append("")
}
func setValueForKey(value:String, key:String) {
if let index = find(keys, key) {
values[index] = value
} else {
print( "ERROR -- There was no key: \(key) in the header Array")
}
}
func headerString() -> String {
return ",".join(keys)
}
func headerData() -> NSData {
return headerString().dataUsingEncoding(NSUTF8StringEncoding)!
}
func newLine() {
outData.appendData(csvData())
clear()
}
// Clear out the Array
func clear() {
for (var i = 0; i < values.count; i++) {
values[i] = ""
}
}
func writeToFile(fileName : String) {
outData.writeToFile(fileName, atomically: true)
}
}
Be sure that Swift's optimization level in Build Settings is not -Onone. In my experience, it is orders of magnitude slower than -O. (-O is also the default for 'release', so alternatively you could simply build for release, as already suggested.) As for 'zeroing out' the array, it might be faster (although I do not know) to simply re-initialize the array with a repeated value:
values = [String](count: values.count, repeatedValue: "")
Or if you know you will be appending the new values as you go along, and are not bound to using the indices, you could call:
values.removeAll(keepCapacity: true)
And add the new values with values.append() rather than at indices.
It appears my issues were due to a debug build. In debug build there is no optimization. Once you do a run build the optimization kicks in and things run MUCH MUCH faster....
Similar to the answer posted here: Is Swift really slow at dealing with numbers?

Resources