Skip to content

Commit

Permalink
SHA-3 support in CMS
Browse files Browse the repository at this point in the history
  • Loading branch information
ocheron committed Jun 2, 2024
1 parent 98facd1 commit a48e958
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 19 deletions.
64 changes: 56 additions & 8 deletions src/Crypto/Store/CMS/Algorithms.hs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ data DigestProxy hashAlg where
SHA384 :: DigestProxy Hash.SHA384
-- | SHA-512
SHA512 :: DigestProxy Hash.SHA512
-- | SHA3-224
SHA3_224 :: DigestProxy Hash.SHA3_224
-- | SHA3-256
SHA3_256 :: DigestProxy Hash.SHA3_256
-- | SHA3-384
SHA3_384 :: DigestProxy Hash.SHA3_384
-- | SHA3-512
SHA3_512 :: DigestProxy Hash.SHA3_512
-- | SHAKE128 (256 bits)
SHAKE128_256 :: DigestProxy (Hash.SHAKE128 256)
-- | SHAKE256 (512 bits)
Expand All @@ -186,6 +194,10 @@ instance Show (DigestProxy hashAlg) where
showsPrec _ SHA256 = showString "SHA256"
showsPrec _ SHA384 = showString "SHA384"
showsPrec _ SHA512 = showString "SHA512"
showsPrec _ SHA3_224 = showString "SHA3_224"
showsPrec _ SHA3_256 = showString "SHA3_256"
showsPrec _ SHA3_384 = showString "SHA3_384"
showsPrec _ SHA3_512 = showString "SHA3_512"
showsPrec _ SHAKE128_256 = showString "SHAKE128_256"
showsPrec _ SHAKE256_512 = showString "SHAKE256_512"
showsPrec d (SHAKE128 p) =
Expand All @@ -208,6 +220,10 @@ instance HasStrength (DigestProxy hashAlg) where
getSecurityBits SHA256 = 128
getSecurityBits SHA384 = 192
getSecurityBits SHA512 = 256
getSecurityBits SHA3_224 = 112
getSecurityBits SHA3_256 = 128
getSecurityBits SHA3_384 = 192
getSecurityBits SHA3_512 = 256
getSecurityBits SHAKE128_256 = 128
getSecurityBits SHAKE256_512 = 256
getSecurityBits (SHAKE128 a) = shakeSecurityBits 128 a
Expand All @@ -233,6 +249,10 @@ instance Eq DigestAlgorithm where
DigestAlgorithm SHA256 == DigestAlgorithm SHA256 = True
DigestAlgorithm SHA384 == DigestAlgorithm SHA384 = True
DigestAlgorithm SHA512 == DigestAlgorithm SHA512 = True
DigestAlgorithm SHA3_224 == DigestAlgorithm SHA3_224 = True
DigestAlgorithm SHA3_256 == DigestAlgorithm SHA3_256 = True
DigestAlgorithm SHA3_384 == DigestAlgorithm SHA3_384 = True
DigestAlgorithm SHA3_512 == DigestAlgorithm SHA3_512 = True
DigestAlgorithm SHAKE128_256 == DigestAlgorithm SHAKE128_256 = True
DigestAlgorithm SHAKE256_512 == DigestAlgorithm SHAKE256_512 = True
DigestAlgorithm (SHAKE128 a) == DigestAlgorithm (SHAKE128 b) = natVal a == natVal b
Expand All @@ -251,6 +271,10 @@ data DigestType
| Type_SHA256
| Type_SHA384
| Type_SHA512
| Type_SHA3_224
| Type_SHA3_256
| Type_SHA3_384
| Type_SHA3_512
| Type_SHAKE128_256
| Type_SHAKE256_512
| Type_SHAKE128_Len
Expand All @@ -265,6 +289,10 @@ instance Enumerable DigestType where
, Type_SHA256
, Type_SHA384
, Type_SHA512
, Type_SHA3_224
, Type_SHA3_256
, Type_SHA3_384
, Type_SHA3_512
, Type_SHAKE128_256
, Type_SHAKE256_512
, Type_SHAKE128_Len
Expand All @@ -280,6 +308,10 @@ instance OIDable DigestType where
getObjectID Type_SHA256 = [2,16,840,1,101,3,4,2,1]
getObjectID Type_SHA384 = [2,16,840,1,101,3,4,2,2]
getObjectID Type_SHA512 = [2,16,840,1,101,3,4,2,3]
getObjectID Type_SHA3_224 = [2,16,840,1,101,3,4,2,7]
getObjectID Type_SHA3_256 = [2,16,840,1,101,3,4,2,8]
getObjectID Type_SHA3_384 = [2,16,840,1,101,3,4,2,9]
getObjectID Type_SHA3_512 = [2,16,840,1,101,3,4,2,10]
getObjectID Type_SHAKE128_256 = [2,16,840,1,101,3,4,2,11]
getObjectID Type_SHAKE256_512 = [2,16,840,1,101,3,4,2,12]
getObjectID Type_SHAKE128_Len = [2,16,840,1,101,3,4,2,17]
Expand All @@ -300,6 +332,10 @@ instance AlgorithmId DigestAlgorithm where
algorithmType (DigestAlgorithm SHA256) = Type_SHA256
algorithmType (DigestAlgorithm SHA384) = Type_SHA384
algorithmType (DigestAlgorithm SHA512) = Type_SHA512
algorithmType (DigestAlgorithm SHA3_224) = Type_SHA3_224
algorithmType (DigestAlgorithm SHA3_256) = Type_SHA3_256
algorithmType (DigestAlgorithm SHA3_384) = Type_SHA3_384
algorithmType (DigestAlgorithm SHA3_512) = Type_SHA3_512
algorithmType (DigestAlgorithm SHAKE128_256) = Type_SHAKE128_256
algorithmType (DigestAlgorithm SHAKE256_512) = Type_SHAKE256_512
algorithmType (DigestAlgorithm (SHAKE128 _)) = Type_SHAKE128_Len
Expand All @@ -320,6 +356,10 @@ instance AlgorithmId DigestAlgorithm where
parseParameter Type_SHA256 = parseDigestParam (DigestAlgorithm SHA256)
parseParameter Type_SHA384 = parseDigestParam (DigestAlgorithm SHA384)
parseParameter Type_SHA512 = parseDigestParam (DigestAlgorithm SHA512)
parseParameter Type_SHA3_224 = parseDigestParam (DigestAlgorithm SHA3_224)
parseParameter Type_SHA3_256 = parseDigestParam (DigestAlgorithm SHA3_256)
parseParameter Type_SHA3_384 = parseDigestParam (DigestAlgorithm SHA3_384)
parseParameter Type_SHA3_512 = parseDigestParam (DigestAlgorithm SHA3_512)
parseParameter Type_SHAKE128_256 = parseDigestParam (DigestAlgorithm SHAKE128_256)
parseParameter Type_SHAKE256_512 = parseDigestParam (DigestAlgorithm SHAKE256_512)
parseParameter Type_SHAKE128_Len = parseBitLen $
Expand Down Expand Up @@ -456,19 +496,27 @@ instance Enumerable MACType where
, TypeHMAC SHA256
, TypeHMAC SHA384
, TypeHMAC SHA512
, TypeHMAC SHA3_224
, TypeHMAC SHA3_256
, TypeHMAC SHA3_384
, TypeHMAC SHA3_512
, TypeKMAC_SHAKE128
, TypeKMAC_SHAKE256
]

