summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <>2018-09-12 06:35:38 +0000
committerdjm <>2018-09-12 06:35:38 +0000
commit8862867fd25d4b58970fbba6b27ed2a36347500d (patch)
treeaaeca881a5b92a89a54597eeb5aacdbd9d58fe30
parent55621332fb7374cfcfccae0561ed84e62513e575 (diff)
downloadopenbsd-8862867fd25d4b58970fbba6b27ed2a36347500d.tar.gz
openbsd-8862867fd25d4b58970fbba6b27ed2a36347500d.tar.bz2
openbsd-8862867fd25d4b58970fbba6b27ed2a36347500d.zip
Add some accessor functions:
RSA_meth_get_finish() RSA_meth_set1_name() EVP_CIPHER_CTX_(get|set)_iv() feedback and ok jsing@ tb@
-rw-r--r--src/lib/libcrypto/Symbols.list4
-rw-r--r--src/lib/libcrypto/evp/evp.h6
-rw-r--r--src/lib/libcrypto/evp/evp_lib.c40
-rw-r--r--src/lib/libcrypto/man/EVP_EncryptInit.335
-rw-r--r--src/lib/libcrypto/man/RSA_meth_new.344
-rw-r--r--src/lib/libcrypto/rsa/rsa.h4
-rw-r--r--src/lib/libcrypto/rsa/rsa_meth.c20
-rw-r--r--src/lib/libcrypto/shlib_version2
8 files changed, 138 insertions, 17 deletions
diff --git a/src/lib/libcrypto/Symbols.list b/src/lib/libcrypto/Symbols.list
index ea5c93995b..7851c4c3a6 100644
--- a/src/lib/libcrypto/Symbols.list
+++ b/src/lib/libcrypto/Symbols.list
@@ -1262,6 +1262,7 @@ EVP_CIPHER_CTX_encrypting
1262EVP_CIPHER_CTX_flags 1262EVP_CIPHER_CTX_flags
1263EVP_CIPHER_CTX_free 1263EVP_CIPHER_CTX_free
1264EVP_CIPHER_CTX_get_app_data 1264EVP_CIPHER_CTX_get_app_data
1265EVP_CIPHER_CTX_get_iv
1265EVP_CIPHER_CTX_init 1266EVP_CIPHER_CTX_init
1266EVP_CIPHER_CTX_iv_length 1267EVP_CIPHER_CTX_iv_length
1267EVP_CIPHER_CTX_key_length 1268EVP_CIPHER_CTX_key_length
@@ -1271,6 +1272,7 @@ EVP_CIPHER_CTX_rand_key
1271EVP_CIPHER_CTX_reset 1272EVP_CIPHER_CTX_reset
1272EVP_CIPHER_CTX_set_app_data 1273EVP_CIPHER_CTX_set_app_data
1273EVP_CIPHER_CTX_set_flags 1274EVP_CIPHER_CTX_set_flags
1275EVP_CIPHER_CTX_set_iv
1274EVP_CIPHER_CTX_set_key_length 1276EVP_CIPHER_CTX_set_key_length
1275EVP_CIPHER_CTX_set_padding 1277EVP_CIPHER_CTX_set_padding
1276EVP_CIPHER_CTX_test_flags 1278EVP_CIPHER_CTX_test_flags
@@ -2274,7 +2276,9 @@ RSA_get_ex_new_index
2274RSA_get_method 2276RSA_get_method
2275RSA_meth_dup 2277RSA_meth_dup
2276RSA_meth_free 2278RSA_meth_free
2279RSA_meth_get_finish
2277RSA_meth_new 2280RSA_meth_new
2281RSA_meth_set1_name
2278RSA_meth_set_finish 2282RSA_meth_set_finish
2279RSA_meth_set_priv_dec 2283RSA_meth_set_priv_dec
2280RSA_meth_set_priv_enc 2284RSA_meth_set_priv_enc
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 1684b13e49..c09e2c046a 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp.h,v 1.68 2018/08/24 20:22:15 tb Exp $ */ 1/* $OpenBSD: evp.h,v 1.69 2018/09/12 06:35:38 djm Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -496,6 +496,10 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
496int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); 496int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
497int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); 497int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
498int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); 498int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
499int EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx,
500 unsigned char *iv, size_t len);
501int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx,
502 const unsigned char *iv, size_t len);
499int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); 503int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
500void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); 504void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
501void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); 505void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c
index 3571755620..90107739e7 100644
--- a/src/lib/libcrypto/evp/evp_lib.c
+++ b/src/lib/libcrypto/evp/evp_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: evp_lib.c,v 1.16 2018/08/24 19:36:52 tb Exp $ */ 1/* $OpenBSD: evp_lib.c,v 1.17 2018/09/12 06:35:38 djm Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -274,6 +274,44 @@ EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
274} 274}
275 275
276int 276int
277EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len)
278{
279 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
280 return 0;
281 if (len > EVP_MAX_IV_LENGTH)
282 return 0; /* sanity check; shouldn't happen */
283 /*
284 * Skip the memcpy entirely when the requested IV length is zero,
285 * since the iv pointer may be NULL or invalid.
286 */
287 if (len != 0) {
288 if (iv == NULL)
289 return 0;
290 memcpy(iv, ctx->iv, len);
291 }
292 return 1;
293}
294
295int
296EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len)
297{
298 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx))
299 return 0;
300 if (len > EVP_MAX_IV_LENGTH)
301 return 0; /* sanity check; shouldn't happen */
302 /*
303 * Skip the memcpy entirely when the requested IV length is zero,
304 * since the iv pointer may be NULL or invalid.
305 */
306 if (len != 0) {
307 if (iv == NULL)
308 return 0;
309 memcpy(ctx->iv, iv, len);
310 }
311 return 1;
312}
313
314int
277EVP_MD_block_size(const EVP_MD *md) 315EVP_MD_block_size(const EVP_MD *md)
278{ 316{
279 return md->block_size; 317 return md->block_size;
diff --git a/src/lib/libcrypto/man/EVP_EncryptInit.3 b/src/lib/libcrypto/man/EVP_EncryptInit.3
index 1409bfed69..0dbaa6c848 100644
--- a/src/lib/libcrypto/man/EVP_EncryptInit.3
+++ b/src/lib/libcrypto/man/EVP_EncryptInit.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: EVP_EncryptInit.3,v 1.23 2018/08/28 17:47:29 tb Exp $ 1.\" $OpenBSD: EVP_EncryptInit.3,v 1.24 2018/09/12 06:35:38 djm Exp $
2.\" full merge up to: OpenSSL 5211e094 Nov 11 14:39:11 2014 -0800 2.\" full merge up to: OpenSSL 5211e094 Nov 11 14:39:11 2014 -0800
3.\" selective merge up to: OpenSSL 16cfc2c9 Mar 8 22:30:28 2018 +0100 3.\" selective merge up to: OpenSSL 16cfc2c9 Mar 8 22:30:28 2018 +0100
4.\" 4.\"
@@ -51,7 +51,7 @@
51.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52.\" OF THE POSSIBILITY OF SUCH DAMAGE. 52.\" OF THE POSSIBILITY OF SUCH DAMAGE.
53.\" 53.\"
54.Dd $Mdocdate: August 28 2018 $ 54.Dd $Mdocdate: September 12 2018 $
55.Dt EVP_ENCRYPTINIT 3 55.Dt EVP_ENCRYPTINIT 3
56.Os 56.Os
57.Sh NAME 57.Sh NAME
@@ -94,6 +94,8 @@
94.Nm EVP_CIPHER_CTX_block_size , 94.Nm EVP_CIPHER_CTX_block_size ,
95.Nm EVP_CIPHER_CTX_key_length , 95.Nm EVP_CIPHER_CTX_key_length ,
96.Nm EVP_CIPHER_CTX_iv_length , 96.Nm EVP_CIPHER_CTX_iv_length ,
97.Nm EVP_CIPHER_CTX_get_iv ,
98.Nm EVP_CIPHER_CTX_set_iv ,
97.Nm EVP_CIPHER_CTX_get_app_data , 99.Nm EVP_CIPHER_CTX_get_app_data ,
98.Nm EVP_CIPHER_CTX_set_app_data , 100.Nm EVP_CIPHER_CTX_set_app_data ,
99.Nm EVP_CIPHER_CTX_type , 101.Nm EVP_CIPHER_CTX_type ,
@@ -367,6 +369,18 @@
367.Fo EVP_CIPHER_CTX_iv_length 369.Fo EVP_CIPHER_CTX_iv_length
368.Fa "const EVP_CIPHER_CTX *ctx" 370.Fa "const EVP_CIPHER_CTX *ctx"
369.Fc 371.Fc
372.Ft int
373.Fo EVP_CIPHER_CTX_get_iv
374.Fa "const EVP_CIPHER_CTX *ctx"
375.Fa "u_char *iv"
376.Fa "size_t len"
377.Fc
378.Ft int
379.Fo EVP_CIPHER_CTX_set_iv
380.Fa "EVP_CIPHER_CTX *ctx"
381.Fa "const u_char *iv"
382.Fa "size_t len"
383.Fc
370.Ft void * 384.Ft void *
371.Fo EVP_CIPHER_CTX_get_app_data 385.Fo EVP_CIPHER_CTX_get_app_data
372.Fa "const EVP_CIPHER_CTX *ctx" 386.Fa "const EVP_CIPHER_CTX *ctx"
@@ -651,6 +665,15 @@ The constant
651.Dv EVP_MAX_IV_LENGTH 665.Dv EVP_MAX_IV_LENGTH
652is the maximum IV length for all ciphers. 666is the maximum IV length for all ciphers.
653.Pp 667.Pp
668.Fn EVP_CIPHER_CTX_get_iv
669and
670.Fn EVP_CIPHER_CTX_set_iv
671will respectively retrieve and set the IV for a
672.Vt EVP_CIPHER_CTX .
673In both cases, the specified IV length must exactly equal the expected
674IV length for the context as returned by
675.Fn EVP_CIPHER_CTX_iv_length .
676.Pp
654.Fn EVP_CIPHER_block_size 677.Fn EVP_CIPHER_block_size
655and 678and
656.Fn EVP_CIPHER_CTX_block_size 679.Fn EVP_CIPHER_CTX_block_size
@@ -804,6 +827,8 @@ for failure.
804.Pp 827.Pp
805.Fn EVP_CIPHER_CTX_reset , 828.Fn EVP_CIPHER_CTX_reset ,
806.Fn EVP_CIPHER_CTX_cleanup , 829.Fn EVP_CIPHER_CTX_cleanup ,
830.Fn EVP_CIPHER_CTX_get_iv ,
831.Fn EVP_CIPHER_CTX_set_iv ,
807.Fn EVP_EncryptInit_ex , 832.Fn EVP_EncryptInit_ex ,
808.Fn EVP_EncryptUpdate , 833.Fn EVP_EncryptUpdate ,
809.Fn EVP_EncryptFinal_ex , 834.Fn EVP_EncryptFinal_ex ,
@@ -1330,6 +1355,12 @@ first appeared in OpenSSL 1.0.1 and have been available since
1330.Fn EVP_CIPHER_CTX_reset 1355.Fn EVP_CIPHER_CTX_reset
1331first appeared in OpenSSL 1.1.0 and has been available since 1356first appeared in OpenSSL 1.1.0 and has been available since
1332.Ox 6.3 . 1357.Ox 6.3 .
1358.Pp
1359.Fn EVP_CIPHER_CTX_get_iv
1360and
1361.Fn EVP_CIPHER_CTX_set_iv
1362first appeared in LibreSSL 2.8.1 and has been available since
1363.Ox 6.4 .
1333.Sh BUGS 1364.Sh BUGS
1334.Dv EVP_MAX_KEY_LENGTH 1365.Dv EVP_MAX_KEY_LENGTH
1335and 1366and
diff --git a/src/lib/libcrypto/man/RSA_meth_new.3 b/src/lib/libcrypto/man/RSA_meth_new.3
index ae3ca88adb..6eabcc5bf8 100644
--- a/src/lib/libcrypto/man/RSA_meth_new.3
+++ b/src/lib/libcrypto/man/RSA_meth_new.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: RSA_meth_new.3,v 1.1 2018/03/18 13:06:36 schwarze Exp $ 1.\" $OpenBSD: RSA_meth_new.3,v 1.2 2018/09/12 06:35:38 djm Exp $
2.\" selective merge up to: OpenSSL a970b14f Jul 31 18:58:40 2017 -0400 2.\" selective merge up to: OpenSSL a970b14f Jul 31 18:58:40 2017 -0400
3.\" 3.\"
4.\" This file is a derived work. 4.\" This file is a derived work.
@@ -65,13 +65,15 @@
65.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 65.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
66.\" OF THE POSSIBILITY OF SUCH DAMAGE. 66.\" OF THE POSSIBILITY OF SUCH DAMAGE.
67.\" 67.\"
68.Dd $Mdocdate: March 18 2018 $ 68.Dd $Mdocdate: September 12 2018 $
69.Dt RSA_METH_NEW 3 69.Dt RSA_METH_NEW 3
70.Os 70.Os
71.Sh NAME 71.Sh NAME
72.Nm RSA_meth_new , 72.Nm RSA_meth_new ,
73.Nm RSA_meth_free ,
74.Nm RSA_meth_dup , 73.Nm RSA_meth_dup ,
74.Nm RSA_meth_free ,
75.Nm RSA_meth_get_finish ,
76.Nm RSA_meth_set1_name ,
75.Nm RSA_meth_set_finish , 77.Nm RSA_meth_set_finish ,
76.Nm RSA_meth_set_priv_enc , 78.Nm RSA_meth_set_priv_enc ,
77.Nm RSA_meth_set_priv_dec 79.Nm RSA_meth_set_priv_dec
@@ -83,15 +85,22 @@
83.Fa "const char *name" 85.Fa "const char *name"
84.Fa "int flags" 86.Fa "int flags"
85.Fc 87.Fc
88.Ft RSA_METHOD *
89.Fo RSA_meth_dup
90.Fa "const RSA_METHOD *meth"
91.Fc
86.Ft void 92.Ft void
87.Fo RSA_meth_free 93.Fo RSA_meth_free
88.Fa "RSA_METHOD *meth" 94.Fa "RSA_METHOD *meth"
89.Fc 95.Fc
90.Ft RSA_METHOD * 96.Ft int
91.Fo RSA_meth_dup 97.Fo RSA_meth_set1_name
92.Fa "const RSA_METHOD *meth" 98.Fa "RSA_METHOD *meth"
99.Fa "const char *name"
93.Fc 100.Fc
94.Ft int 101.Ft int
102.Fn "(*RSA_meth_get_finish(const RSA_METHOD *meth))" "RSA *rsa"
103.Ft int
95.Fo RSA_meth_set_finish 104.Fo RSA_meth_set_finish
96.Fa "RSA_METHOD *meth" 105.Fa "RSA_METHOD *meth"
97.Fa "int (*finish)(RSA *rsa)" 106.Fa "int (*finish)(RSA *rsa)"
@@ -142,8 +151,18 @@ destroys
142.Fa meth 151.Fa meth
143and frees any memory associated with it. 152and frees any memory associated with it.
144.Pp 153.Pp
154.Fn RSA_meth_set1_name
155Stores a copy of the NUL-terminated
156.Fa name
157in the
158.Vt RSA_METHOD
159object after freeing the previously stored
160.Fa name.
161.Pp
162.Fn RSA_meth_get_finish
163and
145.Fn RSA_meth_set_finish 164.Fn RSA_meth_set_finish
146sets an optional function for destroying an 165get and set an optional function for destroying an
147.Vt RSA 166.Vt RSA
148object. 167object.
149Unless 168Unless
@@ -180,7 +199,7 @@ object or
180on failure. 199on failure.
181.Pp 200.Pp
182All 201All
183.Fn RSA_meth_set_* 202.Fn RSA_meth_set*
184functions return 1 on success or 0 on failure. 203functions return 1 on success or 0 on failure.
185.Sh SEE ALSO 204.Sh SEE ALSO
186.Xr RSA_new 3 , 205.Xr RSA_new 3 ,
@@ -188,6 +207,11 @@ functions return 1 on success or 0 on failure.
188.Xr RSA_private_encrypt 3 , 207.Xr RSA_private_encrypt 3 ,
189.Xr RSA_set_method 3 208.Xr RSA_set_method 3
190.Sh HISTORY 209.Sh HISTORY
191These functions first appeared in OpenSSL 1.1.0 210These functions first appeared in OpenSSL 1.1.0.
192and have been available since 211.Fn RSA_meth_get_finish
212and
213.Fn RSA_meth_set1_name
214have been available since
215.Ox 6.4 ,
216all the other functions since
193.Ox 6.3 . 217.Ox 6.3 .
diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h
index 23929aafb9..d2df1a92d3 100644
--- a/src/lib/libcrypto/rsa/rsa.h
+++ b/src/lib/libcrypto/rsa/rsa.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa.h,v 1.38 2018/03/17 15:12:56 tb Exp $ */ 1/* $OpenBSD: rsa.h,v 1.39 2018/09/12 06:35:38 djm Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -433,10 +433,12 @@ RSA *RSAPrivateKey_dup(RSA *rsa);
433RSA_METHOD *RSA_meth_new(const char *name, int flags); 433RSA_METHOD *RSA_meth_new(const char *name, int flags);
434void RSA_meth_free(RSA_METHOD *meth); 434void RSA_meth_free(RSA_METHOD *meth);
435RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth); 435RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth);
436int RSA_meth_set1_name(RSA_METHOD *meth, const char *name);
436int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, 437int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen,
437 const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); 438 const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
438int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen, 439int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec)(int flen,
439 const unsigned char *from, unsigned char *to, RSA *rsa, int padding)); 440 const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
441int (*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa);
440int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa)); 442int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish)(RSA *rsa));
441 443
442/* BEGIN ERROR CODES */ 444/* BEGIN ERROR CODES */
diff --git a/src/lib/libcrypto/rsa/rsa_meth.c b/src/lib/libcrypto/rsa/rsa_meth.c
index 0e52799a38..ae613cc65c 100644
--- a/src/lib/libcrypto/rsa/rsa_meth.c
+++ b/src/lib/libcrypto/rsa/rsa_meth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: rsa_meth.c,v 1.1 2018/03/17 15:12:56 tb Exp $ */ 1/* $OpenBSD: rsa_meth.c,v 1.2 2018/09/12 06:35:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org> 3 * Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
4 * 4 *
@@ -63,6 +63,24 @@ RSA_meth_dup(const RSA_METHOD *meth)
63} 63}
64 64
65int 65int
66RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
67{
68 char *copy;
69
70 if ((copy = strdup(name)) == NULL)
71 return 0;
72 free((char *)meth->name);
73 meth->name = copy;
74 return 1;
75}
76
77int
78(*RSA_meth_get_finish(const RSA_METHOD *meth))(RSA *rsa)
79{
80 return meth->finish;
81}
82
83int
66RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen, 84RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc)(int flen,
67 const unsigned char *from, unsigned char *to, RSA *rsa, int padding)) 85 const unsigned char *from, unsigned char *to, RSA *rsa, int padding))
68{ 86{
diff --git a/src/lib/libcrypto/shlib_version b/src/lib/libcrypto/shlib_version
index 5f1adc35ef..77964f81e8 100644
--- a/src/lib/libcrypto/shlib_version
+++ b/src/lib/libcrypto/shlib_version
@@ -1,3 +1,3 @@
1# Don't forget to give libssl and libtls the same type of bump! 1# Don't forget to give libssl and libtls the same type of bump!
2major=44 2major=44
3minor=0 3minor=1