Index: ObjFW.xcodeproj/project.pbxproj ================================================================== --- ObjFW.xcodeproj/project.pbxproj +++ ObjFW.xcodeproj/project.pbxproj @@ -286,10 +286,18 @@ 4B5B02C118B2897500CE6AE4 /* OFINIFileTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5B02C018B2897500CE6AE4 /* OFINIFileTests.m */; }; 4B5B02C418B28A1B00CE6AE4 /* testfile.ini in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B5B02C218B289ED00CE6AE4 /* testfile.ini */; }; 4B5C112F17E9AB3E003C917F /* forwarding.S in Sources */ = {isa = PBXBuildFile; fileRef = 4B5C112C17E9AAED003C917F /* forwarding.S */; }; 4B5CF8F914940BD2007AA324 /* OFString+JSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B5CF8F614940BD2007AA324 /* OFString+JSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B5CF8FA14940BD2007AA324 /* OFString+JSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5CF8F714940BD2007AA324 /* OFString+JSONValue.m */; }; + 4B60259F19B76A5C00694BCC /* OFSHA384Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B60259919B76A5C00694BCC /* OFSHA384Hash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B6025A019B76A5C00694BCC /* OFSHA384Hash.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B60259A19B76A5C00694BCC /* OFSHA384Hash.m */; }; + 4B6025A119B76A5C00694BCC /* OFSHA384Or512Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B60259B19B76A5C00694BCC /* OFSHA384Or512Hash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B6025A219B76A5C00694BCC /* OFSHA384Or512Hash.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B60259C19B76A5C00694BCC /* OFSHA384Or512Hash.m */; }; + 4B6025A319B76A5C00694BCC /* OFSHA512Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B60259D19B76A5C00694BCC /* OFSHA512Hash.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B6025A419B76A5C00694BCC /* OFSHA512Hash.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B60259E19B76A5C00694BCC /* OFSHA512Hash.m */; }; + 4B6025A719B76B5000694BCC /* OFSHA384HashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6025A519B76B5000694BCC /* OFSHA384HashTests.m */; }; + 4B6025A819B76B5000694BCC /* OFSHA512HashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B6025A619B76B5000694BCC /* OFSHA512HashTests.m */; }; 4B62ED1518566FCA0004E0E3 /* OFCopyItemFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B62ED1318566FCA0004E0E3 /* OFCopyItemFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B62ED1618566FCA0004E0E3 /* OFCopyItemFailedException.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B62ED1418566FCA0004E0E3 /* OFCopyItemFailedException.m */; }; 4B66B636182ADC45000A69E3 /* OFDeflate64Stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66B634182ADC45000A69E3 /* OFDeflate64Stream.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B66B637182ADC45000A69E3 /* OFDeflate64Stream.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B66B635182ADC45000A69E3 /* OFDeflate64Stream.m */; }; 4B6743F1163C384A00EB1E59 /* OFLockFailedException.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6743EB163C384A00EB1E59 /* OFLockFailedException.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -705,10 +713,18 @@ 4B5C112B17E9AAED003C917F /* apple-forwarding-x86_64.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; name = "apple-forwarding-x86_64.S"; path = "src/forwarding/apple-forwarding-x86_64.S"; sourceTree = ""; }; 4B5C112C17E9AAED003C917F /* forwarding.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; name = forwarding.S; path = src/forwarding/forwarding.S; sourceTree = ""; }; 4B5C112E17E9AB0C003C917F /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; name = Makefile; path = src/forwarding/Makefile; sourceTree = ""; }; 4B5CF8F614940BD2007AA324 /* OFString+JSONValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OFString+JSONValue.h"; path = "src/OFString+JSONValue.h"; sourceTree = ""; }; 4B5CF8F714940BD2007AA324 /* OFString+JSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OFString+JSONValue.m"; path = "src/OFString+JSONValue.m"; sourceTree = ""; }; + 4B60259919B76A5C00694BCC /* OFSHA384Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSHA384Hash.h; path = src/OFSHA384Hash.h; sourceTree = ""; }; + 4B60259A19B76A5C00694BCC /* OFSHA384Hash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA384Hash.m; path = src/OFSHA384Hash.m; sourceTree = ""; }; + 4B60259B19B76A5C00694BCC /* OFSHA384Or512Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSHA384Or512Hash.h; path = src/OFSHA384Or512Hash.h; sourceTree = ""; }; + 4B60259C19B76A5C00694BCC /* OFSHA384Or512Hash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA384Or512Hash.m; path = src/OFSHA384Or512Hash.m; sourceTree = ""; }; + 4B60259D19B76A5C00694BCC /* OFSHA512Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFSHA512Hash.h; path = src/OFSHA512Hash.h; sourceTree = ""; }; + 4B60259E19B76A5C00694BCC /* OFSHA512Hash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA512Hash.m; path = src/OFSHA512Hash.m; sourceTree = ""; }; + 4B6025A519B76B5000694BCC /* OFSHA384HashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA384HashTests.m; path = tests/OFSHA384HashTests.m; sourceTree = ""; }; + 4B6025A619B76B5000694BCC /* OFSHA512HashTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFSHA512HashTests.m; path = tests/OFSHA512HashTests.m; sourceTree = ""; }; 4B62ED1318566FCA0004E0E3 /* OFCopyItemFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFCopyItemFailedException.h; path = src/exceptions/OFCopyItemFailedException.h; sourceTree = ""; }; 4B62ED1418566FCA0004E0E3 /* OFCopyItemFailedException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFCopyItemFailedException.m; path = src/exceptions/OFCopyItemFailedException.m; sourceTree = ""; }; 4B66B634182ADC45000A69E3 /* OFDeflate64Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFDeflate64Stream.h; path = src/OFDeflate64Stream.h; sourceTree = ""; }; 4B66B635182ADC45000A69E3 /* OFDeflate64Stream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OFDeflate64Stream.m; path = src/OFDeflate64Stream.m; sourceTree = ""; }; 4B6743EB163C384A00EB1E59 /* OFLockFailedException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OFLockFailedException.h; path = src/exceptions/OFLockFailedException.h; sourceTree = ""; }; @@ -1355,10 +1371,16 @@ 4B24592719B5397C0059F271 /* OFSHA224Hash.m */, 4B24592819B5397C0059F271 /* OFSHA224Or256Hash.h */, 4B24592919B5397C0059F271 /* OFSHA224Or256Hash.m */, 4B3B03E919B3F70500F70C05 /* OFSHA256Hash.h */, 4B3B03EA19B3F70500F70C05 /* OFSHA256Hash.m */, + 4B60259919B76A5C00694BCC /* OFSHA384Hash.h */, + 4B60259A19B76A5C00694BCC /* OFSHA384Hash.m */, + 4B60259B19B76A5C00694BCC /* OFSHA384Or512Hash.h */, + 4B60259C19B76A5C00694BCC /* OFSHA384Or512Hash.m */, + 4B60259D19B76A5C00694BCC /* OFSHA512Hash.h */, + 4B60259E19B76A5C00694BCC /* OFSHA512Hash.m */, 4B141BA215FCDF74000C21A8 /* OFSortedList.h */, 4B141BA315FCDF74000C21A8 /* OFSortedList.m */, 4B0256E2172B60400062B5F1 /* OFStdIOStream.h */, 4B0256E3172B60400062B5F1 /* OFStdIOStream.m */, 4B67997D1099E7C50041064A /* OFStream.h */, @@ -1481,10 +1503,12 @@ 4B3D5693139A617D0010A78F /* OFSerializationTests.m */, 4B4B6903191437D500334775 /* OFSetTests.m */, 4B6EF6771235358D0076B512 /* OFSHA1HashTests.m */, 4B24592E19B53BC80059F271 /* OFSHA224HashTests.m */, 4B24592F19B53BC80059F271 /* OFSHA256HashTests.m */, + 4B6025A519B76B5000694BCC /* OFSHA384HashTests.m */, + 4B6025A619B76B5000694BCC /* OFSHA512HashTests.m */, 4B6EF6781235358D0076B512 /* OFStreamTests.m */, 4B6EF6791235358D0076B512 /* OFStringTests.m */, 4B6EF67A1235358D0076B512 /* OFTCPSocketTests.m */, 4B6EF67B1235358D0076B512 /* OFThreadTests.m */, 4B0EA924189869D900F573A4 /* OFUDPSocketTests.m */, @@ -1626,10 +1650,13 @@ 4B8385181951BF9500D5358A /* OFSettings.h in Headers */, 4B3D23D41337FCB000DD29B8 /* OFSHA1Hash.h in Headers */, 4B24592A19B5397C0059F271 /* OFSHA224Hash.h in Headers */, 4B24592C19B5397C0059F271 /* OFSHA224Or256Hash.h in Headers */, 4B3B03EB19B3F70500F70C05 /* OFSHA256Hash.h in Headers */, + 4B60259F19B76A5C00694BCC /* OFSHA384Hash.h in Headers */, + 4B6025A119B76A5C00694BCC /* OFSHA384Or512Hash.h in Headers */, + 4B6025A319B76A5C00694BCC /* OFSHA512Hash.h in Headers */, 4B141BA415FCDF74000C21A8 /* OFSortedList.h in Headers */, 4B0256E4172B60400062B5F1 /* OFStdIOStream.h in Headers */, 4B3D23D51337FCB000DD29B8 /* OFStream.h in Headers */, 4B3D23D71337FCB000DD29B8 /* OFStreamSocket.h in Headers */, 4B3D23D81337FCB000DD29B8 /* OFString.h in Headers */, @@ -2003,10 +2030,13 @@ 4B8385171951BF9500D5358A /* OFSettings_INIFile.m in Sources */, 4B3D23A21337FC0D00DD29B8 /* OFSHA1Hash.m in Sources */, 4B24592B19B5397C0059F271 /* OFSHA224Hash.m in Sources */, 4B24592D19B5397C0059F271 /* OFSHA224Or256Hash.m in Sources */, 4B3B03EC19B3F70500F70C05 /* OFSHA256Hash.m in Sources */, + 4B6025A019B76A5C00694BCC /* OFSHA384Hash.m in Sources */, + 4B6025A219B76A5C00694BCC /* OFSHA384Or512Hash.m in Sources */, + 4B6025A419B76A5C00694BCC /* OFSHA512Hash.m in Sources */, 4B141BA515FCDF74000C21A8 /* OFSortedList.m in Sources */, 4B0256E5172B60400062B5F1 /* OFStdIOStream.m in Sources */, 4B3D23A31337FC0D00DD29B8 /* OFStream.m in Sources */, 4B3D23A51337FC0D00DD29B8 /* OFStreamSocket.m in Sources */, 4B3D23A61337FC0D00DD29B8 /* OFString.m in Sources */, @@ -2123,12 +2153,14 @@ 4BF33B03133807A20059CEF7 /* OFListTests.m in Sources */, 4BF33B04133807A20059CEF7 /* OFMD5HashTests.m in Sources */, 4BF33B05133807A20059CEF7 /* OFNumberTests.m in Sources */, 4BF33B06133807A20059CEF7 /* OFObjectTests.m in Sources */, 4BF33B07133807A20059CEF7 /* OFPluginTests.m in Sources */, + 4B6025A819B76B5000694BCC /* OFSHA512HashTests.m in Sources */, 4B3D5694139A617D0010A78F /* OFSerializationTests.m in Sources */, 4B4B6904191437D500334775 /* OFSetTests.m in Sources */, + 4B6025A719B76B5000694BCC /* OFSHA384HashTests.m in Sources */, 4BF33B08133807A20059CEF7 /* OFSHA1HashTests.m in Sources */, 4B24593019B53BC80059F271 /* OFSHA224HashTests.m in Sources */, 4B24593119B53BC80059F271 /* OFSHA256HashTests.m in Sources */, 4BF33B09133807A20059CEF7 /* OFStreamTests.m in Sources */, 4BF33B0A133807A20059CEF7 /* OFStringTests.m in Sources */, Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -45,10 +45,13 @@ OFSet.m \ OFSHA1Hash.m \ OFSHA224Hash.m \ OFSHA224Or256Hash.m \ OFSHA256Hash.m \ + OFSHA384Hash.m \ + OFSHA384Or512Hash.m \ + OFSHA512Hash.m \ OFSortedList.m \ OFStdIOStream.m \ OFStream.m \ OFString.m \ OFString+Hashing.m \ Index: src/OFDataArray+Hashing.h ================================================================== --- src/OFDataArray+Hashing.h +++ src/OFDataArray+Hashing.h @@ -54,6 +54,22 @@ * OFString. * * @return The SHA-256 hash of the data array as an autoreleased OFString */ - (OFString*)SHA256Hash; + +/*! + * @brief Returns the SHA-384 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-384 hash of the data array as an autoreleased OFString + */ +- (OFString*)SHA384Hash; + +/*! + * @brief Returns the SHA-512 hash of the data array as an autoreleased + * OFString. + * + * @return The SHA-512 hash of the data array as an autoreleased OFString + */ +- (OFString*)SHA512Hash; @end Index: src/OFDataArray+Hashing.m ================================================================== --- src/OFDataArray+Hashing.m +++ src/OFDataArray+Hashing.m @@ -21,10 +21,12 @@ #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" +#import "OFSHA384Hash.h" +#import "OFSHA512Hash.h" int _OFDataArray_Hashing_reference; @implementation OFDataArray (Hashing) - (OFString*)OF_hashAsStringWithHash: (Class )hashClass @@ -74,6 +76,16 @@ - (OFString*)SHA256Hash { return [self OF_hashAsStringWithHash: [OFSHA256Hash class]]; } + +- (OFString*)SHA384Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA384Hash class]]; +} + +- (OFString*)SHA512Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA512Hash class]]; +} @end ADDED src/OFSHA384Hash.h Index: src/OFSHA384Hash.h ================================================================== --- src/OFSHA384Hash.h +++ src/OFSHA384Hash.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSHA384Or512Hash.h" + +/*! + * @class OFSHA384Hash OFSHA384Hash.h ObjFW/OFSHA384Hash.h + * + * @brief A class which provides functions to create an SHA-384 hash. + */ +@interface OFSHA384Hash: OFSHA384Or512Hash +@end ADDED src/OFSHA384Hash.m Index: src/OFSHA384Hash.m ================================================================== --- src/OFSHA384Hash.m +++ src/OFSHA384Hash.m @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSHA384Hash.h" + +@implementation OFSHA384Hash ++ (size_t)digestSize +{ + return 48; +} + +- init +{ + self = [super init]; + + _state[0] = 0xCBBB9D5DC1059ED8; + _state[1] = 0x629A292A367CD507; + _state[2] = 0x9159015A3070DD17; + _state[3] = 0x152FECD8F70E5939; + _state[4] = 0x67332667FFC00B31; + _state[5] = 0x8EB44A8768581511; + _state[6] = 0xDB0C2E0D64F98FA7; + _state[7] = 0x47B5481DBEFA4FA4; + + return self; +} +@end ADDED src/OFSHA384Or512Hash.h Index: src/OFSHA384Or512Hash.h ================================================================== --- src/OFSHA384Or512Hash.h +++ src/OFSHA384Or512Hash.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFHash.h" + +/*! + * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h + * + * @brief A base class for SHA-384 and SHA-512. + */ +@interface OFSHA384Or512Hash: OFObject +{ + uint64_t _state[8]; + uint64_t _bits[2]; + union { + uint8_t bytes[128]; + uint64_t words[80]; + } _buffer; + size_t _bufferLength; + bool _calculated; +} +@end ADDED src/OFSHA384Or512Hash.m Index: src/OFSHA384Or512Hash.m ================================================================== --- src/OFSHA384Or512Hash.m +++ src/OFSHA384Or512Hash.m @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include +#include + +#import "OFSHA384Or512Hash.h" + +#import "OFHashAlreadyCalculatedException.h" + +static const uint64_t table[] = { + 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, + 0xE9B5DBA58189DBBC, 0x3956C25BF348B538, 0x59F111F1B605D019, + 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118, 0xD807AA98A3030242, + 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2, + 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, + 0xC19BF174CF692694, 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, + 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65, 0x2DE92C6F592B0275, + 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5, + 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, + 0xBF597FC7BEEF0EE4, 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, + 0x06CA6351E003826F, 0x142929670A0E6E70, 0x27B70A8546D22FFC, + 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF, + 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, + 0x92722C851482353B, 0xA2BFE8A14CF10364, 0xA81A664BBC423001, + 0xC24B8B70D0F89791, 0xC76C51A30654BE30, 0xD192E819D6EF5218, + 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8, + 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, + 0x34B0BCB5E19B48A8, 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, + 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3, 0x748F82EE5DEFB2FC, + 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC, + 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, + 0xC67178F2E372532B, 0xCA273ECEEA26619C, 0xD186B8C721C0C207, + 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178, 0x06F067AA72176FBA, + 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B, + 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, + 0x431D67C49C100D4C, 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, + 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 +}; + +static void +byteSwapVectorIfLE(uint64_t *vector, uint_fast8_t length) +{ + uint_fast8_t i; + + for (i = 0; i < length; i++) + vector[i] = OF_BSWAP64_IF_LE(vector[i]); +} + +static void +processBlock(uint64_t *state, uint64_t *buffer) +{ + uint64_t new[8]; + uint_fast8_t i; + + new[0] = state[0]; + new[1] = state[1]; + new[2] = state[2]; + new[3] = state[3]; + new[4] = state[4]; + new[5] = state[5]; + new[6] = state[6]; + new[7] = state[7]; + + byteSwapVectorIfLE(buffer, 16); + + for (i = 16; i < 80; i++) { + uint64_t tmp; + + tmp = buffer[i - 2]; + buffer[i] = (OF_ROR(tmp, 19) ^ OF_ROR(tmp, 61) ^ (tmp >> 6)) + + buffer[i - 7]; + tmp = buffer[i - 15]; + buffer[i] += (OF_ROR(tmp, 1) ^ OF_ROR(tmp, 8) ^ (tmp >> 7)) + + buffer[i - 16]; + } + + for (i = 0; i < 80; i++) { + uint64_t tmp1 = new[7] + (OF_ROR(new[4], 14) ^ + OF_ROR(new[4], 18) ^ OF_ROR(new[4], 41)) + + ((new[4] & (new[5] ^ new[6])) ^ new[6]) + + table[i] + buffer[i]; + uint64_t tmp2 = (OF_ROR(new[0], 28) ^ OF_ROR(new[0], 34) ^ + OF_ROR(new[0], 39)) + + ((new[0] & (new[1] | new[2])) | (new[1] & new[2])); + + new[7] = new[6]; + new[6] = new[5]; + new[5] = new[4]; + new[4] = new[3] + tmp1; + new[3] = new[2]; + new[2] = new[1]; + new[1] = new[0]; + new[0] = tmp1 + tmp2; + } + + state[0] += new[0]; + state[1] += new[1]; + state[2] += new[2]; + state[3] += new[3]; + state[4] += new[4]; + state[5] += new[5]; + state[6] += new[6]; + state[7] += new[7]; +} + +@implementation OFSHA384Or512Hash ++ (size_t)digestSize +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (size_t)blockSize +{ + return 128; +} + ++ (instancetype)hash +{ + return [[[self alloc] init] autorelease]; +} + +- init +{ + if (object_getClass(self) == [OFSHA384Or512Hash class]) { + @try { + [self doesNotRecognizeSelector: _cmd]; + } @catch (id e) { + [self release]; + @throw e; + } + + abort(); + } + + return [super init]; +} + +- (void)updateWithBuffer: (const void*)buffer_ + length: (size_t)length +{ + const uint8_t *buffer = buffer_; + + if (_calculated) + @throw [OFHashAlreadyCalculatedException + exceptionWithHash: self]; + + if (UINT64_MAX - _bits[0] < (length * 8)) + _bits[1]++; + _bits[0] += (length * 8); + + while (length > 0) { + size_t min = 128 - _bufferLength; + + if (min > length) + min = length; + + memcpy(_buffer.bytes + _bufferLength, buffer, min); + _bufferLength += min; + + buffer += min; + length -= min; + + if (_bufferLength == 128) { + processBlock(_state, _buffer.words); + _bufferLength = 0; + } + } +} + +- (const uint8_t*)digest +{ + if (_calculated) + return (const uint8_t*)_state; + + _buffer.bytes[_bufferLength] = 0x80; + memset(_buffer.bytes + _bufferLength + 1, 0, 128 - _bufferLength - 1); + + if (_bufferLength >= 112) { + processBlock(_state, _buffer.words); + memset(_buffer.bytes, 0, 128); + } + + _buffer.words[14] = OF_BSWAP64_IF_LE(_bits[1]); + _buffer.words[15] = OF_BSWAP64_IF_LE(_bits[0]); + + processBlock(_state, _buffer.words); + memset(&_buffer, 0, sizeof(_buffer)); + byteSwapVectorIfLE(_state, 8); + _calculated = true; + + return (const uint8_t*)_state; +} + +- (bool)isCalculated +{ + return _calculated; +} +@end ADDED src/OFSHA512Hash.h Index: src/OFSHA512Hash.h ================================================================== --- src/OFSHA512Hash.h +++ src/OFSHA512Hash.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSHA384Or512Hash.h" + +/*! + * @class OFSHA512Hash OFSHA512Hash.h ObjFW/OFSHA512Hash.h + * + * @brief A class which provides functions to create an SHA-512 hash. + */ +@interface OFSHA512Hash: OFSHA384Or512Hash +@end ADDED src/OFSHA512Hash.m Index: src/OFSHA512Hash.m ================================================================== --- src/OFSHA512Hash.m +++ src/OFSHA512Hash.m @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFSHA512Hash.h" + +@implementation OFSHA512Hash ++ (size_t)digestSize +{ + return 64; +} + +- init +{ + self = [super init]; + + _state[0] = 0x6A09E667F3BCC908; + _state[1] = 0xBB67AE8584CAA73B; + _state[2] = 0x3C6EF372FE94F82B; + _state[3] = 0xA54FF53A5F1D36F1; + _state[4] = 0x510E527FADE682D1; + _state[5] = 0x9B05688C2B3E6C1F; + _state[6] = 0x1F83D9ABFB41BD6B; + _state[7] = 0x5BE0CD19137E2179; + + return self; +} +@end Index: src/OFString+Hashing.h ================================================================== --- src/OFString+Hashing.h +++ src/OFString+Hashing.h @@ -50,6 +50,20 @@ * @brief Returns the SHA-256 hash of the string as an autoreleased OFString. * * @return The SHA-256 hash of the string as an autoreleased OFString */ - (OFString*)SHA256Hash; + +/*! + * @brief Returns the SHA-384 hash of the string as an autoreleased OFString. + * + * @return The SHA-384 hash of the string as an autoreleased OFString + */ +- (OFString*)SHA384Hash; + +/*! + * @brief Returns the SHA-512 hash of the string as an autoreleased OFString. + * + * @return The SHA-512 hash of the string as an autoreleased OFString + */ +- (OFString*)SHA512Hash; @end Index: src/OFString+Hashing.m ================================================================== --- src/OFString+Hashing.m +++ src/OFString+Hashing.m @@ -20,10 +20,12 @@ #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" +#import "OFSHA384Hash.h" +#import "OFSHA512Hash.h" int _OFString_Hashing_reference; @implementation OFString (Hashing) - (OFString*)OF_hashAsStringWithHash: (Class )hashClass @@ -73,6 +75,16 @@ - (OFString*)SHA256Hash { return [self OF_hashAsStringWithHash: [OFSHA256Hash class]]; } + +- (OFString*)SHA384Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA384Hash class]]; +} + +- (OFString*)SHA512Hash +{ + return [self OF_hashAsStringWithHash: [OFSHA512Hash class]]; +} @end Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -74,10 +74,12 @@ #import "OFHash.h" #import "OFMD5Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" +#import "OFSHA384Hash.h" +#import "OFSHA512Hash.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -35,11 +35,13 @@ SRCS_FILES = OFINIFileTests.m \ OFMD5HashTests.m \ OFSerializationTests.m \ OFSHA1HashTests.m \ OFSHA224HashTests.m \ - OFSHA256HashTests.m + OFSHA256HashTests.m \ + OFSHA384HashTests.m \ + OFSHA512HashTests.m SRCS_PLUGINS = OFPluginTests.m SRCS_SOCKETS = OFTCPSocketTests.m \ OFUDPSocketTests.m SRCS_THREADS = OFThreadTests.m Index: tests/OFDataArrayTests.m ================================================================== --- tests/OFDataArrayTests.m +++ tests/OFDataArrayTests.m @@ -108,10 +108,16 @@ TEST(@"-[SHA224Hash]", [[array[0] SHA224Hash] isEqual: [@"abcde" SHA224Hash]]) TEST(@"-[SHA256Hash]", [[array[0] SHA256Hash] isEqual: [@"abcde" SHA256Hash]]) + + TEST(@"-[SHA384Hash]", [[array[0] SHA384Hash] + isEqual: [@"abcde" SHA384Hash]]) + + TEST(@"-[SHA512Hash]", [[array[0] SHA512Hash] + isEqual: [@"abcde" SHA512Hash]]) TEST(@"-[stringByBase64Encoding]", [[array[0] stringByBase64Encoding] isEqual: @"YWJjZGU="]) TEST(@"+[dataArrayWithBase64EncodedString:]", ADDED tests/OFSHA384HashTests.m Index: tests/OFSHA384HashTests.m ================================================================== --- tests/OFSHA384HashTests.m +++ tests/OFSHA384HashTests.m @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include + +#import "OFSHA384Hash.h" +#import "OFString.h" +#import "OFFile.h" +#import "OFAutoreleasePool.h" + +#import "OFHashAlreadyCalculatedException.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFSHA384Hash"; + +const uint8_t testfile_sha384[48] = + "\x7E\xDE\x62\xE2\x10\xA5\x1E\x18\x8A\x11\x7F\x78\xD7\xC7\x55\xB6\x43" + "\x94\x1B\xD2\x78\x5C\xCF\xF3\x8A\xB8\x98\x22\xC7\x0E\xFE\xF1\xEC\x53" + "\xE9\x1A\xB3\x51\x70\x8C\x1F\x3F\x56\x12\x44\x01\x91\x54"; + +@implementation TestsAppDelegate (SHA384HashTests) +- (void)SHA384HashTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFSHA384Hash *sha384; + OFFile *f = [OFFile fileWithPath: @"testfile.bin" + mode: @"rb"]; + + TEST(@"+[hash]", (sha384 = [OFSHA384Hash hash])) + + while (![f isAtEndOfStream]) { + char buf[128]; + size_t len = [f readIntoBuffer: buf + length: 128]; + [sha384 updateWithBuffer: buf + length: len]; + } + [f close]; + + TEST(@"-[digest]", !memcmp([sha384 digest], testfile_sha384, 48)) + + EXPECT_EXCEPTION(@"Detect invalid call of " + @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, + [sha384 updateWithBuffer: "" + length: 1]) + + [pool drain]; +} +@end ADDED tests/OFSHA512HashTests.m Index: tests/OFSHA512HashTests.m ================================================================== --- tests/OFSHA512HashTests.m +++ tests/OFSHA512HashTests.m @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include + +#import "OFSHA512Hash.h" +#import "OFString.h" +#import "OFFile.h" +#import "OFAutoreleasePool.h" + +#import "OFHashAlreadyCalculatedException.h" + +#import "TestsAppDelegate.h" + +static OFString *module = @"OFSHA512Hash"; + +const uint8_t testfile_sha512[64] = + "\x8F\x36\x6E\x3C\x19\x4B\xBB\xC7\x82\xAA\xCD\x7D\x55\xA2\xD3\x29\x29" + "\x97\x6A\x3F\xEB\x9B\xB2\xCB\x75\xC9\xEC\xC8\x10\x07\xD6\x07\x31\x4A" + "\xB1\x30\x97\x82\x58\xA5\x1F\x71\x42\xE6\x56\x07\x99\x57\xB2\xB8\x3B" + "\xA1\x8A\x41\x64\x33\x69\x21\x8C\x2A\x44\x6D\xF2\xA0"; + +@implementation TestsAppDelegate (SHA512HashTests) +- (void)SHA512HashTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFSHA512Hash *sha512; + OFFile *f = [OFFile fileWithPath: @"testfile.bin" + mode: @"rb"]; + + TEST(@"+[hash]", (sha512 = [OFSHA512Hash hash])) + + while (![f isAtEndOfStream]) { + char buf[128]; + size_t len = [f readIntoBuffer: buf + length: 128]; + [sha512 updateWithBuffer: buf + length: len]; + } + [f close]; + + TEST(@"-[digest]", !memcmp([sha512 digest], testfile_sha512, 64)) + + EXPECT_EXCEPTION(@"Detect invalid call of " + @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, + [sha512 updateWithBuffer: "" + length: 1]) + + [pool drain]; +} +@end Index: tests/OFStringTests.m ================================================================== --- tests/OFStringTests.m +++ tests/OFStringTests.m @@ -542,14 +542,21 @@ TEST(@"-[SHA224Hash]", [[@"asdfoobar" SHA224Hash] isEqual: @"5a06822dcbd5a874f67d062b80b9d8a9cb9b5b303960b9da9290c192"]) - TEST(@"-[SHA256Hash]", [[@"asdfoobar" SHA256Hash] - isEqual: - @"28e65b1dcd7f6ce2ea6277b15f87b913628b5500bf7913a2bbf4cedcfa1215f6" - ]) + TEST(@"-[SHA256Hash]", [[@"asdfoobar" SHA256Hash] isEqual: + @"28e65b1dcd7f6ce2ea6277b15f87b913" + @"628b5500bf7913a2bbf4cedcfa1215f6"]) + + TEST(@"-[SHA384Hash]", [[@"asdfoobar" SHA384Hash] isEqual: + @"73286da882ffddca2f45e005cfa6b44f3fc65bfb26db1d08" + @"7ded2f9c279e5addf8be854044bca0cece073fce28eec7d9"]) + + TEST(@"-[SHA512Hash]", [[@"asdfoobar" SHA512Hash] isEqual: + @"0464c427da158b02161bb44a3090bbfc594611ef6a53603640454b56412a9247c" + @"3579a329e53a5dc74676b106755e3394f9454a2d42273242615d32f80437d61"]) TEST(@"-[stringByURLEncoding]", [[@"foo\"ba'_~$" stringByURLEncoding] isEqual: @"foo%22ba%27_%7E$"]) TEST(@"-[stringByURLDecoding]", Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -149,10 +149,18 @@ @end @interface TestsAppDelegate (OFSHA256HashTests) - (void)SHA256HashTests; @end + +@interface TestsAppDelegate (OFSHA384HashTests) +- (void)SHA384HashTests; +@end + +@interface TestsAppDelegate (OFSHA512HashTests) +- (void)SHA512HashTests; +@end @interface TestsAppDelegate (OFStreamTests) - (void)streamTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -341,10 +341,12 @@ #ifdef OF_HAVE_FILES [self MD5HashTests]; [self SHA1HashTests]; [self SHA224HashTests]; [self SHA256HashTests]; + [self SHA384HashTests]; + [self SHA512HashTests]; [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self TCPSocketTests]; [self UDPSocketTests];