instance OIDable MACType where
getObjectID (TypeHMAC MD5) = [1,3,6,1,5,5,8,1,1]
getObjectID (TypeHMAC SHA1) = [1,3,6,1,5,5,8,1,2]
getObjectID (TypeHMAC SHA224) = [1,2,840,113549,2,8]
getObjectID (TypeHMAC SHA256) = [1,2,840,113549,2,9]
getObjectID (TypeHMAC SHA384) = [1,2,840,113549,2,10]
getObjectID (TypeHMAC SHA512) = [1,2,840,113549,2,11]
getObjectID TypeKMAC_SHAKE128 = [2,16,840,1,101,3,4,2,19]
getObjectID TypeKMAC_SHAKE256 = [2,16,840,1,101,3,4,2,20]
getObjectID (TypeHMAC MD5) = [1,3,6,1,5,5,8,1,1]
getObjectID (TypeHMAC SHA1) = [1,3,6,1,5,5,8,1,2]
getObjectID (TypeHMAC SHA224) = [1,2,840,113549,2,8]
getObjectID (TypeHMAC SHA256) = [1,2,840,113549,2,9]
getObjectID (TypeHMAC SHA384) = [1,2,840,113549,2,10]
getObjectID (TypeHMAC SHA512) = [1,2,840,113549,2,11]
getObjectID (TypeHMAC SHA3_224) = [2,16,840,1,101,3,4,2,13]
getObjectID (TypeHMAC SHA3_256) = [2,16,840,1,101,3,4,2,14]
getObjectID (TypeHMAC SHA3_384) = [2,16,840,1,101,3,4,2,15]
getObjectID (TypeHMAC SHA3_512) = [2,16,840,1,101,3,4,2,16]
getObjectID TypeKMAC_SHAKE128 = [2,16,840,1,101,3,4,2,19]
getObjectID TypeKMAC_SHAKE256 = [2,16,840,1,101,3,4,2,20]

