R2A -->  R3A
diff --git a/TLS_CNL113839.tpd b/TLS_CNL113839.tpd
index aa09b98..c9777f9 100644
--- a/TLS_CNL113839.tpd
+++ b/TLS_CNL113839.tpd
@@ -1,4 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2018 Ericsson
+
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+
+
+   File:               TLS_CNL113839.tpd
+   Description:        tpd project file
+   Rev:                R3A
+   Prodnr:             CNL 113 839
+
+ -->
 <TITAN_Project_File_Information version="1.0">
   <ProjectName>TLS_CNL113839</ProjectName>
   <Files>
@@ -24,4 +39,4 @@
       </ProjectProperties>
     </Configuration>
   </Configurations>
-</TITAN_Project_File_Information>
\ No newline at end of file
+</TITAN_Project_File_Information>
diff --git a/doc/TLS_CNL113839_1551.doc b/doc/TLS_CNL113839_1551.doc
index 51e1d7f..2727c7f 100644
--- a/doc/TLS_CNL113839_1551.doc
+++ b/doc/TLS_CNL113839_1551.doc
Binary files differ
diff --git a/doc/TLS_CNL113839_PRI.doc b/doc/TLS_CNL113839_PRI.doc
index 073ece4..9f278ff 100644
--- a/doc/TLS_CNL113839_PRI.doc
+++ b/doc/TLS_CNL113839_PRI.doc
Binary files differ
diff --git a/src/TLS_Handler.ttcn b/src/TLS_Handler.ttcn
index 6b69824..cc785cf 100644
--- a/src/TLS_Handler.ttcn
+++ b/src/TLS_Handler.ttcn
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2017 Ericsson Telecom AB
+// Copyright (c) 2000-2018 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
@@ -10,7 +10,7 @@
 //
 //  File:               TLS_Handler.ttcn
 //  Description:        Type and function definition for TLS
-//  Rev:                <RnXnn>
+//  Rev:                R3A
 //  Prodnr:             CNL 113 839
 //
 
@@ -42,7 +42,11 @@
   charstring  ssl_trustedCAlist_file optional,
   charstring  ssl_cipher_list optional,
   charstring  ssl_password optional,  // private key file password
-  boolean     ssl_verify_certificate optional
+  boolean     ssl_verify_certificate optional,
+  charstring  psk_hint optional,
+  charstring  psk_identity optional,
+  charstring  psk_key optional,
+  boolean     psk_for_server optional
 }
 
 // Dispose the TLS/SSL object.
diff --git a/src/TLS_HandlerFunction.cc b/src/TLS_HandlerFunction.cc
index 0eaaec9..0d1b91d 100644
--- a/src/TLS_HandlerFunction.cc
+++ b/src/TLS_HandlerFunction.cc
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2000-2017 Ericsson Telecom AB
+// Copyright (c) 2000-2018 Ericsson Telecom AB
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the Eclipse Public License v1.0
@@ -10,7 +10,7 @@
 //
 //  File:               TLS_HandlerFunction.cc
 //  Description:        external functions for TLS
-//  Rev:                <RnXnn>
+//  Rev:                R3A
 //  Prodnr:             CNL 113 839
 //
 #include "TLS_Handler.hh"
@@ -30,7 +30,9 @@
   BIO* out_bio;  // we use memory write bios
   CHARSTRING passwd; // stores the password of the private key
   INTEGER  user_idx; // stores the user supplied idx value
-  bool  handshake_started; 
+  bool  handshake_started;
+  CHARSTRING pskIdentity;
+  CHARSTRING pskKey;
   TLS_object();
   ~TLS_object();
   
@@ -127,6 +129,48 @@
     return(strlen(pass));
 }
 
+unsigned int psk_server_cb(SSL *ssl, const char *identity,
+	      unsigned char *psk, unsigned int max_psk_len)
+{
+  int ret;
+
+  int idx = *(int *)SSL_get_app_data(ssl);
+  TLS_object* obj=obj_list[idx];
+  if (!identity)return 0;
+  if (strcmp(identity,obj->pskIdentity ) != 0) return 0;
+  if (strlen(obj->pskKey)>=(max_psk_len*2)) return 0;
+
+  /* convert the PSK key to binary */
+  ret = strlen(obj->pskKey)/2;
+  memcpy(psk,str2oct(obj->pskKey),ret);
+  
+  if (ret<=0) return 0;
+  return ret;
+}
+
+unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+	unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
+{
+  int ret;
+
+  int idx = *(int *)SSL_get_app_data(ssl);
+  TLS_object* obj=obj_list[idx];
+
+  if (!hint){
+    TTCN_warning("NULL received PSK identity hint, continuing anyway");
+  }
+  ret = snprintf(identity, max_identity_len, "%s", (const char *)(obj->pskIdentity));
+  if (ret < 0 || (unsigned int)ret > max_identity_len) return 0;
+  if (strlen(obj->pskKey)>=(max_psk_len*2)) return 0;
+
+  ret = strlen(obj->pskKey)/2;
+  /* convert the PSK key to binary */ 
+  memcpy(psk,str2oct(obj->pskKey),ret);
+ 
+  if (ret<=0) return 0;
+  return ret;
+}
+
 // How should we call the generic SSL/TLS method
 // it depends on the OpenSSL version
 #ifndef SSLv23_method
@@ -206,16 +250,43 @@
     const char* cf=(const char*)descr.ssl__cipher__list()();
     if (SSL_CTX_set_cipher_list(ctx, cf)!=1)
     {
-      TTCN_warning("ipher list restriction failed for %s", cf);
+      TTCN_warning("Cipher list restriction failed for %s", cf);
       log_error();
       return -1;
     }
   }
+  
+//PSK
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+  if(descr.psk__hint().ispresent()){
+    SSL_CTX_use_psk_identity_hint(ctx,(const char*)descr.psk__hint()() );
+  }
+  if(descr.psk__identity().ispresent()){
+    pskIdentity=descr.psk__identity()();
+  }
+  else pskIdentity="";
+  if(descr.psk__key().ispresent()){
+    pskKey=descr.psk__key()();
+  }
+  else pskKey="";
+  if(descr.psk__for__server().ispresent() && descr.psk__for__server()()){
+    SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+  }
+  else{
+    SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
+  }
+#else
+    TTCN_warning("The used OpenSSL doesn't support the PSK");
+#endif
 
 // set other side verification mode
 // By  default the verification is enabled
   if(descr.ssl__verify__certificate().ispresent() && !descr.ssl__verify__certificate()()){
     SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+  } else if(pskKey!="" && pskIdentity!="") {
+    SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
+#endif
   } else {
     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
   }
@@ -335,7 +406,6 @@
   SSL_set_bio(ssl, in_bio,out_bio);
  
 
-
   return 0;
 }
 
@@ -396,6 +466,10 @@
 //printf("idx %d\r\n",idx);    
     TLS__op__result ret_code=TLS__op__result::TLS__ERROR;
     TLS_object* obj=obj_list[idx];
+    
+    //used in psk cb functions
+    SSL_set_app_data(obj->ssl,(const char*)&idx);
+
     if(!(obj->handshake_started)){
       if((bool)is__server) {
         SSL_set_accept_state(obj->ssl);