@@ -20,6 +20,8 @@ module JCAModel {
2020
2121 abstract class SignatureAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer { }
2222
23+ abstract class MacAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer { }
24+
2325 // TODO: Verify that the PBEWith% case works correctly
2426 bindingset [ algo]
2527 predicate cipher_names ( string algo ) {
@@ -85,7 +87,7 @@ module JCAModel {
8587 name .toUpperCase ( )
8688 .matches ( [
8789 "HMAC%" , "AESCMAC" , "DESCMAC" , "GMAC" , "Poly1305" , "SipHash" , "BLAKE2BMAC" ,
88- "HMACRIPEMD160"
90+ "HMACRIPEMD160" , "%CMAC"
8991 ] .toUpperCase ( ) )
9092 }
9193
@@ -128,6 +130,10 @@ module JCAModel {
128130 result instanceof Crypto:: SHA2 and
129131 digestLength = name .replaceAll ( "-" , "" ) .splitAt ( "SHA" , 1 ) .toInt ( )
130132 or
133+ name in [ "SHA-512/224" , "SHA-512/256" , "SHA512/224" , "SHA512/256" ] and
134+ result instanceof Crypto:: SHA2 and
135+ digestLength = name .replaceAll ( "-" , "" ) .splitAt ( "SHA-512/" , 1 ) .toInt ( )
136+ or
131137 name in [ "SHA3-224" , "SHA3-256" , "SHA3-384" , "SHA3-512" , "SHA3256" , "SHA3384" , "SHA3512" ] and
132138 result instanceof Crypto:: SHA3 and
133139 digestLength = name .replaceAll ( "-" , "" ) .splitAt ( "SHA3" , 1 ) .toInt ( )
@@ -1580,7 +1586,7 @@ module JCAModel {
15801586 if super .getValue ( ) .toUpperCase ( ) .matches ( "HMAC%" )
15811587 then result = KeyOpAlg:: TMac ( KeyOpAlg:: HMAC ( ) )
15821588 else
1583- if super .getValue ( ) .toUpperCase ( ) .matches ( "CMAC%" )
1589+ if super .getValue ( ) .toUpperCase ( ) .matches ( "% CMAC%" )
15841590 then result = KeyOpAlg:: TMac ( KeyOpAlg:: CMAC ( ) )
15851591 else result = KeyOpAlg:: TMac ( KeyOpAlg:: OtherMacAlgorithmType ( ) )
15861592 }
@@ -1600,6 +1606,54 @@ module JCAModel {
16001606 override Crypto:: PaddingAlgorithmInstance getPaddingAlgorithm ( ) { none ( ) }
16011607 }
16021608
1609+ class KnownHmacAlgorithmInstance extends Crypto:: HmacAlgorithmInstance instanceof KnownMacAlgorithm
1610+ {
1611+ override Crypto:: AlgorithmValueConsumer getHashAlgorithmValueConsumer ( ) {
1612+ result = this .( KnownMacAlgorithm ) .getConsumer ( )
1613+ }
1614+
1615+ override int getKeySizeFixed ( ) {
1616+ // already defined by parent key operation algorithm, but extending an instance
1617+ // still requires we override this method
1618+ result = super .getKeySizeFixed ( )
1619+ }
1620+
1621+ override Crypto:: ConsumerInputDataFlowNode getKeySizeConsumer ( ) {
1622+ // already defined by parent key operation algorithm, but extending an instance
1623+ // still requires we override this method
1624+ result = super .getKeySizeConsumer ( )
1625+ }
1626+
1627+ override string getRawAlgorithmName ( ) {
1628+ // already defined by parent key operation algorithm, but extending an instance
1629+ // still requires we override this method
1630+ result = super .getRawAlgorithmName ( )
1631+ }
1632+
1633+ override Crypto:: KeyOpAlg:: AlgorithmType getAlgorithmType ( ) {
1634+ result = KeyOpAlg:: TMac ( KeyOpAlg:: HMAC ( ) )
1635+ }
1636+ }
1637+
1638+ class KnownMacHashAlgorithm extends Crypto:: HashAlgorithmInstance instanceof KnownMacAlgorithm ,
1639+ JavaConstant
1640+ {
1641+ Crypto:: THashType hashType ;
1642+ int digestLength ;
1643+
1644+ KnownMacHashAlgorithm ( ) {
1645+ super .getValue ( ) .toUpperCase ( ) .matches ( "HMAC%" ) and
1646+ hashType =
1647+ hash_name_to_type_known ( super .getValue ( ) .toUpperCase ( ) .splitAt ( "HMAC" , 1 ) , digestLength )
1648+ }
1649+
1650+ override string getRawHashAlgorithmName ( ) { result = super .getValue ( ) }
1651+
1652+ override Crypto:: THashType getHashType ( ) { result = hashType }
1653+
1654+ override int getFixedDigestLength ( ) { result = digestLength }
1655+ }
1656+
16031657 class MacGetInstanceCall extends MethodCall {
16041658 MacGetInstanceCall ( ) { this .getCallee ( ) .hasQualifiedName ( "javax.crypto" , "Mac" , "getInstance" ) }
16051659
@@ -1629,7 +1683,9 @@ module JCAModel {
16291683 }
16301684 }
16311685
1632- class MacGetInstanceAlgorithmValueConsumer extends Crypto:: AlgorithmValueConsumer {
1686+ class MacGetInstanceAlgorithmValueConsumer extends MacAlgorithmValueConsumer ,
1687+ HashAlgorithmValueConsumer
1688+ {
16331689 MacGetInstanceAlgorithmValueConsumer ( ) { this = any ( MacGetInstanceCall c ) .getAlgorithmArg ( ) }
16341690
16351691 override Crypto:: ConsumerInputDataFlowNode getInputNode ( ) { result .asExpr ( ) = this }
@@ -1696,9 +1752,18 @@ module JCAModel {
16961752 MacFlowAnalysisImpl:: getAnIntermediateUseFromFinalUse ( this , _, _) .getOutput ( )
16971753 }
16981754
1699- override Crypto:: AlgorithmValueConsumer getHashAlgorithmValueConsumer ( ) { none ( ) }
1755+ override Crypto:: AlgorithmValueConsumer getHashAlgorithmValueConsumer ( ) {
1756+ result = this .getInstantiationCall ( ) .getAlgorithmArg ( )
1757+ }
17001758
1701- override predicate hasHashAlgorithmConsumer ( ) { none ( ) }
1759+ override predicate hasHashAlgorithmConsumer ( ) {
1760+ // TODO: do we consider that these operations have no hash and that it is only associated to the mac algorithm node?
1761+ // in JCA that seems to be correct, but would removing the hash consumer here break things generally?
1762+ this .getHashAlgorithmValueConsumer ( )
1763+ .getAKnownAlgorithmSource ( )
1764+ .( Crypto:: KeyOperationAlgorithmInstance )
1765+ .getAlgorithmType ( ) = KeyOpAlg:: TMac ( KeyOpAlg:: HMAC ( ) )
1766+ }
17021767
17031768 override Crypto:: KeyOperationSubtype getKeyOperationSubtype ( ) {
17041769 result instanceof Crypto:: TMacMode
0 commit comments