Index: /branches/rel_apv_10_7_3/usr/click/lib/libcrypto_app/tlsv13_crypto.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libcrypto_app/tlsv13_crypto.c	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libcrypto_app/tlsv13_crypto.c	(working copy)
@@ -70,7 +70,7 @@
 			uint8_t *data, uint32_t data_len,
 			uint8_t *out, uint32_t out_len)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	
 	const char label_prefix[] = "tls13 ";
 	EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
@@ -183,7 +183,7 @@
 			uint8_t *message, uint32_t message_len,
 			uint8_t *out, uint32_t out_len)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	
 	EVP_MD *md;
 	uint8_t hash[EVP_MAX_MD_SIZE];
@@ -239,7 +239,7 @@
 			uint8_t *insecret, uint32_t insecretlen,
 			uint8_t *outsecret, uint32_t outsecretlen)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	
 	int ret;
 	EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
@@ -368,7 +368,7 @@
 int tlsv13_derive_key(uint32_t hash_len, uint8_t *secret, 
 		     uint8_t *key, uint32_t keylen)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	const char keylabel[] = "key";
 
 	return tlsv13_hkdf_expand_label(hash_len, secret, keylabel, sizeof(keylabel) - 1, NULL, 0, key, keylen);
@@ -381,7 +381,7 @@
 int tlsv13_derive_iv(uint32_t hash_len, uint8_t *secret,
 		    uint8_t *iv, uint32_t ivlen)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	const char ivlabel[] = "iv";
 
 	return tlsv13_hkdf_expand_label(hash_len, secret, ivlabel, sizeof(ivlabel) - 1, NULL, 0, iv, ivlen);
@@ -390,7 +390,7 @@
 int tlsv13_derive_finishedkey(uint32_t hash_len, uint8_t *secret,
 			     uint8_t *fin, uint32_t finlen)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	const char finishedlabel[] = "finished";
 
 	return tlsv13_hkdf_expand_label(hash_len, secret, finishedlabel, sizeof(finishedlabel) - 1, NULL, 0, fin, finlen);
@@ -417,7 +417,7 @@
 				uint8_t *key,
 				uint32_t key_len)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	int ret, taglen;
 	EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)aead_ctx;
 	EVP_CIPHER *evp_cip;
@@ -512,7 +512,7 @@
 			uint32_t *output_len_list,
 			uint32_t output_num)
 {
-	ssl_dbg_printf("Called in.\n");
+	ssl_dbg_printf("Called in func:%s\n", __FUNCTION__);
 	EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)aead_ctx;
 	int i, ret, taglen, offset, len_updata, len_final;
 	uint8_t *p_aad, *p_tag, tag_buf[EVP_GCM_TLS_TAG_LEN];
@@ -520,7 +520,7 @@
 	uint32_t input_total_len, output_total_len, total_outlen, tmp_outlen, tmp_inlen;
 	int i_idx, o_idx;
 	
-
+	ssl_dbg_printf("is_enc=%d. click_cipher=%x\n",is_enc,click_cipher);
 	/* Set cipher type and mode */
 	switch (click_cipher) {
 	case CLICK_SSL_AES128GCM:
@@ -569,6 +569,7 @@
 		}
 	}
 
