@@ -891,11 +891,10 @@ struct balloon_thread_data {
891891/* Balloon context */
892892struct balloon_context {
893893 int algo ;
894- int hash_type ;
895894 int prng_type ;
896895
897896 unsigned int blklen ;
898- gcry_md_spec_t md_spec ;
897+ const gcry_md_spec_t * md_spec ;
899898
900899 const unsigned char * password ;
901900 size_t passwordlen ;
@@ -925,20 +924,55 @@ prng_aes_ctr_init (gcry_cipher_hd_t *hd_p, balloon_ctx_t b,
925924 gpg_err_code_t ec ;
926925 gcry_cipher_hd_t hd ;
927926 unsigned char key [BALLOON_SALT_LEN_MAX ];
927+ int cipher_algo ;
928+ unsigned int keylen , blklen ;
928929
929- b -> md_spec .hash_buffers (key , b -> blklen , iov , iov_count );
930- ec = _gcry_cipher_open (& hd , GCRY_CIPHER_AES , GCRY_CIPHER_MODE_CTR , 0 );
930+ switch (b -> blklen )
931+ {
932+ case 64 :
933+ cipher_algo = GCRY_CIPHER_AES256 ;
934+ break ;
935+
936+ case 48 :
937+ cipher_algo = GCRY_CIPHER_AES192 ;
938+ break ;
939+
940+ default :
941+ case 32 :
942+ cipher_algo = GCRY_CIPHER_AES ;
943+ break ;
944+ }
945+
946+ keylen = _gcry_cipher_get_algo_keylen (cipher_algo );
947+ blklen = _gcry_cipher_get_algo_blklen (cipher_algo );
948+
949+ b -> md_spec -> hash_buffers (key , b -> blklen , iov , iov_count );
950+ ec = _gcry_cipher_open (& hd , cipher_algo , GCRY_CIPHER_MODE_CTR , 0 );
931951 if (ec )
932952 return ec ;
933953
934- ec = _gcry_cipher_setkey (hd , key , 16 );
954+ ec = _gcry_cipher_setkey (hd , key , keylen );
935955 if (ec )
936956 {
937957 _gcry_cipher_close (hd );
938958 return ec ;
939959 }
940960
941- wipememory (key , 32 );
961+ if (cipher_algo == GCRY_CIPHER_AES
962+ && b -> md_spec == & _gcry_digest_spec_sha256 )
963+ /* Original Balloon uses zero IV. */
964+ ;
965+ else
966+ {
967+ ec = _gcry_cipher_setiv (hd , key + keylen , blklen );
968+ if (ec )
969+ {
970+ _gcry_cipher_close (hd );
971+ return ec ;
972+ }
973+ }
974+
975+ wipememory (key , BALLOON_SALT_LEN_MAX );
942976 * hd_p = hd ;
943977 return ec ;
944978}
@@ -985,15 +1019,37 @@ balloon_open (gcry_kdf_hd_t *hd, int subalgo,
9851019 size_t n ;
9861020 unsigned char * block ;
9871021 unsigned int i ;
988- gcry_md_spec_t md_spec ;
1022+ const gcry_md_spec_t * md_spec ;
9891023
990- /* For now, only SHA256 is supported. */
991- if (subalgo != GCRY_MD_SHA256 )
992- return GPG_ERR_NOT_SUPPORTED ;
993- else
1024+ hash_type = subalgo ;
1025+ switch (hash_type )
9941026 {
995- hash_type = subalgo ;
996- md_spec = _gcry_digest_spec_sha256 ;
1027+ case GCRY_MD_SHA256 :
1028+ md_spec = & _gcry_digest_spec_sha256 ;
1029+ break ;
1030+
1031+ case GCRY_MD_SHA384 :
1032+ md_spec = & _gcry_digest_spec_sha384 ;
1033+ break ;
1034+
1035+ case GCRY_MD_SHA512 :
1036+ md_spec = & _gcry_digest_spec_sha512 ;
1037+ break ;
1038+
1039+ case GCRY_MD_SHA3_256 :
1040+ md_spec = & _gcry_digest_spec_sha3_256 ;
1041+ break ;
1042+
1043+ case GCRY_MD_SHA3_384 :
1044+ md_spec = & _gcry_digest_spec_sha3_384 ;
1045+ break ;
1046+
1047+ case GCRY_MD_SHA3_512 :
1048+ md_spec = & _gcry_digest_spec_sha3_512 ;
1049+ break ;
1050+
1051+ default :
1052+ return GPG_ERR_NOT_SUPPORTED ;
9971053 }
9981054
9991055 blklen = _gcry_md_get_algo_dlen (hash_type );
@@ -1006,7 +1062,7 @@ balloon_open (gcry_kdf_hd_t *hd, int subalgo,
10061062 /*
10071063 * It should have space_cost and time_cost.
10081064 * Optionally, for parallelised version, it has parallelism.
1009- * Possibly (in future), it may have options for PRNG.
1065+ * Possibly (in future), it may have option to specify PRNG type .
10101066 */
10111067 if (paramlen != 2 && paramlen != 3 )
10121068 return GPG_ERR_INV_VALUE ;
@@ -1027,7 +1083,6 @@ balloon_open (gcry_kdf_hd_t *hd, int subalgo,
10271083 return gpg_err_code_from_errno (errno );
10281084
10291085 b -> algo = GCRY_KDF_BALLOON ;
1030- b -> hash_type = hash_type ;
10311086 b -> md_spec = md_spec ;
10321087 b -> blklen = blklen ;
10331088
@@ -1097,7 +1152,7 @@ balloon_compress (balloon_ctx_t b, u64 *counter_p, unsigned char *out,
10971152 iov [i ].off = 0 ;
10981153 }
10991154
1100- b -> md_spec . hash_buffers (out , b -> blklen , iov , 1 + BALLOON_COMPRESS_BLOCKS );
1155+ b -> md_spec -> hash_buffers (out , b -> blklen , iov , 1 + BALLOON_COMPRESS_BLOCKS );
11011156 * counter_p += 1 ;
11021157}
11031158
@@ -1120,7 +1175,7 @@ balloon_expand (balloon_ctx_t b, u64 *counter_p, unsigned char *block,
11201175 buf_put_le64 (octet_counter , * counter_p );
11211176 iov [1 ].data = block ;
11221177 block += b -> blklen ;
1123- b -> md_spec . hash_buffers (block , b -> blklen , iov , 2 );
1178+ b -> md_spec -> hash_buffers (block , b -> blklen , iov , 2 );
11241179 * counter_p += 1 ;
11251180 }
11261181}
@@ -1160,7 +1215,7 @@ balloon_compute_fill (balloon_ctx_t b,
11601215 iov [5 ].data = octet_parallelism ;
11611216 iov [5 ].len = 4 ;
11621217 iov [5 ].off = 0 ;
1163- b -> md_spec . hash_buffers (t -> block , b -> blklen , iov , 6 );
1218+ b -> md_spec -> hash_buffers (t -> block , b -> blklen , iov , 6 );
11641219 * counter_p += 1 ;
11651220 balloon_expand (b , counter_p , t -> block , b -> n_blocks );
11661221}
@@ -1296,6 +1351,9 @@ balloon_final (balloon_ctx_t b, size_t resultlen, void *result)
12961351 struct balloon_thread_data * t = & b -> thread_data [i ];
12971352 const unsigned char * last_block ;
12981353
1354+ if (t -> ec )
1355+ return t -> ec ;
1356+
12991357 last_block = t -> block + (b -> blklen * (t -> b -> n_blocks - 1 ));
13001358 balloon_xor_block (b , result , (u64 * )last_block );
13011359 }
0 commit comments