getObjectID ty = error ("Unsupported MACAlgorithm: " ++ show ty)

Expand Down
15 changes: 11 additions & 4 deletions tests/CMS/Instances.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
module CMS.Instances
( arbitraryPassword
, arbitraryAttributes
, arbitraryIntegrityDigest
, arbitrarySigVer
, arbitraryEnvDev
) where
Expand Down Expand Up @@ -138,25 +137,33 @@ instance Arbitrary DigestAlgorithm where
, pure $ DigestAlgorithm SHA256
, pure $ DigestAlgorithm SHA384
, pure $ DigestAlgorithm SHA512
, pure $ DigestAlgorithm SHA3_224
, pure $ DigestAlgorithm SHA3_256
, pure $ DigestAlgorithm SHA3_384
, pure $ DigestAlgorithm SHA3_512
, pure $ DigestAlgorithm SHAKE128_256
, pure $ DigestAlgorithm SHAKE256_512
, (\(SomeNat p) -> DigestAlgorithm (SHAKE128 p)) <$> arbitraryNat
, (\(SomeNat p) -> DigestAlgorithm (SHAKE256 p)) <$> arbitraryNat
]

arbitraryIntegrityDigest :: Gen DigestAlgorithm
arbitraryIntegrityDigest = elements
arbitraryDigest :: Gen DigestAlgorithm
arbitraryDigest = elements
[ DigestAlgorithm MD5
, DigestAlgorithm SHA1
, DigestAlgorithm SHA224
, DigestAlgorithm SHA256
, DigestAlgorithm SHA384
, DigestAlgorithm SHA512
, DigestAlgorithm SHA3_224
, DigestAlgorithm SHA3_256
, DigestAlgorithm SHA3_384
, DigestAlgorithm SHA3_512
]

