2424
2525#define XCRYPT_VER_MAX 0
2626#define XCRYPT_VER_MIN 1
27- #define XCRYPT_BUILD_NUM 22
27+ #define XCRYPT_BUILD_NUM 23
2828
2929#define XAES_KEY_LENGTH 256
3030#define XHEX_COLUMNS 16
@@ -39,6 +39,7 @@ typedef struct
3939 char sText [XSTR_MID ];
4040 char sPair [XSTR_MID ];
4141 char sKey [XSTR_MID ];
42+ char sIV [XSTR_MICRO ];
4243
4344 size_t nKeySize ;
4445 xbool_t bDecrypt ;
@@ -104,17 +105,17 @@ static void XCrypt_DisplayUsage(const char *pName)
104105 bRSA = XTRUE ;
105106#endif
106107
107- const char * pRSAOption = bRSA ? "[-g <pub:priv>]" : XSTR_EMPTY ;
108+ const char * pRSAOption = bRSA ? " [-g <pub:priv>]" : XSTR_EMPTY ;
108109 const char * pRSADesc = bRSA ? "and RSA" : XSTR_EMPTY ;
109110
110- xlog ("==========================================================" );
111+ xlog ("============================================================ " );
111112 xlog (" Crypt/Decrypt file or text - v%d.%d build %d (%s)" ,
112113 XCRYPT_VER_MAX , XCRYPT_VER_MIN , XCRYPT_BUILD_NUM , __DATE__ );
113- xlog ("==========================================================" );
114+ xlog ("============================================================ " );
114115
115- xlog ("Usage: %s [-c <ciphers>] [-i <input>] [-o <output>]" , pName );
116- xlog (" %s [-K <keyfile>] [-k <key>] %s " , XCrypt_WhiteSpace (nLength ), pRSAOption );
117- xlog (" %s [-t <text>] [-d] [-f] [-p] [-s] [-h] [-v ]\n" , XCrypt_WhiteSpace (nLength ));
116+ xlog ("Usage: %s [-c <ciphers>] [-i <input>] [-o <output>] [-v] " , pName );
117+ xlog (" %s [-K <keyfile>] [-k <key>]%s [-x] " , XCrypt_WhiteSpace (nLength ), pRSAOption );
118+ xlog (" %s [-t <text>] [-I <iv>] [- d] [-f] [-p] [-s] [-h]\n" , XCrypt_WhiteSpace (nLength ));
118119
119120 xlog ("Options are:" );
120121 xlog (" -c <ciphers> # Encryption or decryption ciphers (%s*%s)" , XSTR_CLR_RED , XSTR_FMT_RESET );
@@ -126,6 +127,7 @@ static void XCrypt_DisplayUsage(const char *pName)
126127 xlog (" -K <keyfile> # File path containing the key" );
127128 xlog (" -k <key> # The key to pass as an argument" );
128129 xlog (" -t <text> # Input text to pass as an argument" );
130+ xlog (" -I <iv> # Initialization vector for AES" );
129131 xlog (" -d # Decryption mode" );
130132 xlog (" -f # Force overwrite output" );
131133 xlog (" -s # Key size for AES %s" , pRSADesc );
@@ -296,6 +298,60 @@ static xbool_t XCrypt_GetKey(xcrypt_args_t *pArgs, xcrypt_key_t *pKey)
296298 return XCrypt_SetKey (pArgs , pKey , nLength );
297299}
298300
301+ static xbool_t XCrypt_GetIV (xcrypt_args_t * pArgs , xcrypt_key_t * pKey )
302+ {
303+ if (xstrused (pArgs -> sIV ))
304+ {
305+ size_t nLength = xstrncpy (pKey -> sIV , sizeof (pKey -> sIV ), pArgs -> sIV );
306+ if (nLength < 16 )
307+ {
308+ xlogw ("IV is too short, will be padded with zero bytes" );
309+ memset (pKey -> sIV + nLength , 0 , 16 - nLength );
310+ }
311+
312+ return XTRUE ;
313+ }
314+
315+ char sIV [XSTR_PICO ];
316+ sIV [0 ] = XSTR_NUL ;
317+
318+ const char * pCipher = XCrypt_GetCipherStr (pKey -> eCipher );
319+ printf ("Enter IV for the cipher '%s': " , pCipher );
320+
321+ if (!XCLI_GetPass (NULL , pKey -> sIV , sizeof (pKey -> sIV )))
322+ {
323+ xloge ("Failed to read IV: %d" , errno );
324+ return XFALSE ;
325+ }
326+
327+ if (!pArgs -> bDecrypt || pArgs -> bForce )
328+ {
329+ printf ("Re-enter IV for the cipher '%s': " , pCipher );
330+ sIV [0 ] = XSTR_NUL ;
331+
332+ if (!XCLI_GetPass (NULL , sIV , sizeof (sIV )))
333+ {
334+ xloge ("Failed to read IV: %d" , errno );
335+ return XFALSE ;
336+ }
337+
338+ if (strcmp (pKey -> sIV , sIV ))
339+ {
340+ xloge ("IV do not match" );
341+ return XFALSE ;
342+ }
343+ }
344+
345+ size_t nLength = strlen (pKey -> sIV );
346+ if (nLength < 16 )
347+ {
348+ xlogw ("IV is too short, will be padded with zero bytes" );
349+ memset (pKey -> sIV + nLength , 0 , 16 - nLength );
350+ }
351+
352+ return XTRUE ;
353+ }
354+
299355static XSTATUS XCrypt_ValidateArgs (xcrypt_args_t * pArgs )
300356{
301357 if (xstrused (pArgs -> sPair ))
@@ -376,7 +432,7 @@ static xbool_t XCrypt_ParseArgs(xcrypt_args_t *pArgs, int argc, char *argv[])
376432 memset (pArgs , 0 , sizeof (xcrypt_args_t ));
377433 int nChar = 0 ;
378434
379- while ((nChar = getopt (argc , argv , "c:i:o:g:k:K:t:s:d1:f1:h1:p1:s1:x1:v1" )) != -1 )
435+ while ((nChar = getopt (argc , argv , "c:i:o:g:k:K:I: t:s:d1:f1:h1:p1:s1:x1:v1" )) != -1 )
380436 {
381437 switch (nChar )
382438 {
@@ -400,6 +456,9 @@ static xbool_t XCrypt_ParseArgs(xcrypt_args_t *pArgs, int argc, char *argv[])
400456 case 'K' :
401457 xstrncpy (pArgs -> sKeyFile , sizeof (pArgs -> sKeyFile ), optarg );
402458 break ;
459+ case 'I' :
460+ xstrncpy (pArgs -> sIV , sizeof (pArgs -> sIV ), optarg );
461+ break ;
403462 case 't' :
404463 xstrncpy (pArgs -> sText , sizeof (pArgs -> sText ), optarg );
405464 break ;
@@ -470,6 +529,13 @@ xbool_t XCrypt_Callback(xcrypt_cb_type_t eType, void *pData, void *pCtx)
470529 xcrypt_key_t * pKey = (xcrypt_key_t * )pData ;
471530 return XCrypt_GetKey (pArgs , pKey );
472531 }
532+ else if (eType == XCB_IV )
533+ {
534+ xcrypt_args_t * pArgs = (xcrypt_args_t * )pCtx ;
535+ xcrypt_key_t * pKey = (xcrypt_key_t * )pData ;
536+ return XCrypt_GetIV (pArgs , pKey );
537+ }
538+
473539
474540 xloge ("%s (%d)" , (const char * )pData , errno );
475541 return XFALSE ;
0 commit comments