+	/* Also set tag length in tlsv13_derive_secret_key_and_iv for CCM, this could be redundant? */
 	if ((click_cipher & CLICK_TLSV13_CCM) &&
 			is_enc && 
 			EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) {
@@ -678,7 +679,8 @@
 	tmp_outlen = 0;
 	tmp_inlen = 0;
 	total_outlen = 0;
-	while (i_idx < input_num) {
+
+	while (i_idx < input_num && !(click_cipher & CLICK_TLSV13_CCM)) {
 		uint32_t input_entry_len;
 		
 		if (output_len_list[o_idx] >= input_len_list[i_idx]) {
@@ -715,7 +717,67 @@
 			tmp_outlen = 0;
 		}
 	}
-	
+
+	/* For CCM mode, we can skipped the while loop above.
+	*  Beacause we can only call once for EVP_cipherupdate() to deal with plantext.
+	*  Merge all input into one input buffer then EVP update using input_buf.
+	*  input_list[i_idx] -> input_buf -> output_buf -> output_list[o_idx] 
+	*/
+	if (click_cipher & CLICK_TLSV13_CCM) {
+		uint32_t buf_len = (input_total_len > output_total_len) ? input_total_len : output_total_len;
+		uint8_t *input_buf = (uint8_t *)malloc(buf_len);
+		uint8_t *output_buf = (uint8_t *)malloc(buf_len);
+
+		// ssl_dbg_printf("buf_len = %u, input_total_len=%u, output_total_len=%u\n", buf_len, input_total_len, output_total_len);
+
+		if (!input_buf || !output_buf) {
+			ssl_dbg_printf("CCM input/output buffer malloc failed!\n");
+			free(input_buf);
+			free(output_buf);
+			return -1;
+		}
+
+		// merge every input_list[] to input_buf
+		uint32_t copied = 0;
+		for (i_idx = 0; i_idx < input_num; i_idx++) {
+			uint32_t len_to_copy = input_len_list[i_idx];
+			if (copied + len_to_copy > buf_len) {
+				ssl_dbg_printf("risk of input_buf overflow, copied=%u + len=%u > buf_len=%u\n", copied, len_to_copy, buf_len);
+				free(input_buf);
+				free(output_buf);
+				return -1;
+			}
+			memcpy(input_buf + copied, input_list[i_idx], len_to_copy);
+			copied += len_to_copy;
+			input_len_list[i_idx] = 0;
+		}
+
+		int len = 0;
+		if (EVP_CipherUpdate(ctx, output_buf, &len, input_buf, input_total_len) <= 0) {
+			ssl_dbg_printf("EVP_CipherUpdate failed in CCM mode\n");
+			free(input_buf);
+			free(output_buf);
+			return -1;
+		}
+
+		// output_buf spread back to output_list[]
+		copied = 0;
+		uint32_t remain = len;
+		for (o_idx = 0; o_idx < output_num && remain > 0; o_idx++) {
+			uint32_t len_to_copy = (remain < output_len_list[o_idx]) ? remain : output_len_list[o_idx];
+			memcpy(output_list[o_idx], output_buf + copied, len_to_copy);
+			copied += len_to_copy;
+			remain -= len_to_copy;
+			output_len_list[o_idx] = 0;
+		}
+
+		total_outlen = len;
+		o_idx--; /* bring o_idx back after last for-loop iteration */
+
+		free(input_buf);
+		free(output_buf);
+	}
+
 	ssl_dbg_printf("i_idx:%d, o_idx:%d, total_outlen:%d\n", i_idx, o_idx, total_outlen);
 
 	if (o_idx+1 != output_num) {
Index: /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.h
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.h	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.h	(working copy)
@@ -179,19 +179,15 @@
 	ECDHE_SM4_SM3_TYPE,
 	TLS13_AES256_GCM_SHA384_TYPE,
 	TLS13_AES128_GCM_SHA256_TYPE,
-#if 0 /* TLSV13 TODO */
+	TLS13_CHACHA20_POLY1305_SHA256_TYPE,
 	TLS13_AES_128_CCM_8_SHA256_TYPE,
 	TLS13_AES128_CCM_SHA256_TYPE,
-	TLS13_CHACHA20_POLY1305_SHA256_TYPE,
-#endif
 	ECC_SM4_GCM_SM3_TYPE,
 	ECDHE_SM4_GCM_SM3_TYPE,
 	MAX_CIPHER_TYPE,
 } cipher_t;
 
-/* TLSV13 TODO */
-//#define SSL_TLS13_SUPPORTED_CIPHERS "TLS-AES256-GCM-SHA384:TLS-AES128-GCM-SHA256:TLS-AES128-CCM-8-SHA256:TLS-AES128-CCM-SHA256:TLS-CHACHA20-POLY1305-SHA256"
-#define SSL_TLS13_SUPPORTED_CIPHERS "TLS-AES256-GCM-SHA384:TLS-AES128-GCM-SHA256"
+#define SSL_TLS13_SUPPORTED_CIPHERS "TLS-AES256-GCM-SHA384:TLS-AES128-GCM-SHA256:TLS-AES128-CCM-8-SHA256:TLS-AES128-CCM-SHA256:TLS-CHACHA20-POLY1305-SHA256"
 #define TLSV13_SUPPORTED_SIGNATURE_CIPHERS "ecdsa:rsae:rsapss"
 
 #define MAX_CIPHERSUITE_ID_TYPE (MAX_CIPHER_TYPE-1) /* Not contain "NONE_SSLV2_TYPE" cipher id */
Index: /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.c	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libssl_cli/ssl_cli.c	(working copy)
@@ -2564,7 +2564,9 @@
 	if( ((p1 = strstr(cipherList, "ECDHE-ECDSA-AES128-SHA")) != NULL) || ((p1 = strstr(cipherList, "ECDHE-ECDSA-AES256-SHA")) != NULL) || 
 		((p1 = strstr(cipherList, "ECDHE-ECDSA-AES128-SHA256")) != NULL) || ((p1 = strstr(cipherList, "ECDHE-ECDSA-AES256-SHA384")) != NULL) ||
 		((p1 = strstr(cipherList, "ECDHE-ECDSA-AES128-GCM-SHA256")) != NULL) || ((p1 = strstr(cipherList, "ECDHE-ECDSA-AES256-GCM-SHA384")) != NULL) ||
-		((p1 = strstr(cipherList, "TLS-AES256-GCM-SHA384")) != NULL) || ((p1 = strstr(cipherList, "TLS-AES128-GCM-SHA256")) != NULL)) { 
+		((p1 = strstr(cipherList, "TLS-AES256-GCM-SHA384")) != NULL) || ((p1 = strstr(cipherList, "TLS-AES128-GCM-SHA256")) != NULL) ||
+		((p1 = strstr(cipherList, "TLS-CHACHA20-POLY1305-SHA256")) != NULL) ||
+		((p1 = strstr(cipherList, "TLS-AES128-CCM-SHA256")) != NULL) || ((p1 = strstr(cipherList, "TLS-AES128-CCM-8-SHA256")) != NULL)) {
 #if 0   //Move these "RSA" related ciphers to be part of valid RSA ciphers as Venky's suggestion on 04/29/2015.
 		||  
 		((p1 = strstr(cipherList, "ECDHE-RSA-AES128-SHA")) != NULL) || ((p1 = strstr(cipherList, "ECDHE-RSA-AES256-SHA")) != NULL) || 
@@ -2615,7 +2617,10 @@
 		   (strcmp(cipher, "ECDHE-RSA-AES128-GCM-SHA256") == 0) ||
 		   (strcmp(cipher, "ECDHE-RSA-AES256-GCM-SHA384") == 0) ||
 		   (strcmp(cipher, "TLS-AES128-GCM-SHA256") == 0) || 
-		   (strcmp(cipher, "TLS-AES256-GCM-SHA384") == 0)) {
+		   (strcmp(cipher, "TLS-AES256-GCM-SHA384") == 0) ||
+		   (strcmp(cipher, "TLS-CHACHA20-POLY1305-SHA256") == 0) ||
+		   (strcmp(cipher, "TLS-AES128-CCM-SHA256") == 0) ||
+		   (strcmp(cipher, "TLS-AES128-CCM-8-SHA256") == 0)) {
 			//printf("matching RSA cipher=%s, given cipherstring=%s.\n", cipher, cipherList);
 			free(tofree);
 			return 1;
@@ -25658,11 +25663,9 @@
 	{ECDHE_SM4_SM3_CIPHER,0},
 	{"TLS-AES128-GCM-SHA256",0},
 	{"TLS-AES256-GCM-SHA384",0},
-#if 0 /* comment tls13 unsupported cipher temporary */
+	{"TLS-CHACHA20-POLY1305-SHA256",0},
 	{"TLS-AES128-CCM-8-SHA256",0},
 	{"TLS-AES128-CCM-SHA256",0},
-	{"TLS-CHACHA20-POLY1305-SHA256",0}
-#endif
 	{ECC_SM4_GCM_SM3_CIPHER, 0},
 	{ECDHE_SM4_GCM_SM3_CIPHER, 0}
 };
@@ -25716,11 +25719,9 @@
 					switch (i) {
 						case TLS13_AES256_GCM_SHA384_TYPE:
 						case TLS13_AES128_GCM_SHA256_TYPE:
-#if 0 /* TLSV13 TODO */
+						case TLS13_CHACHA20_POLY1305_SHA256_TYPE:
 						case TLS13_AES_128_CCM_8_SHA256_TYPE:
 						case TLS13_AES128_CCM_SHA256_TYPE:
-						case TLS13_CHACHA20_POLY1305_SHA256_TYPE:
-#endif
 							break;
 						default:
 							just_tlsv13_cipher = 0;
@@ -25786,26 +25787,24 @@
 			printf("%s", ciphers[TLS13_AES128_GCM_SHA256_TYPE].name);
 			found_tlsv13_cipher++;
 		}
-#if 0 /* TLSV13 TODO */
-		if ( ciphers[TLS13_AES_128_CCM_8_SHA256_TYPE].count ) {
+		if ( ciphers[TLS13_CHACHA20_POLY1305_SHA256_TYPE].count) {
 			if ( found_tls12_cipher >= 1)
 				printf(", ");
-			printf("%s", ciphers[TLS13_AES_128_CCM_8_SHA256_TYPE].name);
+			printf("%s", ciphers[TLS13_CHACHA20_POLY1305_SHA256_TYPE].name);
 			found_tlsv13_cipher++;
 		}
-		if ( ciphers[TLS13_AES128_CCM_SHA256_TYPE].count ) {
+		if ( ciphers[TLS13_AES_128_CCM_8_SHA256_TYPE].count ) {
 			if ( found_tls12_cipher >= 1)
 				printf(", ");
-			printf("%s", ciphers[TLS13_AES128_CCM_SHA256_TYPE].name);
+			printf("%s", ciphers[TLS13_AES_128_CCM_8_SHA256_TYPE].name);
 			found_tlsv13_cipher++;
 		}
-		if ( ciphers[TLS13_CHACHA20_POLY1305_SHA256_TYPE].count) {
+		if ( ciphers[TLS13_AES128_CCM_SHA256_TYPE].count ) {
 			if ( found_tls12_cipher >= 1)
 				printf(", ");
-			printf("%s", ciphers[TLS13_CHACHA20_POLY1305_SHA256_TYPE].name);
+			printf("%s", ciphers[TLS13_AES128_CCM_SHA256_TYPE].name);
 			found_tlsv13_cipher++;
 		}
-#endif
 		if ( found_tlsv13_cipher == 1)
 			printf(" is ");
 		else
@@ -26052,11 +26051,9 @@
 				switch (i) {
 					case TLS13_AES256_GCM_SHA384_TYPE:
 					case TLS13_AES128_GCM_SHA256_TYPE:
-#if 0 /* TLSV13 TODO */
+					case TLS13_CHACHA20_POLY1305_SHA256_TYPE:
 					case TLS13_AES_128_CCM_8_SHA256_TYPE:
 					case TLS13_AES128_CCM_SHA256_TYPE:
-					case TLS13_CHACHA20_POLY1305_SHA256_TYPE:
-#endif
 						find_tls13_cipher = 1;
 						break;
 					default:
@@ -26196,11 +26193,9 @@
 	{"ECDHE-SM4-SM3",0xe011},
 	{"TLS-AES128-GCM-SHA256",0x1301},
 	{"TLS-AES256-GCM-SHA384",0x1302},
-#if 0 /* comment tls13 unsupported cipher temporary, TLSV13 TODO */
 	{"TLS-CHACHA20-POLY1305-SHA256",0x1303},
 	{"TLS-AES128-CCM-SHA256",0x1304},
-	{"TLS-AES128-CCM-8-SHA256",0x1305}
-#endif
+	{"TLS-AES128-CCM-8-SHA256",0x1305},
 	{"ECC-SM4-GCM-SM3", 0xe053},
 	{"ECDHE-SM4-GCM-SM3",0xe051}
 
Index: /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/models/loadbalancing/slb/ssl/virtual.py
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/models/loadbalancing/slb/ssl/virtual.py	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/click/webui/htdocs/new/src/apv/models/loadbalancing/slb/ssl/virtual.py	(working copy)
@@ -913,7 +913,10 @@
                         "TLS-AES128-GCM-SHA256":"0x1301",
                         "TLS-AES256-GCM-SHA384":"0x1302",
                         "ECC-SM4-GCM-SM3": "0xe053",
-                        "ECDHE-SM4-GCM-SM3":"0xe051"
+                        "ECDHE-SM4-GCM-SM3":"0xe051",
+                        "TLS-CHACHA20-POLY1305-SHA256":"0x1303",
+                        "TLS-AES128-CCM-SHA256":"0x1304",
+                        "TLS-AES128-CCM-8-SHA256":"0x1305"
                     }
             self.cli.set_enable()
             result = self.cli.cmd('show ssl settings "%s"' % pk_dict['name'],
@@ -2382,10 +2385,13 @@
                         "TLS-AES128-GCM-SHA256":"0x1301",
                         "TLS-AES256-GCM-SHA384":"0x1302",
                         "ECC-SM4-GCM-SM3": "0xe053",
-                        "ECDHE-SM4-GCM-SM3":"0xe051"
+                        "ECDHE-SM4-GCM-SM3":"0xe051",
+                        "TLS-CHACHA20-POLY1305-SHA256":"0x1303",
+                        "TLS-AES128-CCM-SHA256":"0x1304",
+                        "TLS-AES128-CCM-8-SHA256":"0x1305"
                     }
             self.cli.set_enable()
-            res = [{'cipher_suite':'AES256-GCM-SHA384'},{'cipher_suite':'AES128-GCM-SHA256'},{'cipher_suite':'AES256-SHA256'},{'cipher_suite':'AES256-SHA'},{'cipher_suite':'AES128-SHA256'},{'cipher_suite':'AES128-SHA'},{'cipher_suite':'DES-CBC3-SHA'},{'cipher_suite':'DES-CBC-SHA'},{'cipher_suite':'RC4-SHA'},{'cipher_suite':'RC4-MD5'},{'cipher_suite':'ECDHE-RSA-AES256-GCM-SHA384'},{'cipher_suite':'ECDHE-RSA-AES128-GCM-SHA256'},{'cipher_suite':'ECDHE-RSA-AES256-SHA384'},{'cipher_suite':'ECDHE-RSA-AES256-SHA'},{'cipher_suite':'ECDHE-RSA-AES128-SHA256'},{'cipher_suite':'ECDHE-RSA-AES128-SHA'},{'cipher_suite':'ECDHE-ECDSA-AES256-GCM-SHA384'},{'cipher_suite':'ECDHE-ECDSA-AES128-GCM-SHA256'},{'cipher_suite':'ECDHE-ECDSA-AES256-SHA384'},{'cipher_suite':'ECDHE-ECDSA-AES256-SHA'},{'cipher_suite':'ECDHE-ECDSA-AES128-SHA256'},{'cipher_suite':'ECDHE-ECDSA-AES128-SHA'},{'cipher_suite':'ECC-SM4-SM3'},{'cipher_suite':'ECDHE-SM4-SM3'},{'cipher_suite':'ECDHE-SM4-GCM-SM3'},{'cipher_suite':'ECC-SM4-GCM-SM3'}, {'cipher_suite':'TLS-AES128-GCM-SHA256'}, {'cipher_suite':'TLS-AES256-GCM-SHA384'}]
+            res = [{'cipher_suite':'AES256-GCM-SHA384'},{'cipher_suite':'AES128-GCM-SHA256'},{'cipher_suite':'AES256-SHA256'},{'cipher_suite':'AES256-SHA'},{'cipher_suite':'AES128-SHA256'},{'cipher_suite':'AES128-SHA'},{'cipher_suite':'DES-CBC3-SHA'},{'cipher_suite':'DES-CBC-SHA'},{'cipher_suite':'RC4-SHA'},{'cipher_suite':'RC4-MD5'},{'cipher_suite':'ECDHE-RSA-AES256-GCM-SHA384'},{'cipher_suite':'ECDHE-RSA-AES128-GCM-SHA256'},{'cipher_suite':'ECDHE-RSA-AES256-SHA384'},{'cipher_suite':'ECDHE-RSA-AES256-SHA'},{'cipher_suite':'ECDHE-RSA-AES128-SHA256'},{'cipher_suite':'ECDHE-RSA-AES128-SHA'},{'cipher_suite':'ECDHE-ECDSA-AES256-GCM-SHA384'},{'cipher_suite':'ECDHE-ECDSA-AES128-GCM-SHA256'},{'cipher_suite':'ECDHE-ECDSA-AES256-SHA384'},{'cipher_suite':'ECDHE-ECDSA-AES256-SHA'},{'cipher_suite':'ECDHE-ECDSA-AES128-SHA256'},{'cipher_suite':'ECDHE-ECDSA-AES128-SHA'},{'cipher_suite':'ECC-SM4-SM3'},{'cipher_suite':'ECDHE-SM4-SM3'},{'cipher_suite':'ECDHE-SM4-GCM-SM3'},{'cipher_suite':'ECC-SM4-GCM-SM3'}, {'cipher_suite':'TLS-AES128-GCM-SHA256'}, {'cipher_suite':'TLS-AES256-GCM-SHA384'}, {'cipher_suite':'TLS-CHACHA20-POLY1305-SHA256'}, {'cipher_suite':'TLS-AES128-CCM-SHA256'}, {'cipher_suite':'TLS-AES128-CCM-8-SHA256'}]
             for each in res:
                 each['cipher_suite'] += ' ('+cipher_id[each['cipher_suite']]+')'
                 self._model._meta.mark_delay_query(each)
Index: /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/ssl_record.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/ssl_record.c	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/ssl_record.c	(working copy)
@@ -660,6 +660,7 @@
 				ssl_printf("rp->rh.v3rh.ver[1]: %d\n", (int)rp->rh.v3rh.ver[1]);
 				ssl_printf("sslp->ver[0]: %d\n", (int)sslp->ver[0]);
 				ssl_printf("sslp->ver[1]: %d\n", (int)sslp->ver[1]);
+				ssl_printf("rp->rh.v3rh.type = %d\n", (int)rp->rh.v3rh.type);
 			
 				SSL_RECORD_PRINTF("mp: ", mp);
 				
@@ -962,6 +963,8 @@
 			} else {
 				int retval;
 				int cipher = sslp->rdata.rp->cipher;
+				/* Tag length are 16 bytes, but for CCM8 is 8 bytes */
+				int taglen = C_IS_CCM128_8(cipher) ? TLS_CCM8_TAG_LEN:TLS_GCM_TAG_LEN;
 
 				/* Add new code for client-side early data encryption*/
 				int send_early_data = 0;
@@ -983,7 +986,7 @@
 	
 						sslp->rdata.rp->len += TLSV13_MESSAGE_TYPE_SIZE;
 						
-						sslp->rdata.tmp = m_buffer4(SSL_RECORD_HEADER_LEN + sslp->rdata.rp->len + TLS_GCM_TAG_LEN);
+						sslp->rdata.tmp = m_buffer4(SSL_RECORD_HEADER_LEN + sslp->rdata.rp->len + taglen);
 						if (sslp->rdata.tmp == NULL) {
 							sslstats.ssls_mbuf++;
 							if (sslp->vhost->segment_id == SEGMENT_ID_INVALID) {
@@ -1004,7 +1007,7 @@
 						m_adj(sslp->rdata.tmp, SSL_RECORD_HEADER_LEN);
 						mbuf_checkin(sslp->rdata.tmp, 27);
 
-						m_tag = m_buffer4(TLS_GCM_TAG_LEN);
+						m_tag = m_buffer4(taglen);
 						if (m_tag == NULL) {
 							sslstats.ssls_mbuf++;
 							if (sslp->vhost->segment_id == SEGMENT_ID_INVALID) {
@@ -1034,7 +1037,7 @@
 
 						ssl_printf("1sslp->rdata.rp->len:%d\n", sslp->rdata.rp->len);
 					} else if (!sslp->newssl) {
-						sslp->rdata.rp->len += (TLS_GCM_TAG_LEN + TLSV13_MESSAGE_TYPE_SIZE);
+						sslp->rdata.rp->len += (taglen + TLSV13_MESSAGE_TYPE_SIZE);
 						ssl_printf("sslp->rdata.rp->len:%d\n", sslp->rdata.rp->len);
 						
 						sslp->rdata.tmp = m_buffer4(SSL_RECORD_HEADER_LEN + sslp->rdata.rp->len);
@@ -1084,7 +1087,7 @@
 						m_adj(sslp->rdata.tmp, SSL_RECORD_HEADER_LEN);
 						mbuf_checkin(sslp->rdata.tmp, 27);
 
-						m_tag = m_buffer2(TLS_GCM_TAG_LEN);
+						m_tag = m_buffer2(taglen);
 						if (m_tag == NULL) {
 							sslstats.ssls_mbuf++;
 							if (sslp->vhost->segment_id == SEGMENT_ID_INVALID) {
@@ -1106,7 +1109,7 @@
 
 						m_cat(sslp->rdata.tmp, m_tag);
 						sslp->rdata.tmp->m_pkthdr.len += m_tag->m_pkthdr.len;
-						sslp->rdata.rp->len += TLS_GCM_TAG_LEN;
+						sslp->rdata.rp->len += taglen;
 					}
 
 					if (sslp->rdata.rp->rh.v3rh.type == SSL3_RT_HANDSHAKE ||
@@ -1127,7 +1130,7 @@
 					if (!sslp->newssl && SslHwDeviceIdentifier == SSL_HW_QAT) {
 						m_cat(sslp->rdata.mp, m_tag);
 						sslp->rdata.mp->m_pkthdr.len += m_tag->m_pkthdr.len;
-						sslp->rdata.rp->len += TLS_GCM_TAG_LEN;
+						sslp->rdata.rp->len += taglen;
 					}
 					PRINTF("sslp->rdata.mp:", mtod(sslp->rdata.mp, uint8_t *), sslp->rdata.mp->m_pkthdr.len);
 					ssl_printf("sslp->rdata.rp->len:%d\n", sslp->rdata.rp->len);
@@ -2997,6 +3000,7 @@
 		context = sslp->pending_context;
 	}
 
+	ssl_printf("rp->rh.v3rh.type=%d\n", rp->rh.v3rh.type);
 	/* bug92330, 0-rtt meet clienthello retry, client might send a lot of 0-rt packet before receive retry clienthelo,
 	 * we will try to decrypt 0-rtt but context is NULL, cause ssl_tasks.c coredump, so just destroy this record and
 	 * send back to SSLS_RECORD_START to analysis more packet
@@ -3018,8 +3022,10 @@
 		sslp->rdata.rp = rp;
 		sslp->rdata.mp = rp->mp;
 		rp->mp = NULL;
+		/* Tag length are 16 bytes, but for CCM8 is 8 bytes */
+		int taglen = C_IS_CCM128_8(rp->cipher) ? TLS_CCM8_TAG_LEN:TLS_GCM_TAG_LEN;
 
-		if (sslp->rdata.mp->m_pkthdr.len <= TLS_GCM_TAG_LEN) {
+		if (sslp->rdata.mp->m_pkthdr.len <= taglen) {
 			get_sslp_peer_ip(sslp, ssl_peerip);
 			if(sslp->proxy_data.vs_info.vs_p){
 				fastlog_logex_vs(SSL_INCORRECT_LEN, sslp->proxy_data.vs_info.vs_p->name, 2, sslp->vhost->name, ssl_peerip);
@@ -3032,7 +3038,7 @@
 		if (SslHwDeviceIdentifier == SSL_HW_QAT && !sslp->newssl) {
 			sslp->rdata.tmp = m_buffer(sslp->rdata.mp->m_pkthdr.len);
 		} else {
-			sslp->rdata.tmp = m_buffer(sslp->rdata.mp->m_pkthdr.len - TLS_GCM_TAG_LEN);
+			sslp->rdata.tmp = m_buffer(sslp->rdata.mp->m_pkthdr.len - taglen);
 		}
 		if (sslp->rdata.tmp == NULL) {
 			sslstats.ssls_mbuf++;
@@ -3058,7 +3064,7 @@
 			sslp->flags &= ~SSL_FLAG_CARD_RECORD_PENDING;
 			SSL_RECORD_ERROR(sslp, RST_ID_SSL_RECORD_21);
 		}
-
+		
 		SSL_RECORD_NEWSTATE(sslp, SSLRS_TLSV13_DECRYPT);
 		return RECORD_ACTION_CONTINUE;
 	} else {
Index: /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/tlsv13_server.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/tlsv13_server.c	(revision 39468)
+++ /branches/rel_apv_10_7_3/usr/src/sys/click/app/ssl/tlsv13_server.c	(working copy)
@@ -1457,6 +1457,7 @@
 	p1 = pvhost->ciphers[sslp->tlsv13_data->support_ver[1]];	/* server side cipher list in int */
 	found = 0;
 
+	ssl_printf("vhost cipherstr = %s \n", pvhost->cipherstr);
 	/* we negotiate the cipher based on vhost setting order */
 	for (i = 0; i < len1; i++) {
 		p2 = cipher_data;   /* client cipher list in byte */
@@ -1476,6 +1477,7 @@
 	}
 
 	if (!found) {
+		ssl_printf("No matching cipher\n");
 		return SSL_ERROR;
 	}
 
@@ -2959,7 +2961,7 @@
 			sslp->tlsv13_app_data->early_data_statue == SSL_CLIENT_EARLY_WISH &&
 			0 != memcmp(identity->alpn_result, sslp->proxy_data.alpn_result, sizeof(identity->alpn_result))) {
 		/* (RFC p54) In order to accept early data, the server MUST have accepted a PSK
-		 * cipher suite and selected the first key offered in the clientĄ¯s
+		 * cipher suite and selected the first key offered in the client's
 		 * "pre_shared_key" extension. In addition, it MUST verify that the
 		 * following values are the same as those associated with the selected PSK:
 		 *	- The TLS version number
@@ -5699,8 +5701,11 @@
 	clicktcp_enter_func(sslp, sslp->flags);
 	
 	/* Prepare to compute finished */
+	int taglen = C_IS_CCM128_8(sslp->pending_cipher) ? TLS_CCM8_TAG_LEN:TLS_GCM_TAG_LEN;
 	clear_fin_len = C_HASH_LEN(sslp->pending_cipher) + SSL_HANDSHAKE_HEADER_LEN;
-	enc_fin_len = clear_fin_len + TLSV13_MESSAGE_TYPE_SIZE + TLS_GCM_TAG_LEN;
+	enc_fin_len = clear_fin_len + TLSV13_MESSAGE_TYPE_SIZE + taglen;
+
+	// ssl_printf("clear_fin_len=%d, enc_fin_len=%d\n",clear_fin_len, enc_fin_len);
 
 	sslp->tlsv13_data->clear_local_fin = m_buffer2(clear_fin_len);
 	if (!sslp->tlsv13_data->clear_local_fin) {
