Skip to content

Commit

Permalink
feat(jws): introduce new methods to use data and seckey as keys
Browse files Browse the repository at this point in the history
This will enable with JWS, not to require parsing Data or SecKeys to JWT format.
This in part requires that the JWS Header provides alg, and cannot be used in JWE.

- This commit also documents and makes public the JWA algorithms.
  • Loading branch information
beatt83 committed May 29, 2024
1 parent d60826c commit 1af633d
Show file tree
Hide file tree
Showing 82 changed files with 1,796 additions and 345 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,21 @@

import Foundation

struct Zip: ContentCompressor, ContentDecompressor {
func compress(input: Data) throws -> Data {
/// `Zip` provides methods to compress and decompress data using zlib.
public struct Zip: ContentCompressor, ContentDecompressor {
/// Compresses the input data using zlib.
/// - Parameter input: The data to be compressed.
/// - Throws: An error if the compression fails.
/// - Returns: The compressed data.
public func compress(input: Data) throws -> Data {
try (input as NSData).compressed(using: .zlib) as Data
}

func decompress(input: Data) throws -> Data {
/// Decompresses the input data using zlib.
/// - Parameter input: The data to be decompressed.
/// - Throws: An error if the decompression fails.
/// - Returns: The decompressed data.
public func decompress(input: Data) throws -> Data {
try (input as NSData).decompressed(using: .zlib) as Data
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,37 @@
import CryptoKit
import Foundation

struct AES128GCM: ContentEncryptor, ContentDecryptor {
/// `AES128GCM` provides methods to encrypt and decrypt data using AES-128-GCM.
public struct AES128GCM: ContentEncryptor, ContentDecryptor {
/// The content encryption algorithm used, represented as a string.
public let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a128GCM.rawValue
/// The size of the initialization vector in bits.
public let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a128GCM.initializationVectorSizeInBits
/// The size of the content encryption key (CEK) in bits.
public let cekKeySize: Int = ContentEncryptionAlgorithm.a128GCM.keySizeInBits

let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a128GCM.rawValue
let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a128GCM.initializationVectorSizeInBits
let cekKeySize: Int = ContentEncryptionAlgorithm.a128GCM.keySizeInBits

func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits)
/// Generates a random initialization vector.
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the initialization vector.
public func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits / 8)
}

func generateCEK() throws -> Data {
/// Generates a random content encryption key (CEK).
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the CEK.
public func generateCEK() throws -> Data {
try SecureRandom.secureRandomData(count: cekKeySize / 8)
}

func encrypt(
/// Encrypts the payload using AES-128-GCM.
/// - Parameters:
/// - payload: The data to be encrypted.
/// - key: The encryption key.
/// - arguments: Additional encryption arguments, such as initialization vector and additional authenticated data.
/// - Throws: An error if the encryption fails.
/// - Returns: A `ContentEncryptionResult` containing the cipher text and authentication tag.
public func encrypt(
payload: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand All @@ -45,7 +61,14 @@ struct AES128GCM: ContentEncryptor, ContentDecryptor {
return .init(cipher: cipher, authenticationData: tag)
}

func decrypt(
/// Decrypts the cipher text using AES-128-GCM.
/// - Parameters:
/// - cipher: The data to be decrypted.
/// - key: The decryption key.
/// - arguments: Additional decryption arguments, such as initialization vector and authentication tag.
/// - Throws: An error if the decryption fails.
/// - Returns: The decrypted data.
public func decrypt(
cipher: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,37 @@
import CryptoKit
import Foundation

struct AES192GCM: ContentEncryptor, ContentDecryptor {
let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a192GCM.rawValue
let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a192GCM.initializationVectorSizeInBits
let cekKeySize: Int = ContentEncryptionAlgorithm.a192GCM.keySizeInBits
/// `AES192GCM` provides methods to encrypt and decrypt data using AES-192-GCM.
public struct AES192GCM: ContentEncryptor, ContentDecryptor {
/// The content encryption algorithm used, represented as a string.
public let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a192GCM.rawValue
/// The size of the initialization vector in bits.
public let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a192GCM.initializationVectorSizeInBits
/// The size of the content encryption key (CEK) in bits.
public let cekKeySize: Int = ContentEncryptionAlgorithm.a192GCM.keySizeInBits

func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits)
/// Generates a random initialization vector.
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the initialization vector.
public func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits / 8)
}

func generateCEK() throws -> Data {
/// Generates a random content encryption key (CEK).
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the CEK.
public func generateCEK() throws -> Data {
try SecureRandom.secureRandomData(count: cekKeySize / 8)
}

func encrypt(
/// Encrypts the payload using AES-192-GCM.
/// - Parameters:
/// - payload: The data to be encrypted.
/// - key: The encryption key.
/// - arguments: Additional encryption arguments, such as initialization vector and additional authenticated data.
/// - Throws: An error if the encryption fails.
/// - Returns: A `ContentEncryptionResult` containing the cipher text and authentication tag.
public func encrypt(
payload: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand All @@ -44,7 +61,14 @@ struct AES192GCM: ContentEncryptor, ContentDecryptor {
return .init(cipher: cipher, authenticationData: tag)
}

func decrypt(
/// Decrypts the cipher text using AES-192-GCM.
/// - Parameters:
/// - cipher: The data to be decrypted.
/// - key: The decryption key.
/// - arguments: Additional decryption arguments, such as initialization vector and authentication tag.
/// - Throws: An error if the decryption fails.
/// - Returns: The decrypted data.
public func decrypt(
cipher: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,37 @@
import CryptoKit
import Foundation

struct AES256GCM: ContentEncryptor, ContentDecryptor {
/// `AES256GCM` provides methods to encrypt and decrypt data using AES-256-GCM.
public struct AES256GCM: ContentEncryptor, ContentDecryptor {
/// The content encryption algorithm used, represented as a string.
public let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a256GCM.rawValue
/// The size of the initialization vector in bits.
public let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a256GCM.initializationVectorSizeInBits
/// The size of the content encryption key (CEK) in bits.
public let cekKeySize: Int = ContentEncryptionAlgorithm.a256GCM.keySizeInBits

let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a256GCM.rawValue
let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a256GCM.initializationVectorSizeInBits
let cekKeySize: Int = ContentEncryptionAlgorithm.a256GCM.keySizeInBits

func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits)
/// Generates a random initialization vector.
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the initialization vector.
public func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits / 8)
}

func generateCEK() throws -> Data {
/// Generates a random content encryption key (CEK).
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the CEK.
public func generateCEK() throws -> Data {
try SecureRandom.secureRandomData(count: cekKeySize / 8)
}

func encrypt(
/// Encrypts the payload using AES-256-GCM.
/// - Parameters:
/// - payload: The data to be encrypted.
/// - key: The encryption key.
/// - arguments: Additional encryption arguments, such as initialization vector and additional authenticated data.
/// - Throws: An error if the encryption fails.
/// - Returns: A `ContentEncryptionResult` containing the cipher text and authentication tag.
public func encrypt(
payload: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand All @@ -45,7 +61,14 @@ struct AES256GCM: ContentEncryptor, ContentDecryptor {
return .init(cipher: cipher, authenticationData: tag)
}

func decrypt(
/// Decrypts the cipher text using AES-256-GCM.
/// - Parameters:
/// - cipher: The data to be decrypted.
/// - key: The decryption key.
/// - arguments: Additional decryption arguments, such as initialization vector and authentication tag.
/// - Throws: An error if the decryption fails.
/// - Returns: The decrypted data.
public func decrypt(
cipher: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,37 @@ import CryptoKit
import Foundation
import JSONWebKey

struct AESCBC_SHA256: ContentEncryptor, ContentDecryptor {
/// `AESCBC_SHA256` provides methods to encrypt and decrypt data using AES-CBC with SHA-256 for authentication.
public struct AESCBC_SHA256: ContentEncryptor, ContentDecryptor {
/// The content encryption algorithm used, represented as a string.
public let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a128CBCHS256.rawValue
/// The size of the initialization vector in bits.
public let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a128CBCHS256.initializationVectorSizeInBits
/// The size of the content encryption key (CEK) in bits.
public let cekKeySize: Int = ContentEncryptionAlgorithm.a128CBCHS256.keySizeInBits

let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a128CBCHS256.rawValue
let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a128CBCHS256.initializationVectorSizeInBits
let cekKeySize: Int = ContentEncryptionAlgorithm.a128CBCHS256.keySizeInBits

func generateInitializationVector() throws -> Data {
/// Generates a random initialization vector.
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the initialization vector.
public func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits / 8)
}

func generateCEK() throws -> Data {
/// Generates a random content encryption key (CEK).
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the CEK.
public func generateCEK() throws -> Data {
try SecureRandom.secureRandomData(count: cekKeySize / 8)
}

func encrypt(
/// Encrypts the payload using AES-CBC with SHA-256 for authentication.
/// - Parameters:
/// - payload: The data to be encrypted.
/// - key: The encryption key.
/// - arguments: Additional encryption arguments, such as initialization vector and additional authenticated data.
/// - Throws: An error if the encryption fails or if the initialization vector is missing or of incorrect size.
/// - Returns: A `ContentEncryptionResult` containing the cipher text and authentication tag.
public func encrypt(
payload: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down Expand Up @@ -60,7 +76,14 @@ struct AESCBC_SHA256: ContentEncryptor, ContentDecryptor {
return .init(cipher: cipher, authenticationData: tag)
}

func decrypt(
/// Decrypts the cipher text using AES-CBC with SHA-256 for authentication.
/// - Parameters:
/// - cipher: The data to be decrypted.
/// - key: The decryption key.
/// - arguments: Additional decryption arguments, such as initialization vector and authentication tag.
/// - Throws: An error if the decryption fails or if required arguments are missing.
/// - Returns: The decrypted data.
public func decrypt(
cipher: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand All @@ -79,7 +102,7 @@ struct AESCBC_SHA256: ContentEncryptor, ContentDecryptor {

return try AESCBC_SHA<SHA256>.decrypt(
cipher: cipher,
cek: key,
cek: key,
authenticationTagLength: 16,
initializationVector: iv,
additionalAuthenticatedData: aad,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,37 @@
import CryptoKit
import Foundation

struct AESCBC_SHA384: ContentEncryptor, ContentDecryptor {
/// `AESCBC_SHA384` provides methods to encrypt and decrypt data using AES-CBC with SHA-384 for authentication.
public struct AESCBC_SHA384: ContentEncryptor, ContentDecryptor {
/// The content encryption algorithm used, represented as a string.
public let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a192CBCHS384.rawValue
/// The size of the initialization vector in bits.
public let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a192CBCHS384.initializationVectorSizeInBits
/// The size of the content encryption key (CEK) in bits.
public let cekKeySize: Int = ContentEncryptionAlgorithm.a192CBCHS384.keySizeInBits

let contentEncryptionAlgorithm: String = ContentEncryptionAlgorithm.a192CBCHS384.rawValue
let initializationVectorSizeInBits: Int = ContentEncryptionAlgorithm.a192CBCHS384.initializationVectorSizeInBits
let cekKeySize: Int = ContentEncryptionAlgorithm.a192CBCHS384.keySizeInBits

func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits)
/// Generates a random initialization vector.
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the initialization vector.
public func generateInitializationVector() throws -> Data {
try SecureRandom.secureRandomData(count: initializationVectorSizeInBits / 8)
}

func generateCEK() throws -> Data {
/// Generates a random content encryption key (CEK).
/// - Throws: An error if the random data generation fails.
/// - Returns: A data object containing the CEK.
public func generateCEK() throws -> Data {
try SecureRandom.secureRandomData(count: cekKeySize / 8)
}

func encrypt(
/// Encrypts the payload using AES-CBC with SHA-384 for authentication.
/// - Parameters:
/// - payload: The data to be encrypted.
/// - key: The encryption key.
/// - arguments: Additional encryption arguments, such as initialization vector and additional authenticated data.
/// - Throws: An error if the encryption fails or if the initialization vector is missing or of incorrect size.
/// - Returns: A `ContentEncryptionResult` containing the cipher text and authentication tag.
public func encrypt(
payload: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down Expand Up @@ -59,7 +75,14 @@ struct AESCBC_SHA384: ContentEncryptor, ContentDecryptor {
return .init(cipher: cipher, authenticationData: tag)
}

func decrypt(
/// Decrypts the cipher text using AES-CBC with SHA-384 for authentication.
/// - Parameters:
/// - cipher: The data to be decrypted.
/// - key: The decryption key.
/// - arguments: Additional decryption arguments, such as initialization vector and authentication tag.
/// - Throws: An error if the decryption fails or if required arguments are missing.
/// - Returns: The decrypted data.
public func decrypt(
cipher: Data,
using key: Data,
arguments: [ContentEncryptionArguments]
Expand Down
Loading

0 comments on commit 1af633d

Please sign in to comment.