1818#include "crc32.h"
1919#include "sha256.h"
2020#include "sha1.h"
21+ #include "hmac.h"
2122#include "aes.h"
2223#include "rsa.h"
2324
2425#define XCRYPT_VER_MAX 0
2526#define XCRYPT_VER_MIN 1
26- #define XCRYPT_BUILD_NUM 21
27+ #define XCRYPT_BUILD_NUM 22
2728
2829#define XAES_KEY_LENGTH 256
2930#define XHEX_COLUMNS 16
@@ -41,6 +42,7 @@ typedef struct
4142
4243 size_t nKeySize ;
4344 xbool_t bDecrypt ;
45+ xbool_t bHybrid ;
4446 xbool_t bForce ;
4547 xbool_t bPrint ;
4648 xbool_t bHex ;
@@ -129,6 +131,7 @@ static void XCrypt_DisplayUsage(const char *pName)
129131 xlog (" -s # Key size for AES %s" , pRSADesc );
130132 xlog (" -h # Display output as a HEX" );
131133 xlog (" -p # Print output to stdout" );
134+ xlog (" -x # Hybryd mode for AES" );
132135 xlog (" -v # Version and usage\n" );
133136
134137 xlog ("Supported ciphers:" );
@@ -176,12 +179,63 @@ static void XCrypt_DisplayUsage(const char *pName)
176179#endif
177180}
178181
182+ static xbool_t XCrypt_ApplyHMAC (xcrypt_args_t * pArgs , xcrypt_key_t * pKey )
183+ {
184+ char sHSKey [XSTR_MID ];
185+ sHSKey [0 ] = XSTR_NUL ;
186+
187+ printf ("Enter keyword for the cipher 'h256': " );
188+ if (!XCLI_GetPass (NULL , sHSKey , sizeof (sHSKey )))
189+ {
190+ xloge ("Failed to read keyword: %d" , errno );
191+ return XFALSE ;
192+ }
193+
194+ if (!pArgs -> bDecrypt || pArgs -> bForce )
195+ {
196+ char sKey [XSTR_MID ];
197+ sKey [0 ] = XSTR_NUL ;
198+
199+ printf ("Re-enter keyword for the cipher 'h256': " );
200+ if (!XCLI_GetPass (NULL , sKey , sizeof (sKey )))
201+ {
202+ xloge ("Failed to read keyword: %d" , errno );
203+ return XFALSE ;
204+ }
205+
206+ if (strcmp (sHSKey , sKey ))
207+ {
208+ xloge ("Keyword do not match" );
209+ return XFALSE ;
210+ }
211+ }
212+
213+ char * pHMAC = XHMAC_SHA256_NEW ((uint8_t * )pKey -> sKey , strlen (pKey -> sKey ),
214+ (uint8_t * )sHSKey , strlen (sHSKey ));
215+ if (pHMAC == NULL )
216+ {
217+ xloge ("Failed to generate HMAC key" );
218+ return XFALSE ;
219+ }
220+
221+ pKey -> nLength = pArgs -> nKeySize ;
222+ xstrncpy (pKey -> sKey , sizeof (pKey -> sKey ), pHMAC );
223+
224+ free (pHMAC );
225+ return XTRUE ;
226+ }
227+
179228static xbool_t XCrypt_GetKey (xcrypt_args_t * pArgs , xcrypt_key_t * pKey )
180229{
181230 if (xstrused (pArgs -> sKey ))
182231 {
183232 pKey -> nLength = xstrncpy (pKey -> sKey , sizeof (pKey -> sKey ), pArgs -> sKey );
184- if (pKey -> eCipher == XC_AES ) pKey -> nLength = pArgs -> nKeySize ;
233+ if (pKey -> eCipher == XC_AES )
234+ {
235+ if (pArgs -> bHybrid ) return XCrypt_ApplyHMAC (pArgs , pKey );
236+ pKey -> nLength = pArgs -> nKeySize ;
237+ }
238+
185239 return pKey -> nLength ? XTRUE : XFALSE ;
186240 }
187241
@@ -192,14 +246,14 @@ static xbool_t XCrypt_GetKey(xcrypt_args_t *pArgs, xcrypt_key_t *pKey)
192246 if (xstrused (pArgs -> sKeyFile ) &&
193247 (pKey -> eCipher == XC_RS256 || pKey -> eCipher == XC_RSAPR || pKey -> eCipher == XC_RSA ))
194248 pKey -> nLength = XPath_Read (pArgs -> sKeyFile , (uint8_t * )sKey , sizeof (sKey ));
195- #endif
196249
197250 if (xstrused (sKey ))
198251 {
199252 pKey -> nLength = xstrncpy (pKey -> sKey , sizeof (pKey -> sKey ), sKey );
200253 if (pKey -> eCipher == XC_AES ) pKey -> nLength = pArgs -> nKeySize ;
201254 return pKey -> nLength ? XTRUE : XFALSE ;
202255 }
256+ #endif
203257
204258 const char * pCipher = XCrypt_GetCipherStr (pKey -> eCipher );
205259 printf ("Enter keyword for the cipher '%s': " , pCipher );
@@ -213,6 +267,7 @@ static xbool_t XCrypt_GetKey(xcrypt_args_t *pArgs, xcrypt_key_t *pKey)
213267 if (!pArgs -> bDecrypt || pArgs -> bForce )
214268 {
215269 printf ("Re-enter keyword for the cipher '%s': " , pCipher );
270+ sKey [0 ] = XSTR_NUL ;
216271
217272 if (!XCLI_GetPass (NULL , sKey , sizeof (sKey )))
218273 {
@@ -227,6 +282,9 @@ static xbool_t XCrypt_GetKey(xcrypt_args_t *pArgs, xcrypt_key_t *pKey)
227282 }
228283 }
229284
285+ if (pArgs -> bHybrid && pKey -> eCipher == XC_AES )
286+ return XCrypt_ApplyHMAC (pArgs , pKey );
287+
230288 if (pKey -> eCipher == XC_AES ) pKey -> nLength = pArgs -> nKeySize ;
231289 else pKey -> nLength = strlen (pKey -> sKey );
232290
@@ -313,7 +371,7 @@ static xbool_t XCrypt_ParseArgs(xcrypt_args_t *pArgs, int argc, char *argv[])
313371 memset (pArgs , 0 , sizeof (xcrypt_args_t ));
314372 int nChar = 0 ;
315373
316- while ((nChar = getopt (argc , argv , "c:i:o:g:k:K:t:s:d1:f1:h1:p1:s1:v1" )) != -1 )
374+ while ((nChar = getopt (argc , argv , "c:i:o:g:k:K:t:s:d1:f1:h1:p1:s1:x1: v1" )) != -1 )
317375 {
318376 switch (nChar )
319377 {
@@ -355,6 +413,9 @@ static xbool_t XCrypt_ParseArgs(xcrypt_args_t *pArgs, int argc, char *argv[])
355413 case 'p' :
356414 pArgs -> bPrint = XTRUE ;
357415 break ;
416+ case 'x' :
417+ pArgs -> bHybrid = XTRUE ;
418+ break ;
358419 case 'v' :
359420 default :
360421 XCrypt_DisplayUsage (argv [0 ]);
0 commit comments