instance Arbitrary MACAlgorithm where
arbitrary = oneof
[ (\(DigestAlgorithm alg) -> HMAC alg) <$> arbitraryIntegrityDigest
[ (\(DigestAlgorithm alg) -> HMAC alg) <$> arbitraryDigest
, (\(SomeNat p) -> KMAC_SHAKE128 p) <$> arbitraryNat <*> arbitraryCtx
, (\(SomeNat p) -> KMAC_SHAKE256 p) <$> arbitraryNat <*> arbitraryCtx
]
Expand Down
16 changes: 10 additions & 6 deletions tests/CMS/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,16 @@ digestedDataTests =
ci' = toAttachedCI dd'
ci @?= ci'
where path = testFile "cms-digested-data.pem"
algs = [ ("MD5", DigestAlgorithm MD5)
, ("SHA1", DigestAlgorithm SHA1)
, ("SHA224", DigestAlgorithm SHA224)
, ("SHA256", DigestAlgorithm SHA256)
, ("SHA384", DigestAlgorithm SHA384)
, ("SHA512", DigestAlgorithm SHA512)
algs = [ ("MD5", DigestAlgorithm MD5)
, ("SHA1", DigestAlgorithm SHA1)
, ("SHA224", DigestAlgorithm SHA224)
, ("SHA256", DigestAlgorithm SHA256)
, ("SHA384", DigestAlgorithm SHA384)
, ("SHA512", DigestAlgorithm SHA512)
, ("SHA3_224", DigestAlgorithm SHA3_224)
, ("SHA3_256", DigestAlgorithm SHA3_256)
, ("SHA3_384", DigestAlgorithm SHA3_384)
, ("SHA3_512", DigestAlgorithm SHA3_512)
]

encryptedDataTests :: TestTree
Expand Down
13 changes: 13 additions & 0 deletions tests/PKCS12/Instances.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Data.Semigroup

import Test.Tasty.QuickCheck

import Crypto.Store.CMS
import Crypto.Store.PKCS12
import Crypto.Store.PKCS5

Expand All @@ -26,6 +27,18 @@ arbitraryAlias :: Gen String
arbitraryAlias = resize 16 asciiChar
where asciiChar = listOf $ choose ('\x20','\x7f')

arbitraryIntegrityDigest :: Gen DigestAlgorithm
arbitraryIntegrityDigest = elements
[ DigestAlgorithm MD2
, DigestAlgorithm MD4
, DigestAlgorithm MD5
, DigestAlgorithm SHA1
, DigestAlgorithm SHA224
, DigestAlgorithm SHA256
, DigestAlgorithm SHA384
, DigestAlgorithm SHA512
]

arbitraryIntegrityParams :: Gen IntegrityParams
arbitraryIntegrityParams = (,) <$> arbitraryIntegrityDigest <*> arbitrary

Expand Down
19 changes: 19 additions & 0 deletions tests/files/cms-digested-data.pem
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,22 @@ MIGABgkqhkiG9w0BBwWgczBxAgEAMAsGCWCGSAFlAwQCAzAdBgkqhkiG9w0BBwGg
EAQOaGVsbG8sIHdvcmxkDQoEQNmRYGENk6X3fR9Sk9k++QSKUPYBvF+nGKHL4FXN
QVoNz4kKv9BI4MPnsV77ikuw7kWGR3OFLWO8waCyFK+EEu0=
-----END CMS-----
-----BEGIN CMS-----
MFwGCSqGSIb3DQEHBaBPME0CAQAwCwYJYIZIAWUDBAIHMB0GCSqGSIb3DQEHAaAQ
BA5oZWxsbywgd29ybGQNCgQcrHRNG/sKxDCiVbjFsYvAvrXdZNaPFFkUnKb7eg==
-----END CMS-----
-----BEGIN CMS-----
MGAGCSqGSIb3DQEHBaBTMFECAQAwCwYJYIZIAWUDBAIIMB0GCSqGSIb3DQEHAaAQ
BA5oZWxsbywgd29ybGQNCgQgead3JnYtNJOYL50QfPgWkqUtpmuiU9T7itIfOmfa
3l4=
-----END CMS-----
-----BEGIN CMS-----
MHAGCSqGSIb3DQEHBaBjMGECAQAwCwYJYIZIAWUDBAIJMB0GCSqGSIb3DQEHAaAQ
BA5oZWxsbywgd29ybGQNCgQwPvv+XafJtPR2UXRqu2t6l3BuJeoOghvrAfPbbRQ2
cr5IHYmzioNIZ1HlrP6RG0R3
-----END CMS-----
-----BEGIN CMS-----
MIGABgkqhkiG9w0BBwWgczBxAgEAMAsGCWCGSAFlAwQCCjAdBgkqhkiG9w0BBwGg
EAQOaGVsbG8sIHdvcmxkDQoEQHjsLFT6QOVe+FI6fBZhWEIHpXzDX9L4/ARGWEXp
rKVTw6DfjRFICt66Mxxqn4WbRCa/FJXAnVY1PduwTN1Fiqw=
-----END CMS-----
2 changes: 1 addition & 1 deletion tests/files/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ echo "$MESSAGE" | "$OPENSSL" cms -data_create \
# CMS digested data

(
for digest in MD5 SHA1 SHA224 SHA256 SHA384 SHA512; do
for digest in MD5 SHA1 SHA224 SHA256 SHA384 SHA512 SHA3-224 SHA3-256 SHA3-384 SHA3-512; do
echo "$MESSAGE" | "$OPENSSL" cms -digest_create -md $digest \
-outform PEM
done
Expand Down

0 comments on commit a48e958

Please sign in to comment.