diff options
author | Ben Laurie <ben@openssl.org> | 1999-01-17 16:26:24 +0000 |
---|---|---|
committer | Ben Laurie <ben@openssl.org> | 1999-01-17 16:26:24 +0000 |
commit | 649cdb7be91d75184a51993b37fa6a9813dd2ef1 (patch) | |
tree | 9b899572037fa553f470ab990c43d86911b1065f /crypto | |
parent | fdd3b6421597e412fe3e80f09495caff4c8bd897 (diff) |
Fix major cockup with short keys in CAST-128.
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/cast/Makefile.ssl | 2 | ||||
-rw-r--r-- | crypto/cast/asm/cast-586.pl | 262 | ||||
-rw-r--r-- | crypto/cast/c_enc.c | 22 | ||||
-rw-r--r-- | crypto/cast/c_skey.c | 4 | ||||
-rw-r--r-- | crypto/cast/cast.h | 1 | ||||
-rw-r--r-- | crypto/cast/casttest.c | 167 |
6 files changed, 239 insertions, 219 deletions
diff --git a/crypto/cast/Makefile.ssl b/crypto/cast/Makefile.ssl index c59982e783..bbdb3f4a58 100644 --- a/crypto/cast/Makefile.ssl +++ b/crypto/cast/Makefile.ssl @@ -66,7 +66,7 @@ asm/cx86-out.o: asm/cx86unix.cpp asm/cx86bsdi.o: asm/cx86unix.cpp $(CPP) -DBSDI asm/cx86unix.cpp | sed 's/ :/:/' | as -o asm/cx86bsdi.o -asm/cx86unix.cpp: +asm/cx86unix.cpp: asm/cast-586.pl (cd asm; perl cast-586.pl cpp >cx86unix.cpp) files: diff --git a/crypto/cast/asm/cast-586.pl b/crypto/cast/asm/cast-586.pl index d6b6f19bea..eda14ad413 100644 --- a/crypto/cast/asm/cast-586.pl +++ b/crypto/cast/asm/cast-586.pl @@ -32,136 +32,144 @@ $S4="CAST_S_table3"; &asm_finish(); -sub CAST_encrypt - { - local($name,$enc)=@_; +sub CAST_encrypt { + local($name,$enc)=@_; - local($win_ex)=<<"EOF"; + local($win_ex)=<<"EOF"; EXTERN _CAST_S_table0:DWORD EXTERN _CAST_S_table1:DWORD EXTERN _CAST_S_table2:DWORD EXTERN _CAST_S_table3:DWORD EOF - &main'external_label( - "CAST_S_table0", - "CAST_S_table1", - "CAST_S_table2", - "CAST_S_table3", - ); - - &function_begin_B($name,$win_ex); - - &comment(""); - - &push("ebp"); - &push("ebx"); - &mov($tmp2,&wparam(0)); - &mov($K,&wparam(1)); - &push("esi"); - &push("edi"); - - &comment("Load the 2 words"); - &mov($L,&DWP(0,$tmp2,"",0)); - &mov($R,&DWP(4,$tmp2,"",0)); - - &xor( $tmp3, $tmp3); - - # encrypting part - - if ($enc) - { - &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4,1); - } - else - { - &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); - &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4,1); - } - - &nop(); - &mov(&DWP(4,$tmp3,"",0),$L); - &mov(&DWP(0,$tmp3,"",0),$R); - &function_end($name); - } - -sub E_CAST - { - local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4,$lst)=@_; - # Ri needs to have 16 pre added. - - &comment("round $i"); - &mov( $tmp4, &DWP($i*8,$K,"",1)); - - &mov( $tmp1, &DWP($i*8+4,$K,"",1));# must be word - &$OP1( $tmp4, $R); - - &rotl( $tmp4, &LB($tmp1)); - - if ($ppro) - { - &mov( $tmp2, $tmp4); # B - &xor( $tmp1, $tmp1); - - &movb( &LB($tmp1), &HB($tmp4)); # A - &and( $tmp2, 0xff); - - &shr( $tmp4, 16); # - &xor( $tmp3, $tmp3); - } - else - { - &mov( $tmp2, $tmp4); # B - &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD - - &shr( $tmp4, 16); # - &and( $tmp2, 0xff); - } - - &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD - &and( $tmp4, 0xff); # D - - &mov( $tmp1, &DWP($S1,"",$tmp1,4)); - &mov( $tmp2, &DWP($S2,"",$tmp2,4)); - - &$OP2( $tmp1, $tmp2); - &mov( $tmp2, &DWP($S3,"",$tmp3,4)); - - &$OP3( $tmp1, $tmp2); - &mov( $tmp2, &DWP($S4,"",$tmp4,4)); - - &$OP1( $tmp1, $tmp2); - &mov($tmp3,&wparam(0)) if $lst; - # XXX - - &xor( $L, $tmp1); - # XXX - } + &main::external_label( + "CAST_S_table0", + "CAST_S_table1", + "CAST_S_table2", + "CAST_S_table3", + ); + + &function_begin_B($name,$win_ex); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &mov($tmp2,&wparam(0)); + &mov($K,&wparam(1)); + &push("esi"); + &push("edi"); + + &comment("Load the 2 words"); + &mov($L,&DWP(0,$tmp2,"",0)); + &mov($R,&DWP(4,$tmp2,"",0)); + + &comment('Get short key flag'); + &mov($tmp3,&DWP(128,$K,"",0)); + if($enc) { + &push($tmp3); + } else { + &or($tmp3,$tmp3); + &jnz(&label('cast_dec_skip')); + } + + &xor($tmp3, $tmp3); + + # encrypting part + + if ($enc) { + &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &comment('test short key flag'); + &pop($tmp4); + &or($tmp4,$tmp4); + &jnz(&label('cast_enc_done')); + &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } else { + &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &set_label('cast_dec_skip'); + &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } + + &set_label('cast_enc_done') if $enc; +# Why the nop? - Ben 17/1/99 + &nop(); + &mov($tmp3,&wparam(0)); + &mov(&DWP(4,$tmp3,"",0),$L); + &mov(&DWP(0,$tmp3,"",0),$R); + &function_end($name); +} + +sub E_CAST { + local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; + # Ri needs to have 16 pre added. + + &comment("round $i"); + &mov( $tmp4, &DWP($i*8,$K,"",1)); + + &mov( $tmp1, &DWP($i*8+4,$K,"",1)); + &$OP1( $tmp4, $R); + + &rotl( $tmp4, &LB($tmp1)); + + if ($ppro) { + &mov( $tmp2, $tmp4); # B + &xor( $tmp1, $tmp1); + + &movb( &LB($tmp1), &HB($tmp4)); # A + &and( $tmp2, 0xff); + + &shr( $tmp4, 16); # + &xor( $tmp3, $tmp3); + } else { + &mov( $tmp2, $tmp4); # B + &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD + + &shr( $tmp4, 16); # + &and( $tmp2, 0xff); + } + + &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD + &and( $tmp4, 0xff); # D + + &mov( $tmp1, &DWP($S1,"",$tmp1,4)); + &mov( $tmp2, &DWP($S2,"",$tmp2,4)); + + &$OP2( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S3,"",$tmp3,4)); + + &$OP3( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S4,"",$tmp4,4)); + + &$OP1( $tmp1, $tmp2); + # XXX + + &xor( $L, $tmp1); + # XXX +} diff --git a/crypto/cast/c_enc.c b/crypto/cast/c_enc.c index d998dd4953..5e6ecb31f5 100644 --- a/crypto/cast/c_enc.c +++ b/crypto/cast/c_enc.c @@ -81,10 +81,13 @@ CAST_KEY *key; E_CAST( 9,k,r,l,+,^,-); E_CAST(10,k,l,r,^,-,+); E_CAST(11,k,r,l,-,+,^); - E_CAST(12,k,l,r,+,^,-); - E_CAST(13,k,r,l,^,-,+); - E_CAST(14,k,l,r,-,+,^); - E_CAST(15,k,r,l,+,^,-); + if(!k->short_key) + { + E_CAST(12,k,l,r,+,^,-); + E_CAST(13,k,r,l,^,-,+); + E_CAST(14,k,l,r,-,+,^); + E_CAST(15,k,r,l,+,^,-); + } data[1]=l&0xffffffffL; data[0]=r&0xffffffffL; @@ -100,10 +103,13 @@ CAST_KEY *key; l=data[0]; r=data[1]; - E_CAST(15,k,l,r,+,^,-); - E_CAST(14,k,r,l,-,+,^); - E_CAST(13,k,l,r,^,-,+); - E_CAST(12,k,r,l,+,^,-); + if(!k->short_key) + { + E_CAST(15,k,l,r,+,^,-); + E_CAST(14,k,r,l,-,+,^); + E_CAST(13,k,l,r,^,-,+); + E_CAST(12,k,r,l,+,^,-); + } E_CAST(11,k,l,r,-,+,^); E_CAST(10,k,r,l,^,-,+); E_CAST( 9,k,l,r,+,^,-); diff --git a/crypto/cast/c_skey.c b/crypto/cast/c_skey.c index 2fc3363dcd..5262a2ebd2 100644 --- a/crypto/cast/c_skey.c +++ b/crypto/cast/c_skey.c @@ -88,6 +88,10 @@ unsigned char *data; if (len > 16) len=16; for (i=0; i<len; i++) x[i]=data[i]; + if(len <= 10) + key->short_key=1; + else + key->short_key=0; K= &k[0]; X[0]=((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL; diff --git a/crypto/cast/cast.h b/crypto/cast/cast.h index 528cb7c824..cbeb4fc1fa 100644 --- a/crypto/cast/cast.h +++ b/crypto/cast/cast.h @@ -74,6 +74,7 @@ extern "C" { typedef struct cast_key_st { CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ } CAST_KEY; #ifndef NOPROTO diff --git a/crypto/cast/casttest.c b/crypto/cast/casttest.c index 8b009bc249..d55400f5be 100644 --- a/crypto/cast/casttest.c +++ b/crypto/cast/casttest.c @@ -61,7 +61,7 @@ #include <stdlib.h> #include "cast.h" -/* #define FULL_TEST */ +#define FULL_TEST unsigned char k[16]={ 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78, @@ -70,7 +70,7 @@ unsigned char k[16]={ unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; -int k_len[3]={16,10}; +int k_len[3]={16,10,5}; unsigned char c[3][8]={ {0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2}, {0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B}, @@ -123,101 +123,102 @@ static unsigned char cfb_cipher64[CFB_TEST_SIZE]={ int main(argc,argv) int argc; char *argv[]; - { + { #ifdef FULL_TEST - long l; - CAST_KEY key_b; + long l; + CAST_KEY key_b; #endif - int i,z,err=0; - CAST_KEY key; + int i,z,err=0; + CAST_KEY key; - for (z=0; z<1; z++) - { + for (z=0; z<3; z++) + { CAST_set_key(&key,k_len[z],k); CAST_ecb_encrypt(in,out,&key,CAST_ENCRYPT); if (memcmp(out,&(c[z][0]),8) != 0) - { - printf("ecb cast error encrypting\n"); - printf("got :"); - for (i=0; i<8; i++) - printf("%02X ",out[i]); - printf("\n"); - printf("expected:"); - for (i=0; i<8; i++) - printf("%02X ",c[z][i]); - err=20; - printf("\n"); - } + { + printf("ecb cast error encrypting for keysize %d\n",k_len[z]*8); + printf("got :"); + for (i=0; i<8; i++) + printf("%02X ",out[i]); + printf("\n"); + printf("expected:"); + for (i=0; i<8; i++) + printf("%02X ",c[z][i]); + err=20; + printf("\n"); + } CAST_ecb_encrypt(out,out,&key,CAST_DECRYPT); if (memcmp(out,in,8) != 0) - { - printf("ecb cast error decrypting\n"); - printf("got :"); - for (i=0; i<8; i++) - printf("%02X ",out[i]); - printf("\n"); - printf("expected:"); - for (i=0; i<8; i++) - printf("%02X ",in[i]); - printf("\n"); - err=3; - } + { + printf("ecb cast error decrypting for keysize %d\n",k_len[z]*8); + printf("got :"); + for (i=0; i<8; i++) + printf("%02X ",out[i]); + printf("\n"); + printf("expected:"); + for (i=0; i<8; i++) + printf("%02X ",in[i]); + printf("\n"); + err=3; + } } - if (err == 0) printf("ecb cast5 ok\n"); + if (err == 0) + printf("ecb cast5 ok\n"); #ifdef FULL_TEST - { - unsigned char out_a[16],out_b[16]; - static char *hex="0123456789ABCDEF"; - - printf("This test will take some time...."); - fflush(stdout); - memcpy(out_a,in_a,sizeof(in_a)); - memcpy(out_b,in_b,sizeof(in_b)); - i=1; - - for (l=0; l<1000000L; l++) - { - CAST_set_key(&key_b,16,out_b); - CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT); - CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT); - CAST_set_key(&key,16,out_a); - CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT); - CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT); - if ((l & 0xffff) == 0xffff) - { - printf("%c",hex[i&0x0f]); - fflush(stdout); - i++; - } - } - - if ( (memcmp(out_a,c_a,sizeof(c_a)) != 0) || + { + unsigned char out_a[16],out_b[16]; + static char *hex="0123456789ABCDEF"; + + printf("This test will take some time...."); + fflush(stdout); + memcpy(out_a,in_a,sizeof(in_a)); + memcpy(out_b,in_b,sizeof(in_b)); + i=1; + + for (l=0; l<1000000L; l++) + { + CAST_set_key(&key_b,16,out_b); + CAST_ecb_encrypt(&(out_a[0]),&(out_a[0]),&key_b,CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_a[8]),&(out_a[8]),&key_b,CAST_ENCRYPT); + CAST_set_key(&key,16,out_a); + CAST_ecb_encrypt(&(out_b[0]),&(out_b[0]),&key,CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_b[8]),&(out_b[8]),&key,CAST_ENCRYPT); + if ((l & 0xffff) == 0xffff) + { + printf("%c",hex[i&0x0f]); + fflush(stdout); + i++; + } + } + + if ( (memcmp(out_a,c_a,sizeof(c_a)) != 0) || (memcmp(out_b,c_b,sizeof(c_b)) != 0)) - { - printf("\n"); - printf("Error\n"); - - printf("A out ="); - for (i=0; i<16; i++) printf("%02X ",out_a[i]); - printf("\nactual="); - for (i=0; i<16; i++) printf("%02X ",c_a[i]); - printf("\n"); - - printf("B out ="); - for (i=0; i<16; i++) printf("%02X ",out_b[i]); - printf("\nactual="); - for (i=0; i<16; i++) printf("%02X ",c_b[i]); - printf("\n"); - } - else - printf(" ok\n"); - } + { + printf("\n"); + printf("Error\n"); + + printf("A out ="); + for (i=0; i<16; i++) printf("%02X ",out_a[i]); + printf("\nactual="); + for (i=0; i<16; i++) printf("%02X ",c_a[i]); + printf("\n"); + + printf("B out ="); + for (i=0; i<16; i++) printf("%02X ",out_b[i]); + printf("\nactual="); + for (i=0; i<16; i++) printf("%02X ",c_b[i]); + printf("\n"); + } + else + printf(" ok\n"); + } #endif - exit(err); - return(err); - } + exit(err); + return(err); + } |